心法利器[130] | RAG效果调优经验

心法利器

本栏目主要和大家一起讨论近期自己学习的心得和体会。具体介绍:仓颉专项:飞机大炮我都会,利器心法我还有

2023年新的文章合集已经发布,获取方式看这里:又添十万字-CS的陋室2023年文章合集来袭,更有历史文章合集,欢迎下载。

往期回顾

RAG这个东西伴随大模型的发展一直是被大家所关注的方案,然而经常有人会在用了之后说效果并不好,使用RAG后废话或者幻觉更多了,搜索召回的内容并不能很好地指导大模型生成更好的效果。但从后续的讨论和分析会发现,其实并不是RAG这条技术路线的问题,而是打开方式出现了错误。今天,我从效果调优的角度,和大家讲一下RAG的一些调优的经验,方便大家更快更准地找到问题并解决问题。

  • 核心思路

    • 复述方法论

    • RAG问题的分析思路

  • 可优化的trick

    • 文档处理和切片

    • 搜索

    • 大模型

  • 后记

核心思路

复述方法论

在开始之前,仍然重述一下效果调优的核心思路。我在很多文章里其实都有零散地提到,此处我再重新梳理一下。

首先是明确整个结论的合理性,光“效果不好”四个字的结论,虽说结论简单为好,但作为调优的人,专门解决这个问题的人,是需要深入探索分析这个问题内部的细节的:

  • 了解指标的具体含义,明确这个指标的合理性和科学性,说白了就是要思考这个指标是否合理。

  • 明确指标计算的数据集,是否可靠、正确以及合理,例如内部的抽样规则,数量和质量是否有保证。再次强调,一两个臆想出来的case的结果不符合预期,就认为是“效果不好”,这是非常不合适的,但其实现实中类似的判断并不少见,大家一定要避免。

  • 在明确这些问题后,我们才能够比较初步地把握目前整个算法方案的具体效果是什么样的。

然后是,以测试集的bad case分析为引子,逐步深入分析内部的原因,找到关键问题,这点,我在系列文章里有提到,这篇是合集:心法利器[37-40,115] | bad case治疗术:合集。此处不再赘述,唯一需要强调的是,至少在我的经验里,bad case分析是整个效果调优里非常重要的一环,他是我们真正找到问题的必经之路,尽管过程可能很枯燥,但最终的效率收益还是很高的,这套方案抛开了我们对问题的臆想,借助数据暴露的问题,能更精准地定位到问题,方便对症下药。

最后是方案的设计和事实。有了足够可靠、精准的问题分析,我们再设计方案,就更有针对性,兵来将挡水来土掩,具体有哪些可能的解决方案,可以看我下面RAG的一些调优经验。

RAG问题的分析思路

RAG和一般的算法不同,他是一个由多个模块组合而成的系统方案,离线的数据入库,在线的知识搜索和大模型结果生成,每一个模块都可能会出现问题,里面只要有一个模块出现问题,往往就会导致最终出现错误,因此,RAG问题一般的分析思路如下:

  • 最终目标指标的设计与数据集的选择。

  • 针对bad case,分析全流程的计算结果,确认该从case开始出错的位置,例如路由、召回、prompt构造、大模型、cot结果、反思等等,出错的次数多的,那就是问题的关键节点。

  • 针对出问题的部分,再来确定这个位置出现该问题的原因。例如路由部分的错误,大部分情况就是分类模型的错误,类目边界设计是否合理,知识是否有重合,模型本身的能力是否充足,如果是用大模型做的,那prompt是否有描述清楚等,如果是召回部分,则要考虑知识切片是否合理,向量召回的话两者的语义相关性是否足够等。

  • 足量分析,路径越长最好分析的数据量要越多,有些看不出问题的case,在数量的积累下会逐步有感觉,能感知到某些问题的聚集性,便能总结出某类型占所有问题的占比,占比高了就是重要问题,一旦解决便能带来可控可预知的收益。

  • 针对问题提出解决方案,实施和实验。

  • 回溯问题的解决情况,例如某个问题在bad case里的出现比例20%降低到10%,整体准确率是80%,那很可能整体准确率就能提升到82%左右了,带来2个点的收益,那就是明确收益了。

