大模型应用与实践
Smart Copilot:大模型在技术服务和智能客服领域提效的最佳实践
本文档使用 WYMF 发布
-
+
首页
Smart Copilot:大模型在技术服务和智能客服领域提效的最佳实践
一、背景 随着云计算技术的快速发展,越来越多的企业和个人选择将业务迁移到云端。有很多云厂商为客户提供了灵活、可扩展的计算资源和服务,使得客户能够更加专注于核心业务。然而,云计算领域的技术和服务日新月异,客户在使用过程中可能会遇到各种问题,这就需要客服团队提供专业、高效的支持。 传统的客服模式往往面临着人力成本高、响应速度慢、专业度不足等问题。为了解决这些问题,我们开发了一款基于LLM的智能助手 Smart Copilot。Copilot旨在帮助技术服务团队更高效、更专业地解决云计算领域的问题,提高客户满意度。如果大叫有需要或者交流,我们可以交流一些解决方案。 二、功能介绍 目前Smart Copilot的核心功能包括: 1、云技术服务领域问答:Copilot可以快速准确地回答客户关于云计算的各种问题,提高解决问题的效率,并且具备一定的推理能力。 2、自助知识注入: Smart Copilot在你的业务场景回答的不准确?没关系我们提供了自助知识注入平台,你提供弹药,我们负责输出更专业的答案。 三、技术实现 当前,LLM 的最大问题就是缺乏最新的知识和特定领域的知识,目前有两种主要的解法:微调与检索增强。微调的优势在于能让模型真正学会垂直领域的知识,但是微调成本高且极其容易过拟合,更新知识困难;检索增强的优势在于成本低能实时更新知识,但是回答的结果很依赖于检索注入的知识。 我们的实现思路则是结合了上述两种方法模型微调+检索注入,为模型提供云垂直领域数据与FAQ做SFT,同时推理时为模型提供相关的知识做注入。检索注入的流程如下图所示,接下来我们会针对每个模块进行详细介绍。 当前,LLM 的最大问题就是缺乏最新的知识和特定领域的知识,目前有两种主要的解法:微调与检索增强。微调的优势在于能让模型真正学会垂直领域的知识,但是微调成本高且极其容易过拟合,更新知识困难;检索增强的优势在于成本低能实时更新知识,但是回答的结果很依赖于检索注入的知识。 我们的实现思路则是结合了上述两种方法模型微调+检索注入,为模型提供智能客服数据与FAQ做SFT,同时推理时为模型提供相关的知识做注入。检索注入的流程如下图所示,接下来我们会针对每个模块进行详细介绍。 ![](/media/202309/2023-09-16_082001_8557040.8133133259368366.png) LLM 模型方面主要使用ChatGPT、ChatGLM等base模型,基于他们进行注入。 1、LLM的灾难性遗忘 模型微调我们尝试了全量参数的方法与PEFT的方法,但是不管什么样的方法都会面临同样的问题:过拟合导致灾难性遗忘,这也是我们遇到的一个深坑。 在第一个版本中,我们使用了垂直领域云计算会议这个产品的FAQ对ChatGLM-6B进行了Lora微调,框架使用deepspeed,微调后效果并不理想,当时感觉是因为PEFT对模型收益可能较少,因此又修改为了全量参数的微调,在8块A100 40G的卡上采用了流水线并行方法进行了微调,在”云计算会议“这个场景下效果会比PEFT的方法好一点,但是模型出现了灾难性遗忘,不管问什么问题模型总会带上一些和”云计算会议“相关的内容。第一感觉是训练过程跑了多个epoch导致模型过拟合了,因此将epoch降低到了1,但是问题并未解决;后面又感觉是不是因为ChatGLM-6B训练过程中有RM,导致增量训练的时候偏离了原有分布。 实际上,上述两点都不是关键原因,经过我们的调研与测试,包括openai的文档也提到,垂类数据做微调并不是一个好的方案,想要彻底解决这个问题,需要给模型添加足够丰富的各类数据,并把你的垂直领域数据混杂在其中,例如你用1000w token的数据做训练,目前又收集到了10w token的垂类数据,那么你需要把这10w的垂类数据添加到通用数据中shuffle后再训练。 有了数据你还需要考虑在微调阶段是继续做post train(next token prediciton)还是sft呢?我更加建议大家多使用文档数据进行post train,这个阶段是模型真正学习知识的阶段,当然sft阶段也有一定的作用,但是在我看来sft更多是让模型输出符合instrcution分布的数据或者说和“chat“对齐;其次sft阶段的数据更加依赖标注质量,最近的一篇paper LIMA也提到如果有足够高质量的instruction数据,其实只需要1000条就能在一个base LLM上训练出一个效果很好的Chat模型,Llama2在sft阶段的数据量也不多一共就2w+但是数据质量非常高。 模型微调我们尝试了全量参数的方法与PEFT的方法,但是不管什么样的方法都会面临同样的问题:过拟合导致灾难性遗忘,这也是我们遇到的一个深坑。 ![](/media/202309/2023-09-16_082351_6591570.13340218463413545.png) 所以如果你想让模型学会垂直领域的知识,数据的数量和质量缺一不可。 如果你没有那么多的数据又想让模型学会垂类知识怎么办呢?我的思路是添加一个路由层,并直接使用垂类数据做post train和sft,让这个模型在垂直领域过拟合,使用的时候在路由层进行分发,通识类问题让微调前的模型回答,垂类问题让微调后的模型回答,不过这个就依赖你的路由层的效果了,如下图所示,如果你只想使用云计算相关的模型,那就把其它lora的w设置为0。 ![](/media/202309/2023-09-16_082424_3523720.8960460872657942.png) 2、训练框架怎么选 目前市面上有非常多的框架,包括DeepSpeed、Megatron、ColossalAI、 Accelerate等等,初期我们在使用框架的时候也遇到很多坑,因为算力有限制,最后考虑使用流水线并行进行训练,当时ColossalAI炒的很热亲自上手后发现问题极多,文档不完善api过期也没更新文档,无奈之下换了Megatron,Megatron功能最全,支持张量并行即把一个张量拆分到不同的GPU,不过我们微调的模型没有那么大用不到这个功能更多还是用它的流水线并行,当然Megatron也有缺点,你需要使用Megatron自己的算子,它没有适配的算子就很需要自己去实现,这个时间成本很高,目前各类开源的LLM也各有自己优化的模型结构,例如mutil query attention、flash等等,所以最终还是选择了DeepSpeed,配合zero stage使用起来算力要求也没有那么高。最后补充一下流水线并行,流水线并行层与层之间只能传递一个参数,如果你的模型代码传递了多个参数,那就需要把多个参数修改为一个元组进行传递。 3、解码算法用什么 生成模型一个比较关键的点就是解码算法了,目前的LLM的解码算法beam search已经很少使用了,基本都是采样并配合temperature使用,采样的优势主要还是在于能生成多样性的回答,但是不管什么解码方法在垂直领域数据上微调后都很容易遇到一个问题:复读机,模型有时候会重复输出同样的token,如果设置的最大长度比较长,还容易停不下来,为什么会出现这样的问题呢?三个原因: 自回归性质:Transformer架构的语言模型通常是自回归的如果模型在某个时间步骤生成了一个token,那么在下一个时间步骤,由于这个token已经在上下文中,模型可能会倾向于再次生成这个token。 模型训练的偏差:如果在训练数据中,某些词语或短语经常重复出现,那么模型可能会学习到这种重复的模式,从而在生成文本时也会产生重复的token,因为垂直领域的token量不多,就更容易导致这个问题发生。 在使用top-k还是top-p的方法时如果超参设置不合理例如k、p比较小,温度比较小,模型对某个token的预测概率机会特别高,那么这个token就可能会被反复生成。 怎么解决呢?其实最好的方法还是添加足够丰富的数据,从数据层面把这个问题彻底解决,如果数据不够,那就要从解码层面入手了,目前最简单的方案就是对重复的token添加惩罚项,惩罚项如下,其中\theta默认取1.2,g表示的是已经生成的tokens,T是大家熟知的temperature,简单点说就是如果token已经生成过了,就给该token一个较大的温度,从而减小其再被采样到的概率。 ![](/media/202309/2023-09-16_082545_9305500.2569780310465616.png) 4、PEFT还是全参数微调 两种方式各有优缺,如果说你算力足够建议走全参数微调,但是如果你数据不够想走刚才说的添加路由层的思路,那么PEFT才是最优的选择,为什么呢?主要的原因在于如果是PEFT我们可以采用类Lora的方法,部署的时候只需要部署一个主模型和一个Lora模型,这样部署成本低,在路由层添加一些逻辑判断来确定是使用原模型还是Lora模型,如果你想让你的模型在多个垂直领域都有好的表现,也只需要训多个Lora模型并在路由层进行控制。 检索增强 LLM目前最大的问题其实还是幻觉问题,没办法完全规避,为了缓解这个问题,我们采用了检索增强的思路,把用户相关的问题答案以上下文的形式提供给LLM,LLM结合上下文进行回答,即把 ![](/media/202309/2023-09-16_082708_1416820.5442125482431558.png)修改为了 ![](/media/202309/2023-09-16_082725_1488550.8405204481269684.png),后者的概率分布可信度会更高,其次这个方案也有有一个优势,如果文档有更新,那么只需要实时更新注入的知识即可,无需重新训练LLM,这也能保障答案的时效性。 1.数据存储 数据存储主要是向量数据库+embdging,如何存,存什么这些都会影响到最后的效果,我们在数据存储阶段也做了较多的一些优化,包括: 文档chunk的切分方式优化 精简给到embedding模型、排序模型的文本 对不规范的文档数据补充产品名 对FAQ做清洗,移除无关信息 表格数据重新格式化 关于embding和向量数据库尽请观看我们后期文章的更新。 2.prompt构建 这部分我们再聊一下prompt,第一个版本我们的prompt很简单,就只是让模型根据提供的内容进行”阅读理解“,额外加了”let's think step by step“来使用CoT提升模型的推理能力,但是这个版本的问题很多 CoT的引入让模型输出很多思考过程,对于用户体验来说并不友好 因为注入的内容有faq、文档,faq包含问题,导致模型会误解到底哪个是真正的问题,其次所有检索到的知识混杂在一起,模型不好区分不同的知识导致回答错误 模型有时候不会参考注入的知识就胡乱回答问题 在我们的场景就是把阅读理解拆解成了先找相似知识再回答出正确的答案,最后贴一下我们完整的prompt ![](/media/202309/2023-09-16_083145_5579980.334118423081901.png) 四、总结 Smart Copilot旨在提高技术服务团队的效率,提高客户满意度,在智能客服领域帮助提升效率, 在效果层面,我们也在持续的优化模型与检索算法,旨在打造一个垂直领域落地大模型的标杆,在未来我们也计划从Agent的层面出发,实现排障流程引导、自动排障等,进一步提升客服的专业度与解决问题的效率。 如果你有什么想法和需求,欢迎联系我们多多交流。
我有魔法
2023年10月28日 22:18
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码