RAG 的过程很复杂,包含许多组成部分。我们如何确定现有的 RAG 方法及其最佳组合,以确定最佳 RAG 实践?
论文 《Searching for Best Practices in Retrieval-Augmented Generation》给出了回答。
本文将从以下三方面进行介绍:
- 首先,介绍经典的 RAG 流程。
- 然后,介绍RAG 的每个模块的最佳实践。
- 最后,提供一个全面的评估。
一、经典的RAG流程
经典的 RAG 工作流程一般包括几个中间处理步骤:
-
查询分类(确定输入查询是否需要检索)
-
检索(高效获取相关文件)
-
重新排名(根据相关性优化检索到的文档的顺序)
-
重新打包(将检索到的文档组织成结构化格式)
-
摘要(提取关键信息以生成响应并消除冗余)
实现 RAG 还涉及决定如何将文档拆分为块,选择用于语义表示的嵌入,选择合适的向量数据库以进行高效的特征存储,以及寻找有效的微调方法LLMs,如图 1 所示。
图 1:检索增强生成工作流程。每个组件考虑的可选方法以粗体表示,而带下划线的方法表示各个模块的默认选择。以蓝色字体表示的方法表示根据经验确定的性能最佳的选择。
二、每个步骤的最佳实践
2.1 查询分类
为什么需要查询分类?并非所有查询都需要检索增强,某些LLMs功能也需要检索增强。虽然 RAG 可以提高准确性并减少幻觉,但频繁检索会增加响应时间。因此,我们首先对查询进行分类,以确定是否需要检索。通常,当需要超出模型参数的知识时,建议使用检索。
我们可以根据任务是否提供足够的信息将任务分为 15 种类型,并显示具体的任务和示例。完全基于用户提供信息的任务被标记为“充分”,不需要检索;否则,它们将被标记为 “不足” ,可能需要检索。
图 2:不同任务的检索要求分类。在未提供信息的情况下,我们会根据模型的功能对任务进行区分
此分类过程是通过训练分类器自动执行的。
图 3:查询分类器的结果
2.2 分块
将文档划分为较小的块对于提高检索准确性和避免 中的LLM长度问题至关重要。通常有三个级别:
-
Token-level令牌级分块很简单,但可能会拆分句子,从而影响检索质量。
-
Semantic-level语义级分块用于LLM确定断点,保留上下文但需要更多时间。
-
Sentence-level句子级分块在保留文本语义与简洁高效之间取得平衡。
在这里,句子级分块用于平衡简单性和语义保留。分块过程从以下四个维度进行评估。
2.2.1 分块大小
块大小会显著影响性能。较大的块提供更多的上下文,增强理解,但会增加处理时间。较小的块可以提高召回率并缩短时间,但可能缺乏足够的上下文。
图 4 :不同数据块大小的比较
如图 4 所示,使用了两个主要指标:忠实度和相关性。忠实度衡量反应是幻觉还是与检索到的文本相匹配。Relevancy 衡量检索到的文本和响应是否与查询匹配。
块组织
2.3 Embedding模型
如图 6 所示,LLM-Embedder 获得了与 BAAI/bge-large-en 相当的结果,但大小只有它的三分之一。因此,LLM选择 -Embedder 是为了平衡性能和大小。
图 6:namespace-Pt/msmarco 上不同嵌入模型的结果。
2.4 添加元数据
使用标题、关键字和假设问题等元数据增强块可以提高检索率。
该论文不包括具体的实验,但将它们留给未来的工作。
2.5 向量数据库
图 7 提供了五个开源向量数据库的详细比较:Weaviate、Faiss、Chroma、Qdrant 和 Milvus。
Milvus 在评估的数据库中脱颖而出,满足所有基本标准,并且在性能上优于其他开源选项。
图 7:各种矢量数据库的比较。
2.6 检索
对于用户查询,检索模块会根据其相似性从预先构建的语料库中选择与查询最相关的前 k 个文档。
下面评估了三种与检索相关的技术及其组合:
- 查询重写 :此技术改进了查询以更好地匹配相关文档。受 Rewrite-Retrieve-Read 框架的启发 ,我们提示LLM重写查询以提高性能。
- 查询分解:此方法根据从原始查询中提取的子问题检索文档。这些子问题通常更复杂,更难理解和处理。
- 伪文档生成 :此方法根据用户的查询生成假设文档,并使用假设答案的嵌入来检索类似的文档。一个值得注意的实现是 HyDE。
图 8:TREC DL19/20 上不同检索方法的结果。每种方法的最佳结果都用粗体显示,第二种方法用下划线表示。
图 8 显示,监督方法的性能明显优于无监督方法。通过将 HyDE 和混合搜索相结合,LLM-Embedder 获得了最高分。
因此,建议使用 HyDE + 混合搜索作为默认检索方法。混合搜索结合了稀疏检索 (BM25) 和密集检索 (原始嵌入),实现了高性能和相对较低的延迟。
2.7 重排序
初始搜索后, 重新排名阶段会增强检索到的文档的相关性,确保最相关的信息显示在列表顶部。考虑了两种主要方法:
- DLM 重排序:此方法使用深度语言模型 (DLM) 进行重新排名。这些模型经过微调,可将文档与查询的相关性分类为“true”或“false”。在微调期间,使用带有相关性注释的查询和文档对模型进行训练。在推理过程中,根据 “true” 标签的概率对文档进行排序。
- TILDE 重排序:TILDE 通过预测模型词汇中每个词的概率来独立计算每个查询词的可能性。通过将查询词的预计算对数概率相加来对文档进行评分,从而在推理过程中实现快速重新排名。TILDEv2 通过仅对文档中存在的术语进行索引、使用 NCE 损失和扩展文档来改进这一点,从而提高效率并减小索引大小。
图 9:MS MARCO Passage 排名数据集的开发集上不同重新排名方法的结果。对于每个查询,将对 BM25 检索到的前 1000 个候选段落进行重新排序。延迟以每个查询的秒为单位。
如图 9 所示, 建议使用 monoT5 作为平衡性能和效率的综合方法。 RankLLaMA 非常适合那些寻求最佳性能的人,而 TILDEv2 适合在固定集上快速实验。
2.8 重新包装
后续流程(如LLM响应生成)的性能可能会受到文档提供顺序的影响。
为了解决这个问题,我们在重新排名后的工作流程中加入了一个紧凑的重新打包模块,有三种方法:
-
“forward” 方法根据重新排序阶段的相关性分数按降序重新打包文档。
-
“reverse”方法将它们按升序排列。
-
受 Lost in the Middle 启发的 “sides” 选项在相关信息位于输入的开头或结尾时表现最佳。
由于这些重新打包的方法主要影响后续模块,因此在下面的 review 部分介绍它们的评估。
三、总结
检索结果可能包含冗余或不必要的信息,这可能会阻止 生成LLM准确的响应。此外,较长的提示可能会减慢推理过程。因此,在 RAG 过程中,汇总检索到的文档的有效方法至关重要。
提取式压缩器将文本分割成句子,根据重要性对它们进行评分和排名。Generative Compressor 综合来自多个文档的信息,以重新措辞并生成连贯的摘要。这些任务可以是基于查询的,也可以是非基于查询的。
主要评估三种方法:
- Recomp: 它具有抽取式和生成式压缩机。提取式压缩器选择有用的句子,而生成式压缩器则综合来自多个文档的信息。
- LongLLMLingua:它通过关注与查询相关的关键信息来改进 LLMLingua。
- 选择性上下文 :它通过识别和删除输入上下文中的冗余信息来提高效率 LLM。
图 10:不同摘要方法之间的比较。
如图 10 所示, 建议使用 Recomp, 因为它的性能非常出色。虽然 LongLLMLingua 表现不佳,但它在没有经过这些实验数据集训练的情况下表现出更好的泛化能力。因此,我们可以将其视为一种替代方法。
四、生成器微调
图 11 显示,使用混合相关和随机文档 (Mgr) 训练的模型在提供黄金文档或混合上下文时表现最佳。
因此, 在训练过程中混合相关和随机上下文可以提高生成器对不相关信息的鲁棒性,同时确保有效使用相关上下文。
图 11:生成器微调的结果。
五、综合评估
以前的评估是针对每个模块单独进行的,但现在这些模块被整合在一起以进行综合评估。
图 12:寻找最佳 RAG 实践的结果。正在调查包含在盒装模块中的模块,以确定最佳方法。带下划线的方法表示所选的实现。“Avg”(平均分数)是根据所有任务的 Acc、EM 和 RAG 分数计算的,而平均延迟是每个查询的秒数。最佳分数以粗体突出显示。
如图 12 所示,得出了以下关键见解:
- 查询分类模块: 该模块不仅提高了效果和效率,而且将总分从 0.428 分提高到平均分 0.443,并将查询延迟从 16.41 秒降低到 11.58 秒。
- 检索模块: 虽然 “Hybrid with HyDE” 方法的 RAG 得分最高,为 0.58,但其计算成本很高 ,每次查询需要 11.71 秒。 因此,建议使用 “Hybrid” 或 “Original” 方法,因为它们可以减少延迟,同时保持可比的性能。
- 重排序模块: 缺少重新排名模块会导致性能显著下降。MonoT5 获得了最高的平均分,证明了它在提高检索文档的相关性方面的有效性。这表明重新排名在提高生成响应的质量方面发挥着关键作用。
- 重新包装模块: 反向配置表现出卓越的性能,RAG 得分为 0.560。这表明,将更相关的上下文放在更靠近查询位置的位置会产生最佳结果。
- 摘要模块:Recomp 展示了卓越的性能,尽管删除摘要模块可以以更低的延迟获得类似的结果。尽管如此,Recomp 仍然是首选,因为它解决了生成器的最大长度限制。
六、结论
总体而言,推荐了两种不同的 RAG 系统实施策略:
- 最佳性能实践:为了获得最佳性能,包括查询分类模块,使用 “Hybrid with HyDE” 方法进行检索,采用 monoT5 进行重新排序,选择 “Reverse” 进行重新打包,并使用 Recomp 进行汇总。
- 平衡效率实践:为了平衡性能和效率,包括一个查询分类模块,实施 Hybrid 方法进行检索,使用 TILDEv2 进行重新排序,选择 “Reverse” 进行重新打包,并使用 Recomp 进行汇总。
如何学习大模型 AI ?
由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。
但是具体到个人,只能说是:
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
第一阶段(10天):初阶应用
该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。
- 大模型 AI 能干什么?
- 大模型是怎样获得「智能」的?
- 用好 AI 的核心心法
- 大模型应用业务架构
- 大模型应用技术架构
- 代码示例:向 GPT-3.5 灌入新知识
- 提示工程的意义和核心思想
- Prompt 典型构成
- 指令调优方法论
- 思维链和思维树
- Prompt 攻击和防范
- …
第二阶段(30天):高阶应用
该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。
- 为什么要做 RAG
- 搭建一个简单的 ChatPDF
- 检索的基础概念
- 什么是向量表示(Embeddings)
- 向量数据库与向量检索
- 基于向量检索的 RAG
- 搭建 RAG 系统的扩展知识
- 混合检索与 RAG-Fusion 简介
- 向量模型本地部署
- …
第三阶段(30天):模型训练
恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。
到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?
- 为什么要做 RAG
- 什么是模型
- 什么是模型训练
- 求解器 & 损失函数简介
- 小实验2:手写一个简单的神经网络并训练它
- 什么是训练/预训练/微调/轻量化微调
- Transformer结构简介
- 轻量化微调
- 实验数据集的构建
- …
第四阶段(20天):商业闭环
对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。
- 硬件选型
- 带你了解全球大模型
- 使用国产大模型服务
- 搭建 OpenAI 代理
- 热身:基于阿里云 PAI 部署 Stable Diffusion
- 在本地计算机运行大模型
- 大模型的私有化部署
- 基于 vLLM 部署大模型
- 案例:如何优雅地在阿里云私有部署开源大模型
- 部署一套开源 LLM 项目
- 内容安全
- 互联网信息服务算法备案
- …
学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。
如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。