查看原文
其他

大模型在小爱同学应用实践

杜鑫 DataFunSummit
2024-09-11

导读 本文将介绍大模型在小爱同学产品上的应用,分享在意图分发、意图理解、回复生成等方面的实践。

主要内容包括以下几大部分:

1. 小爱同学概要介绍

2. 大模型意图分发

3. 大模型垂域意图理解

4. 大模型回复生成

分享嘉宾|杜鑫 小米公司 高级算法工程师

编辑整理|朱伟

内容校对|李瑶

出品社区|DataFun


01

小爱同学概要介绍

小爱同学是一个无处不在的 AI 助手。目前我们的产品线包括小爱建议、小爱语音、小爱视觉、小爱翻译和小爱通话,支持的设备涵盖了手机、音箱、电视以及小米汽车。

从 ChatGPT 发布,引爆了大模型浪潮,国内外公司纷纷发力开展大模型相关工作,我们也在思考如何让小爱同学用上并用好大模型。通过多轮讨论,我们达成共识,即利用大模型重新构建小爱同学。在大模型的支持下,产品体验和用户留存得到了大幅提升,活跃用户次日留存提升了 10%,中长尾 query 满足率提升了 8%。

上图展示了小爱同学的整体架构,采用的是分而治之的思想。一个 query 来了之后,首先会有一个意图分发的大模型去做意图分发,将 query 分发到下游各个垂域的 agent 上去,每一个垂域 agent 会有一个专门的意图理解大模型进行意图的理解。

02

大模型意图分发

1. 意图分发介绍

意图分发的目的是判断用户 query 的意图归属,然后将 query 路由到指定的垂域 agent 上去做一个深度的理解。因为这个垂域的 agent 只关注于自己垂直的意图理解,整个模型迭代的难度会更小,迭代效率会更高,可以更好地满足用户的需求。

意图分发主要有两个难点:

(1)模型是需要知识才能正确理解的。比如打开设置 vs 打开空调,需要模型知道设置是系统项,空调是设备;

(2)耗时的要求高,小爱场景意图分发需要控制在 200ms 以内。

2. 大模型尝试

首先做意图分发模型是需要知识,大模型通过了海量的数据预训练,我们认为它是具有知识的,自然而然想到就是用 prompt engineering,设定一个任务,然后直接请求大模型去输出这个用户请求中蕴含的意图。

实践中存在以下两个问题:

  • 大模型输出的意图跟我们预定义的意图不一致。

  • 大模型没有办法有效地遵循指令。在实践过程中发现,只有百亿级或者千亿级的模型才会遵循指令,更小的模型会倾向于直接去回答问题。

为了处理上面的问题,我们采用 few-shot 方法,在 prompt 中定义意图,并给一些示例 query。这种方法在一定程度上缓解了上述问题,但又带来一个新的问题就是输入的 token 太多。再加上对耗时的要求,Prompt engineering 的方法无法走通。因此我们尝试大模型的微调。

3. 大模型微调

大模型微调分为两步。

Step1 继续预训练:利用小爱积累的一些对话数据去做继续预训练,增强大模型对小爱领域知识的理解能力。小爱对话数据基于小爱和用户真实的交互历史构造,小爱意图数据基于用户请求和意图以及槽位信息构造。预训练的时候还会加入一些通用的训练数据,通用数据是基于开源数据,分为 NLP 任务指令数据和预训练数据。在整个的继续预训练里,我们会保证小爱的数据和通用数据的比例在 10 比 1 到 15 比 1 的范围内。

Step2 指令微调:在指令微调里边可以看到我们这个 prompt 是比较简单的,而且是没有显示的注入意图定义的。我们认为在模型微调的过程中,模型是有能力记住意图定义的。通过这样的方式,整个输入的 token 数会明显减少。

接下来我们思考是否需要继续预训练?在我们的意图分发场景中,继续预训练+指令微调,评测集准确率会有 2% 的提升。另外,对是否需要 few-shot 我们也进行了一些尝试,训练集增加 few-shot,测试集不增加 few-shot,困难评测集准确率提升了 1%;如果在测试集也增加 few-shot,困难评测集准确率则会有 1.5% 的提升。这里需要注意的是,few-shot 的选择至关重要,如果选择不当会对模型效果产生负向影响。

应用大模型进行意图分发,使中长尾 query 的理解提升8%,多轮 query 理解提升 6%,训练数据则由百万级别降到了万级别,减少了 95%。

03

大模型垂域意图理解

1. 传统意图理解方式

传统的垂域意图理解,通常就是采用 Intent+Slot的这种架构。一个用户query 来了之后,首先会去做意图识别得到 Intent,然后再去做槽位的识别,得到他的 Internet 和 Slot 之后,就可以给到下游去执行回复。