如此一来,一套可控、稳定的调优思路就出来了,大家可以参考这套思路,再迁移到自己的场景下实践。

可优化的trick

下面就是具体的优化方案,值得注意的是,下面的各种方法,最好都基于具体的问题定位进行针对性的选择,如果问题不出在此处,那用起来大概率是没用的。

文档处理和切片

之前我在qanything的源码解读文章里分享了各种文档处理的基本工具和原理(前沿重器[46] RAG开源项目Qanything源码阅读2-离线文件处理),然而这里是最基础的工作,但是如何切片、如何解析的细节,还没讲很多,我稍微展开讲一些可以考虑的trick。

文档处理大部分问题在切片,切片这个事并不是弄个移动窗口按着切就好了,对于不同类型的文章,尤其是不同知识密度的文章,切片粒度是不同的,在这篇文章里给出了很多切片的技巧:https://mp.weixin.qq.com/s/iqOqY3aHXEfiMELef6sNwQ,这里有非常多,我结合这篇文章和自己的经验讲一下几个重点:

  • 长度上,常见的经验是专业性文章,建议用更短的分片来向量化,注意尽可能留住句子内的专业名词。综述新闻类,可以长一些,保留完整信息。

  • 结合用户的输入习惯,query对长短都可能有用,可以考虑多粒度都切,然后都召回各自处理。

  • small2big要做,短句做向量索引,召回后用对应位置的上下文来进大模型prompt。

  • 可以额外加入一些分片的信息,例如所在章节、位置、连续信息的拼接、文章章节标题等。如果是因为切片内不包含这些信息导致无法召回,加入后应该就能召回了。

有关表格问题可能会有人来问,在一些场景可能会遇到,我自己做的会比较少,据我了解身边的经验更多是转化为xml或者markdown的格式,然后递归解析,这块因为我自己做得少所以就不赘述了。

搜索

搜索的事,顺带再把这个系列带上:前沿重器[48-54] 合集:四万字聊搜索系统,搜索的世界非常庞大,要想做好真要多学多思考,往扎心的说,别一天到晚抱着那个向量召回抱怨“效果不好”,真的要拓宽眼界。这个系列大家可以详细展开看看,我这里不赘述,我挑选一些比较重要的部分强调一下。

  • 知识库的领域差异较大的话,还是非常建议通过路由/意图识别的方式来分流分别处理,避免出现领域不同这种差距很大的情况,尤其是垂直领域。有一些比较极端的场景,甚至有人直接用分类模型把高频的几个问答内容给覆盖了,不得说效果很好。

  • 召回的方式可以很丰富,早期预期去调优向量,不如考虑字面召回,用BM25、关键词匹配的方式,召回率尽管低,但是准确率还是很高的,在线高频的case能快速解决,收益会非常大。

  • 不对称相似度问题,除了去折磨向量模型(类似bge-m3之类的模型确实可以拷打拷打),还可以考虑挖掘一些高频问题来进行补足修正,或者借助大模型进行问答对挖掘,QQ匹配远比QA匹配容易见效。

  • query改写是有用的,比较粗暴地,之前写过的这篇文章,再次拿出来:前沿重器[38] | 微软新文query2doc:用大模型做query检索拓展,收益真的很大。

  • 如果内部的切片个数非常多(例如达到10w以上),可以考虑在后面增加rerank模块,对TOP内容进行重新调整,少数据量可能对这个模块的敏感度不高,但是数量多了,语义空间密集了,TOPN召回的内容区分度不够高,通过精排模块能从中优中选优。

