心法利器基础RAG-调优方案
作者: AINLP 来源: AINLP
前两期,给大家介绍了最基础的RAG需要什么样的模块,这两篇从读者这边的回应来看还是不错的,但问题在于,这个比较基础,在日后的调优中,可能会比较掣肘,今天准备的这篇就是来给大家讲,RAG一般的优化手段会有哪些。但因为各种优化手段并不一定在每个场景都有成效,且不同项目下有些微操可能会不同,我没有准备代码,更多需要大家根据实际情况选用和实操了。
开始之前,我先把前面的两篇基础RAG文章的传送门放这里:
提前说一下,这里的方案,大都看起来没那么炫酷,更多是结合实际情况发现的trick,要想知道论文这块比较前沿的方式,可以期待我后面的文章。
重提:大模型调优
在前些日子,我写过一篇有关大模型调优的方法论:心法利器[103] | 大模型bad case修复方案思考,这里有三个比较核心的观点:
-
大方向上,调优主要拆解成两块,分别是对大模型的调优和对大模型前后处理的调优。
-
大模型微调的收益主要在于,但是在实际应用中,对于调优的反馈并不是很明显。
-
前后处理的调优,能更对症,正因如此,现实情况备受青睐。
因此,在实际应用中,我们更多把着力点放在前后处理,通过前后的调整,争取能够得到更符合需求的回复。
检索模块的调优
值得强调的是,检索模块才是RAG模块调优空间最大的部分,而并非大模型本身,尤其是项目的前期,毕竟“查的准”是大模型最终能吐出正确结果的前提条件,一旦结果查的不对,大模型预测的结果可能还不如不进行RAG,这点是应该能从大量的case分析中得发现的,早期的RAG项目,经验上大概有80%+的问题来源于检索,此时,优化检索的结果,让查询能查的准,就变得非常重要。
那么,检索模块的调优,能有哪些呢?这点其实在早期的搜索领域已经非常丰富的经验了(别只惦记着那个向量召回了),这里提供几个常用的思路:
-
构造意图识别模块,可以是分类模型、词典,甚至是知识库检索的时候加一个阈值都可以,一方面对知识库外的内容进行拒识(毕竟知识都不存在了,怎么在库里面查都是不对的),另一方面,在有知识类目下的对知识和query进行分类对应,能提升检索的准确性的同时,降低在检索错误时带来的伤害(即使错了知识点,也大概都能在一个领域内的)。
-
新增字面检索。很多人会提出字面检索的泛化性能不够,但从实际出发,用户的输入往往是长尾效应,即用户的输入习惯会比较集中,在前期尽可能覆盖高频的说法,尽可能匹配到用户常说的内容,其实就已经能让用户体验和整体指标有明显的提升了。当然,字面还能做得更加精细,例如配合实体抽取来做,“周杰伦的七里香”,识别歌手和歌名,这里就能精准匹配到一首歌了。进一步,字面检索本身也有很多优化的trick,例如基于tf-idf做词权重计算,引入BM25等,有无字面检索是一方面,字面检索的好坏还是另一方面。
-
query拓展,借助同义词、大模型拓展、相似度召回等方式,对query进行拓展或者说规范化,例如对某些词汇进行规范化,像一些业务上的简称等。
-
多路召回和精排。如果一路召回不足,可以考虑多进行几次召回,例如字面、向量召回都做,再例如向量召回也可以多用几个不同的模型,例如qq匹配、qa匹配,浅层模型和深层模型等;召回路多了,此时结果要合并进行筛选,这就需要精排,精排不见得一上来就要模型,毕竟早期没什么数据,而且因为产品原因不可能也没有什么点击数据,此时用一些规则,例如字面的准确率高点,卡一个高点的阈值排在前面就行之类的。
-
向量召回模型本身也有调优的空间,早期其实直接用预训练好的simcse、BGE、M3E等模型即可,后期结合自己收集的业务数据,进一步做调优就行,具体的微调方案,直接看对应项目的代码,都是有的。
本身搜索就不是什么很新的技术,前人在这里已经有大量的工作,老粉们应该也有所了解,我在这方面也有不少文章,大家可以在我的历史文章里看看有没有值得采用的方案,这里的可操作空间其实非常大,上面提的每个方面其实都能干上好久。
Prompt
获取检索的结果后,在进入大模型之前,还需要通过prompt工程把检索结果、用户query以及其他的辅助信息进行有机拼接再送入模型。如果从结果来看,就是一个字符串拼接的工作,但实际上从对大模型的理解,对有效信息的组合上看,这里无论是所谓的“技术含量”还是“结果收益”上,其实都挺重要的,不应该小看。
首先基础层面,我曾经写过一篇比较重要的文章,强烈建议大家系统学一遍:
此后,便是结果的组合,一般情况,RAG中的prompt常用的格式,和我在git开源的项目是类似的,我直接贴过来:
RAG_PROMPT = """请根据用户提问和参考资料进行回复,回复的内容控制在100字左右。
用户提问:{}
参考材料:
{}"""
在一些情况,我们是能添加一些限定条件或者是调整,使之符合我们实际任务的需求,我这里句一些例子:
-
字数限定。在一些情况,限定字数能让大模型的输出更加精准,废话比较少,同时说的少出错的概率也就小很多。
-
角色限定。“你是一名出色的律师”、“你是一名优秀的医生”,类似这样的角色限定,在一些情况能让最终输出的质量有所提升。
-
细化具体要求,如“只根据参考材料回复,如果参考材料回答不了问题,请拒绝回答”。
当然了,也可以配合上游的query理解、query拓展等操作,给出一些提示,这些提示能让模型的输出不那么离谱。例如:
-
“请注意,此问题需要关注的关键词是:XX”。
-
“文中提及了歌手【周杰伦】”。
另外,还有一些类似先把参考材料进行摘要压缩等的一些方案,在特定场景也会有一些收益。
后处理
除了前处理,还有一些后处理的trick,可以跟大家说一下:
-
质检,是否有不符合对应场景要求的,例如医疗领域的开药规则,金融领域的话术约束等。
-
某些约束是否有生效,例如字数。
如果有,则可以把条件再加入,然后让大模型再调整一次,能很大程度有特别的要求。
另外,值得注意的是,有一个大家反复在聊的问题——重复,这里我着重聊一下,从感性和理性角度来聊其内部机理:
-
感性上,字数和内容没有什么约束,大模型又必须有话说,因此只能多说几次。
-
理性上,生成角度,部分话术形成了局部最优,所以模型反复说。
因此,核心解决思路就是围绕上面亮点来进行,主要有如下手段:
-
微调,用领域知识进行微调,提升模型的底层能力,增加谈资。
-
prompt层面,控制输出的字数。
-
在generate层上,用重复的惩罚项来进行约束,具体可以参考:心法利器[89] | 实用文本生成中的解码方法中提及的参数。
大模型微调
最后才是大模型微调能做的。一般而言,即使在检索模块能返回正确结果的情况下,大模型仍有一定5%-10%的可能会输出错误,这里可以统一把他叫做“幻觉问题”了,这里跟MRC(机器阅读理解)中的错误其实类似,也很难避免,而如果现阶段已经成为短板,急需解决的话,仍然有一些微调的手段来优化这部分问题。目前发现这些常见问题。
-
模型对某些概念并不能很好的理解,此时要么通过检索层增加对某些关键概念的解释,要么通过大模型微调把某些知识学到大模型里面。
-
缺少背景知识,例如医疗大模型没有法律方面的知识,或者开放域大模型没有特定专业领域的知识,模型对某些内容的甄别不足,此时需要进一步微调学习领域知识。
-
提供的背景知识过多,模型无法解析和处理。这个一方面是客观的整体promt太长,另一方面是大模型本身上限所在,此时一方面可以微调,另一方面可以考虑压缩背景知识内容,例如原来取TOP5,现在取TOP3,或者提前对某些内容摘要或者压缩一下,应该也会有所减缓。
小结
本文主要给大家讲一些RAG方面的一些常见的问题以及常用的调优手段,这些基本都是我自己日常开发过程中经常遇到的了,多半是经验性质,希望大家都有用吧。
另外,可能会有一些人会问,这些方案和问题都是怎么发现的,我只想说,还是得多看多分析数据,发现其中的问题,探究问题在哪个环节上出的问题,前文应该提及一些类似5-10%,80%+,这些都是在bad case分析过程统计发现的,这块的方法论,看我这系列的文章吧,这是最后一篇,里面有每一篇的传送:心法利器[40] | bad case治疗术:解决篇。
进技术交流群请添加AINLP小助手微信(id: ainlp2)
请备注具体方向+所用到的相关技术点
![](https://api.allorigins.win/raw?url=https://mmbiz.qpic.cn/mmbiz_jpg/nW2ZPfuYqSJADkmZ2IX6Z23znAibuEevotDMq9iaMxiapK7jfMibiauGFkycicAJEs6x5U9SGyDJZ0S1tRed9TPNUUDQ/640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1&wx_co=1)
关于AINLP
AINLP 是一个有趣有AI的自然语言处理社区,专注于 AI、NLP、机器学习、深度学习、推荐算法等相关技术的分享,主题包括LLM、预训练模型、自动生成、文本摘要、智能问答、聊天机器人、机器翻译、知识图谱、推荐系统、计算广告、招聘信息、求职经验分享等,欢迎关注!加技术交流群请添加AINLP小助手微信(id:ainlp2),备注工作/研究方向+加群目的。
![](https://api.allorigins.win/raw?url=https://mmbiz.qpic.cn/mmbiz_jpg/nW2ZPfuYqSKABHCqVVQkVYPrM4XY1vsd0iaeuXzyJnoFc8cibd5mYb4wdA3WMQtiaPVmr0XLZHMuVibqWncibpnTSnQ/640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1&wx_co=1)**
更多AI工具,参考Github-AiBard123,国内AiBard123