2. 小爱意图理解方式

小爱同学大模型采用的是 function calling 的方式。首先我们对所有 API 抽象出 function 的定义,包括这个API 的功能以及它需要的参数的描述。当一个 query 来了之后,会把这个query 和 function 的定义一起构造一个 prompt,给到大模型。

大模型会去做两件事情,一是去判断要不要用预定义的 Function。第二个任务是如果选择了某个 function,要给出 Function 需要的参数。比如今天到上海的火车票,大模型识别的这个 function 是一个 Search_train,然后给出来参数是 time 和 arrival。这个时候会去检查他的槽位是否满足 API 执行的条件。如果是,就去请求 API 得到 API 的结果,然后给到大模型去做回复。如果没有就可以直接回复,或者参数不完整的时候,也是大模型直接回复,然后引导用户去补充或者澄清。

3. Function calling 难点

Function calling 也存在一些难点。

(1)如何保证 100% 的指令遵循

  • 小爱场景下 Function calling 是满足的基础,需要保证 100% 的指令遵循,通用大模型 prompt engineering 很难满足。大模型微调的话也是分了两步,第一步是做了继续预训练,方法与意图分发的继续训练模型基本上是一样的,稍微不同的是不同的垂域可以提供不同的继续预训练的数据;第二步就是做指令的微调,也跟意图分发是一样的。

(2)Function calling 依赖关系

  • 串行的方式,类似 ReAct。主要有两个操作,一个是 reasoning 推理规划,另一个是 acting,这是单 function 的执行。对于一个请求,ReAct 首先进行 Resoning 推理,决定下一步的操作,在意图理解里就是输出 Function,每次推理只会输出一个 Function。然后 Acting 执行,即 Function 执行。得到执行结果后,再重复上述过程,直到满足用户需求。如果一个需求,需要多 Function 执行,那么 ReAct 执行链路会很长,在实际应用中难以落地。

  • 解决多 Function 并行可以用编程语义来表达,类似 LLMCompiler。可以并行的 Function 会同时执行,可以减少响应时间。

    LLMCompiler 会有三个组件:LLM Planner 大模型规划,Task Fetching Unit 任务获取,Executor 执行。

    LLM Planner

    利用 LLMs 的推理能力,规划分解为子任务,并识别各子任务的依赖关系,生成一个子任务序列及其依赖关系,形成一个有向无环图。

    如果一个任务依赖于之前的任务,它将使用占位符变量,用该任务的实际输出替换该受量。

    Task Fetching Unit

    无依赖关系的子任务,并行执行。

    有依赖关系的子任务,在完成上一任务后,再进行分发执行。

    Executor

    以异步和并发的方式执行从任务获取单元获取的任务。

    执行器配备了用户提供的工具,并将任务给关联的工具(如:API 调用)。每个任务都有专用的内存来存储其中间结果。任务完成后,最终结果将作为输入转发给依赖于它们的其他任务。

    我们采用的是类似 LLMCompiler 的方式。但是在我们的场景下,更多的是单Function 需求。整体的执行效率没有体现。

    除此之外,最近也有一些 Tree-based Planning,比如 Tree of thoughtlanguage Agent Tree Search(LATS),可以同时考虑多个可行的计划,以作出最佳选择,耗时会过高,因此,在我们的场景下没有采用。

(3)Function calling 推理耗时过高

  • 输入优化

    在大模型微调过程中让其记住 function 的定义和参数,这样可以减少生成的 token 数。但这样做的缺点是大模型需要频繁更新以应对变化,通用性较差。为缓解这一问题,我们让每一个垂域先虚拟一些 function,让大模型具备处理垂域 function 的能力。

  • 推理优化

    一方面是减少生成的 tokens 数,另一方面就是减少推理的次数。减少 tokens 数一般有三种方式,第一个就是选择高压缩率的底座模型,在实践中,我们对比过两个开源模型,压缩比在 1.4-2 之间,如果选择了高压缩率的底座模型,生成的 tokens 数据会明显地减少。第二种方式是扩充词表,我们尝试发现如果直接扩充词表而不去做继续预训练,那么大模型性能是急剧恶化的,所以如果要扩充词表,还是要去做一个继续训练。第三种是做 token 的替换,有的时候可能 function 名字或者参数的名字会被切成多个 token,可以在已有词表里边选择一个相近的 token 来替换,这种方法不够通用,建议慎重使用。

    减少推理次数的方法就是投机采样,其核心是通过一个小模型推理 n 次生成 n 个 token,再让大模型进行评估。在 Function calling 的应用中,小模型用 n-gram 即可实现 2-3 倍的推理速度提升。

应用大模型进行意图理解,中长尾 query 满足率提升了 4%,多轮 query 满足率提升了 3%,训练数据减少了 90%。