有关向量的模块单独说,调优的方案可以考虑这些:

  • bge-m3之类的后起之秀,是支持prompt的,通过提示引导模型给出不同的向量(多去看看论文以及开源代码),在其推理的开源项目里,是能找到一些prompt的,大胆使用。

  • Q也好A也罢,句子太长肯定不利于匹配,长句的信息量过多,匹配起来真的容易稀释(心法利器[51] | 长短句语义相似问题探索),切片能短还是尽量短。

  • 直接开源模型针对的是开放域,对于比较垂直的领域,确实是效果不是很好,此时,准备一些可供微调的数据,进一步微调是会有一定收益的,但也要把控好过拟合的风险。

  • 向量召回的匹配重点有不稳定性,不知道模型认为的重点和你认为的重点是否一致,有一个比较快速的trick是,对query做关键词抽取,过滤或者降权答案内不带有特定关键词的召回结果,能提升准确率。

  • 卡阈值,卡阈值,卡阈值,向量召回或者向量索引,只管给TOPN,如果文档中不存在有关内容,那就没必要放到大模型内了,应该被过滤,此时就需要卡阈值,并做好无答案时下游应该有的回应。

大模型

大模型的部分,我们其实要关心的并不是很多,在绝大多数情况,大模型能结合我们给的检索结果,就能给出合适的回答,但在一些情况,可能并不能,有一定概率是如下原因或解决方案。

  • 模型自己的知识根深蒂固,不够信任我们的知识,可以加上时间、引用材料、作者之类的信息,配合CoT等方式,进行进一步的强化其忠诚度和准确度。

  • 微调的收益一般不是很大,很多时候在解码方案里进行加权,或者使用回溯之类的方式可以优化,至少sft是,反而会降低对资料的信任度或削弱推理能力,至于RL,还有待验证。

  • 回复的可靠性和大模型本身的能力也有很强的关系,越强的、越大的模型忠诚度还是会提升的。

  • 给大模型准备好垃圾桶或者兜底方案,在所给资料中无信息时,设计好兜底方案,例如给出“参考资料中未发现符合要求的回复”,甚至做后处理验证,都是可以的,知识库终究是有限的,所以我们很难避免去做这种兜底方案。

后记

写这篇文章的核心目的是希望能给大家更多调优方面的trick建议,方便大家能有更多拿得出手的招数,也让大家能进一步理解到RAG整个生态体系下的一些常见的模块和方法,最近所谓的deep search概念出来很多人又开始焦虑,不过其实仔细研究发现,不过是新瓶装旧酒,内部很多技术仍旧类似,即使Deepseek的新模型出来,目前RAG所面临的一些问题仍旧存在,知识的更新与筛选在目前版本下,RAG仍旧是一个非常不错的路径,所以持续学习和研究仍旧是有意义的。

7bf3cf63693dc767d10aaa01fd277bf2.png

