茴香豆是一个基于 LLM(Large-Language-Model,大语言模型)的领域知识助手,工作在群聊里(微信、飞书、钉钉等)。不同于 chatgpt 这类单人聊天工具,群聊场景有些特殊:
禁止消息泛滥。茴香豆需要找到真正需要帮助的用户,杜绝闲聊
需要方便添加领域知识。gpt 能处理体育新闻,但面对职业化的竞技体育知识(如 “truck circle”)就会失灵
100% 无幻觉。哪怕一次胡言乱语,也会让用户质疑 bot 的可靠性
为了解决这些需求,我们从基线版本开始,经过两次改进达到了当前的解决方案。为了便于理解,我们用冷兵器形容这些方案。
基础版-“匕首”,直接微调 LLM 来处理问题。意为用匕首硬怼。
改进版-“长矛”,首先找到问题的靶点,然后用 LLM 处理。就像是将匕首固定在木杆上,消除干扰并定位问题。
最终版-“钉耙”。找到多个信息点,把它们搂起来,然后用 LLM 处理。因为与长矛相比,耙子的齿覆盖了更大的目标区域。
需要注意的是,1、2 方案都有致命缺陷,第 3 版才开始得到用户好评。
技术报告:
https://arxiv.org/abs/2401.08772
GitHub 地址:
https://github.com/InternLM/HuixiangDou
说了这么多,我们先看茴香豆在 MMPose 用户群的“聊”效:
可以看到知识助手并不处理技术问题以外的“闲聊”,只针对 wflw 数据集的计算寻找答案。
很直接地,群聊消息经过预处理,交给微调后的 LLM 响应,返回给群组。
一个群组肯定有群名和很多用户,然而常见的 ChatML format 只定义了 3 个角色:system、user 和 bot,导致群聊消息格式没法和 LLM “对齐颗粒度”。
因此我们基于用户 ID 对群组内的消息进行分类,以简化消息处理。考虑到用户不会一次性发完问题,我们设置了定时器,将多个连续的消息合并为一个。所有间隔元素都会被忽略,如表情包、群应用、语音和视频消息。
论文实验部分展示了,匕首版会遇到极严重的幻觉问题。群聊场景里,幻觉来自两部分:
外部用户闲聊
内部模型本身,或者说模型的训练数据和领域知识不一致
因此长矛版的目的是消除幻觉,它增加了两个流程:
两阶段拒识,禁止跟用户唠闲磕
寻找真实问题的答案,包含 RAG 和 LLM prompt
第一阶段。俺们测试多个模型后,认为 2023 开源版的 text2vec 模型精度,并不能满足茴香豆真实场景的 RAG 需求。但反过来思考, text2vec 非常适合排除无关话题。
第二阶段。text2vec 模型并没有人类的价值观,例如 “这个板子很烂” 和 “这块开发板非常棒” 相似度可能是 0.7,对 text2vec 而言是合理的。因此需要 LLM 处理 query 中“人类价值观”部分。我们在论文实验部分,展示了如何用 LLM 打分实现拒识。
2.2.2 响应流程
群聊对话经常出现语气词或客套话,例如“大佬们,不好意思打扰一下。我想问下” 会影响 RAG 效果。因此在响应阶段,首先提取了问题的关键短语,然后使用常见的 langchain/wenda 提取背景材料,最后用 LLM 判断 text2vec 搜到的材料和答复,是否和问题相关。
需要注意的是,拒识流程的输入是原始的用户 query;响应流程的输入是有信息量的短语,所以响应流程创建特征库时用了新的 TextSplitter。
长矛版的召回很高,既不会消息泛滥,也没有幻觉;缺点是 text2vec 命中率不足,茴香豆不爱搭理用户会显得很“高冷”。
钉耙版扩展了响应流程,“耙”取多个信息点位来提升精度。
引入多种搜索和过滤能力,扩展 LLM 服务,增加安全审查
2.3.1 网络搜索
作为 MMPose 的知识助手,假设用户问 “有没有推荐的视频标注软件”。这确实不是 MMPose 项目的工作,但回答这个问题,明显能提升产品的整体体验。
因此我们开启了 web search 处理这类问题。需要额外注意的是,信息源可能是被污染的(夹杂擦边小说、街边广告),因此需要用 LLM 过滤搜索结果。
2.3.2 搜索增强
好答案,来自好问题。
用户其实不会在 MMPose 群里咨询 LMDeploy 的问题,这意味着不总是要面对整个互联网找答案,我们只需要先用 LLM 缩小搜索范围——如 MMPose ——然后检索多个关键短语,合并后阅读理解即可。
2.3.3 混合 LLM 服务
基于卷积的 AI 产品经验在 LLM 时代同样适用,茴香豆并不是每次调用 chat 都需要 LLM 的所有能力,我们也不能奢望成本约束后,单个模型各方面指标还能保持很高。
因此我们把 LLM Chat 看作一个 RPC 服务,内部按需调用不同 local 或者 remote LLM,节约成本。
2.3.4 得分板
得分板本质上是不同消息源的信任度。举例来说,要解决 cuda 问题肯定优先看 nvidia 官网,而非某个技术博客;商业公司的纯技术文章质量,一般高于开源问答社区的质量。我们在茴香豆测试场景里,配置了一些偏好,实际运行时会按偏序选取背景材料,最后交由 LLM 处理。
2.3.5 安全
我们为技术助手答复内容准备了 4 条安全带:
LLM 检查。计算答复和敏感主题的关联度
NLP。用传统方法二次检查是否高危话题
允许撤回。群组中任何人都可以命令助手撤回本群消息
设定工作时间。保证技术助手在人类的监控下运行,同时暂存非工作时间的消息,推迟到工作时间一次性处理
经过反复实测,我们设计了一套算法 pipeline,运行在微信和飞书群来解答领域问题。这套方案部署成本低,仅仅需要 LLM 满足 4 个特征。
我们把 pipeline 开源到了 GitHub;同时把研发期间所有成功或失败的尝试,总结并发布在 arxiv。
技术报告:
https://arxiv.org/abs/2401.08772
GitHub 地址:
https://github.com/InternLM/HuixiangDou
需要注意的是,茴香豆在实际运行中仍有很多不足:
群聊信息缺失。因为群聊消息格式和 ChatML 格式不匹配,技术助手没有看到其他人对问题的补充
不支持多模态。用户习惯先发报错截图再发问题,然而最重要的日志无法识别,无法给出预期结果。我们尝试了商业版 OCR 也无法直接解决,可能需要多模态方法
难例挖掘。尽管搜索增强可以部分解决代码问题,但对真正的难问题(如 linux 源码),仅靠 prompt 无法覆盖所有上下文。随着 context length 增加,transformers 结构 LLM 的显存和计算开销增大,很难用 kv cache 量化稀疏方法根治