04

大模型回复生成

1. 大模型回复的问题

通用大模型回复存在的主要问题是:

  • 时效性。最经济的解决方式就是利用 RAG,外挂知识库,让大模型基于检索到的知识来做回答。

  • 长上下文理解。由于 RAG 通常冗余地注入知识,来保证知识的召回率,会使 token 数很多,对大模型上下文理解能力的要求就更高。

  • 指令遵循。我们的场景下,为了保证用户的体验,期望回复简单,不要做信息的罗列。特别是当商品属性众多,需要明确哪些属性是用户关心的。通常是产品定义。大模型难以遵循指令只输出关键信息。

2. 大模型微调

RAG 场景下大模型回复,大模型需要具备如下能力:

  • 知识总结。比如推荐一款手机,注入知识之后,要把用户关心的那个手机的一些参数给出来。

  • 信息抽取。比如小米十四的像素是多少,我们希望大模型能够从我们注入的知识中,把小米十四的像素信息准确地提取出来。

  • 复杂推理。比如推荐一个拍照好的手机,大模型需要理解这个拍照好对应的是相机的参数。再比如对比一下小米 14 和小米 14 pro 的差别,那大模型需要从注入的知识中,把这个小米 14 和小米 14 的 pro 的参数差异给出来。

  • 多轮对话。多轮的时候经常会有缺省的部分,第一轮我说小米十四的价格,然后第二轮是像素是多少,那我当然希望他回答是小米十四的像素,而不是其他手机的像素。

  • 兜底回复。因为会有一些知识缺失,或者是知识未检索到的情况,我们不希望大模型去杜撰。比如小米 17 什么时候发布,注入知识中肯定是没有小米 17 的,我们希望大模型能够具备抗干扰的能力。

  • 最后为了保证大模型具备通用的问答能力,我们还会混入一些通用的能力。

微调的具体步骤如下:
  • 第一步,优化单能力训练数据;这里,一个很重要的问题是如何评价。我们最终的模型评价是人工标注,但是人工标注成本太高且周期太长,在迭代过程中不适合。我们采用更好的大模型进行自动评价,例如 chatGPT,GPT4。前期评测,大模型评价与人工评价的一致性大概 80% 左右。
  • 第二步,按比例混合训练数据,指令微调。这里最重要的是数据混合比例如何确定:
    单个能力的数据到达一定的规模(1000->1500), 评测集合满足率(40%->81%)呈现大幅度提升,继续增加训练数据(1500->2000),满足率提升缓慢(81%->86%)
    因此,训练数据混合时,我们找到不同能力的满足率大幅提升到平稳的临界点,以此作为调整的基础。一般来说,难度大的,训练数据会稍多。在合并数据过程中,我们会控制每个能力的数据上限。
  • 第三步,构建偏好数据,对齐训练 DPO。数据构建格式是一个四元组<Query, Knowledge,Win_response,Lose_response>

指令微调+DPO 训练,相比单纯的指令微调,回复满足率提升 2%;相比于 prompt engineering 可以提升 10%。

3. 未来展望

前文中介绍到小爱的整个架构是一个分而治之的框架,那么是否可以用一个大模型端到端地去满足用户呢,甚至由一个多模态大模型进行端到端的理解,无需 ASR 和 TTS。用一个多模态的 Anything to Anything 的架构,类似 GPT4o 和谷歌 Gemini。这肯定是我们未来努力的方向,但目前分而治之仍是一个更优的方案。

另外,我们也在做端侧的大模型,以更好地解决用户隐私的问题。

以上就是本次分享的内容,谢谢大家。



分享嘉宾

INTRODUCTION


杜鑫

小米公司

高级算法工程师

2010.9-2013.3 北京邮电大学 硕士研究生

2013.4-2020.6 北京三星研究院,负责30+语种的联机手写识别,三星语音助手 Bixby 开发

2020.7-至今 小米公司 小爱同学 负责语音助手中的 NLP 相关算法开发。




往期推荐


生成式AI带来的冲击与改变,我们讨论得还远远不够

多模态在京东内容算法上的应用

LLM+RAG:大模型在金融场景的落地探索

智能电销新纪元:大模型技术的应用与未来趋势

Apache Hudi 从零到一:初识表服务:压缩、清理及索引(五)

小红书推荐系统迭代:AB测试架构的高效与稳定性策略

7倍性能提升|阿里云AnalyticDB Spark向量化能力解析

金融大模型数据治理与应用创新

面向大规模向量数据的云原生存储解决方案:Milvus 向量数据库的经验

基于 Doris 湖仓一体分析系统在快手的实践



点个在看你最好看

SPRING HAS ARRIVED


继续滑动看下一个
DataFunSummit
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存