资源下载链接为: https://pan.quark.cn/s/f989b9092fc5 HttpServletRequestWrapper 是 Java Servlet API 中的一个工具类,位于 javax.servlet.http 包中,用于对 HttpServletRequest 对象进行封装,从而在 Web 应用中实现对 HTTP 请求的拦截、修改或增强等功能。通过继承该类并覆盖相关方法,开发者可以轻松地自定义请求处理逻辑,例如修改请求参数、添加请求头、记录日志等。 参数过滤:在请求到达处理器之前,可以对请求参数进行检查或修改,例如去除 URL 编码、过滤敏感信息或进行安全检查。 请求头操作:可以修改或添加请求头,比如设置自定义的 Content-Type 或添加认证信息。 请求属性扩展:在原始请求的基础上添加自定义属性,供后续处理使用。 日志记录:在处理请求前记录请求信息,如 URL、参数、请求头等,便于试和监控。 跨域支持:通过添加 CORS 相关的响应头,允许来自不同源的请求。 HttpServletRequestWrapper 通过继承 HttpServletRequest 接口并重写其方法来实现功能。开发者可以在重写的方法中添加自定义逻辑,例如在获取参数时进行过滤,或在读取请求体时进行解密。当用这些方法时,实际上是用了包装器中的方法,从而实现了对原始请求的修改或增强。 以下是一个简单的示例,展示如何创建一个用于过滤请求参数的包装器: 在 doFilter 方法中,可以使用 CustomRequestWrapper 包装原始请求: 这样,每当用 getParameterValues 方法时,都会先经过自定义的过滤逻辑。 HttpServletRequestWrapper 是 Java Web 开发中一个强大的工具,它提供了灵活的扩展性,允许开发者
<think>好的,我现在需要回答用户关于RAG(检索增强生成)模型的开发与性能方法的问题。首先,我得确保自己正确理解RAG的机制。RAG结合了检索系统和生成模型,通过检索相关文档来增强生成结果的质量。接下来,我需要分步骤考虑开发过程和化技巧。 开发流程方面,应该从数据准备开始,包括文档的预处理、分块和嵌入。用户可能想知道具体的数据处理方法,比如分块策略,比如固定长度还是根据语义分割。然后,检索系统的搭建是关键,可能涉及到使用Elasticsearch或FAISS这样的工具。这部分需要详细说明如何建立高效的索引和检索机制。 然后是生成模型的选择,常见的有GPT系列、Llama等。需要提到模型微的重要性,比如如何利用特定领域的数据进行微,以提升生成内容的相关性。此外,用户可能关心如何将检索和生成两部分有效结合,比如通过注意力机制或重排序策略。 性能方面,用户可能想知道如何评估RAG效果,比如使用BLEU、ROUGE等指标,或者人工评估。化检索效率可能包括索引结构的化、近似最近邻算法的整。生成质量的提升可以通过整温度参数、top-k采样等方法。另外,可以引用参考中的信息,比如高级RAG技术如何提升信息覆盖的深度和范围,这可能涉及到多阶段检索或查询扩展技术。 还需要考虑用户提到的引用内容,比如引用[1]提到高级RAG技术增加了信息的范围和深度,这可能对应多轮检索或混合检索策略。引用[3]中提到的微模型的方法,比如对GPT3.5和Llama2的微,可以说明模型微化中的重要性。此外,路线图引用[2]可能涉及到学习资源和系统化的开发步骤。 最后,要确保回答结构清晰,分点列出开发步骤和化技术,并自然地插入引用标记。同时,生成的相关问题需要与RAG开发相关,比如评估方法、微技巧、应用场景等。</think>### RAG(检索增强生成)模型的开发与性能方法 #### 一、RAG开发流程 1. **数据准备与处理** - **文档分块**:根据语义或固定长度分割文本(例如每段512词),使用滑动窗口减少信息丢失[^1]。 - **嵌入模型选择**:采用预训练模型(如BERT、RoBERTa)生成文本向量,支持相似性检索。 - **索引构建**:使用向量数据库(如FAISS、Elasticsearch)建立高效检索结构,支持近似最近邻搜索[^1]。 2. **检索系统搭建** - **混合检索策略**:结合关键词检索(BM25)与语义检索,提升召回率。 - **重排序机制**:通过交叉编码器(如ColBERT)对初步结果重排序,提高相关性。 3. **生成模型化** - **微方法**:在领域数据上微生成模型(如GPT-3.5、Llama2),增强上下文适应性[^3]。 - **注意力注入**:将检索结果通过注意力机制融入生成过程,公式表示为: $$ \text{Output} = \text{Decoder}([\text{Query}; \text{Retrieved\_doc}]) $$ #### 二、性能技术 1. **检索效率化** - **分层索引**:构建粗粒度+细粒度的双层索引结构,平衡速度与精度。 - **量化压缩**:对嵌入向量使用PQ(Product Quantization)技术,减少内存占用。 2. **生成质量提升** - **动态温度节**:根据检索置信度整生成温度参数,公式: $$ T = \alpha \cdot \text{max}(scores) + \beta $$ - **后处理过滤**:使用规则引擎或分类器过滤生成结果中的矛盾信息。 3. **评估体系构建** - **量化指标**:采用RAGAS框架计算答案忠实度(Faithfulness)和上下文相关性(Context Relevance)。 - **人工评估**:设计细粒度评分卡(0-5分制),覆盖事实准确性、连贯性等维度。 #### 三、典型化案例 某论文审稿系统通过以下改进使效果超越GPT-4[^3]: 1. 使用13B参数的Llama2模型进行两阶段微 2. 构建包含10万级paper-review数据集的训练集 3. 引入多视角检索机制(摘要+方法论+结论独立检索)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值