提升 RAG 性能

2024/9/20 21:03:31

本文主要是介绍提升 RAG 性能,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

在我的上一篇博客中,我详细介绍了RAG及其与LlamaIndex的实现方式。然而,RAG在回答问题时经常会遇到许多挑战。在这篇博客中,我将解决这些问题,并且更重要的是,我们将深入探讨改进RAG性能的方法,使其能够投入生产使用。

图片来源:构建检索增强生成系统时的七个失败点

我将讨论来自不同研究论文的各种优化技术。其中大多数技术将基于我特别喜欢的一篇论文,题目为“大型语言模型的检索增强生成:综述”。这篇论文涵盖了最近的大多数优化方法。

RAG 工作流分解

首先,我们将把RAG工作流分解为三个部分,以增强我们对RAG的理解,并优化这些部分以提高整体性能:

预检索

在预检索步骤中,需要准备LLM原始训练数据集之外的新数据,也称为 外部数据 ,将其拆分成小块,然后使用 嵌入模型 将这些数据块转换为数值表示并存储在向量数据库中。这个过程创建了一个LLM可以理解的知识库。

RAG 中的预检索

检索

在最关键的检索步骤中,用户查询被转换为称为嵌入的向量表示,并通过余弦相似度从向量数据库中找到相关的片段。这尝试从向量存储中找到高度相关的文档片段。

检索后

接下来,RAG 模型通过在上下文中添加相关检索到的数据(查询+上下文)来增强用户输入(或提示)。这一步使用提示工程技术与大语言模型有效沟通。增强后的提示使大语言模型能够利用给定的上下文生成准确的答案来回答用户的问题。

RAG 中的检索和检索后处理

目标

我们旨在通过将各种技术应用于RAG工作流的不同部分来提升每个组件。

预检索优化

预检索技术包括提高索引数据的质量和分块优化。这一步也可以称为 增强语义表示

增强数据粒度

提高数据质量
垃圾进,垃圾出

数据清理在RAG框架中起着至关重要的作用。你的RAG解决方案的性能取决于数据清理和组织的程度。需要移除不必要的信息,例如特殊字符、不需要的元数据或文本。

  • 删除无关文本/文档:删除我们不需要LLM回答的所有无关文档。同时去除噪音数据,这包括删除特殊字符、停用词(如“the”和“a”)以及HTML标签。
  • 识别并纠正错误:这包括拼写错误、打字错误和语法错误。
  • 在分割的片段中用名字替换代词可以增强检索时的语义重要性。

添加元数据

添加元数据,例如概念和级别标签,以提高索引数据的质量。

添加元数据信息涉及将引用的元数据(如日期和目的)整合到片段中以进行过滤,同时将章节和子章节等元数据纳入其中以提高检索效率。

以下是一些元数据有用的情景:

  • 如果你搜索项目并且最近性是一个标准,你可以根据日期元数据进行排序
  • 如果你搜索科学论文并且提前知道你寻找的信息总是位于特定部分,例如实验部分,你可以为每个片段添加文章部分作为元数据,并根据它进行过滤以匹配实验部分的内容

元数据很有用,因为它在向量搜索之上添加了一层结构化的搜索。

优化索引结构

  • 知识图谱或图神经网络索引
    通过利用图数据索引中节点之间的关系来捕获相关上下文,结合图结构中的信息。
  • 向量索引
分块优化

选择合适的 chunk_size 是一个关键的决定,它可以从多个方面影响 RAG 系统的效率和准确性:

相关性和粒度
较小的 chunk_size,如 128,会产生更细粒度的片段。然而,这种粒度带来了一定的风险:关键信息可能不会出现在前几个检索到的片段中,特别是当 similarity_top_k 设置为严格的 2 时。相反,将 chunk_size 设置为 512 可以确保所有必要的信息都包含在前几个片段中,从而确保查询的答案随时可用。

响应生成时间
随着chunk_size的增加,输入到LLM中的信息量也会增加。虽然这可以确保更全面的上下文,但也可能会减慢系统速度。

挑战
如果分块太小,可能无法包含LLM回答用户查询所需的所有信息;如果分块太大,则可能包含过多无关信息,导致LLM混淆,或者超出上下文大小限制。

特定任务的分块
根据下游任务所需的最优分块长度来确定,并决定每个分块之间需要多少重叠。

高层次的任务如摘要生成需要较大的块大小,而低层次的任务如编码则需要较小的块大小。

分块技术

Small2big 或 Parent 文档检索

ParentDocumentRetriever 通过拆分并存储小的数据块来达到这种平衡。在检索过程中,它首先获取这些小块,然后查找这些小块的父ID,并将这些较大的文档返回给LLM。

它在初始搜索阶段使用小段文本块,并随后为语言模型提供更大相关的文本块进行处理。

递归检索涉及在初始检索阶段获取较小的片段以捕捉关键语义意义。随后,在过程的后期阶段,提供包含更多上下文信息的较大片段给大语言模型。这种两步检索方法有助于在效率和上下文丰富的响应交付之间取得平衡。

步骤:

  1. 这个过程涉及将原始的大文档分解为更小、更易管理的单元,称为子文档,以及较大的块,称为父文档。
  2. 它侧重于为每个子文档创建嵌入,这些嵌入比整个父文档嵌入更丰富和详细。这有助于框架识别包含与用户查询相关的信息的最相关的子文档。
  3. 一旦与子文档对齐,它会检索与该子文档相关的整个父文档。如图所示,最终检索到了父文档块。
  4. 检索父文档的这一过程非常重要,因为它为理解和响应用户的查询提供了更广泛的背景。框架不再仅依赖于子文档的内容,而是可以访问整个父文档。

Small2big 或 Parent 文档检索分块技术

句子窗口检索

这种分块技术与上述方法非常相似。句子窗口检索的核心思想是根据查询从自定义知识库中选择性地获取上下文,然后利用更广泛的上下文进行更强大的文本生成。

这个过程涉及将一组有限的句子嵌入以供检索,这些句子周围的额外背景信息被称为“窗口上下文”,会单独存储并与其关联。一旦确定了最相似的句子,这个上下文会在这些句子被发送给大型语言模型(LLM)生成之前重新整合,从而丰富整体的上下文理解。

解释句子窗口检索是如何工作的

Sentence Window Retrieval 分段技术在 RAG 中

检索优化

这是RAG工作流中最重要的部分,包括根据用户查询从向量存储中检索文档。这一步也可以称为 查询与文档的对齐

查询重写

查询重写是一种基本的方法,用于使查询和文档的语义相匹配。

在这个过程中,我们利用语言模型(LLM)的能力来重新表述用户的查询,并再次尝试。值得注意的是,两个在人类看来可能相同的问句,在嵌入空间中可能并不相似。

多查询检索器
多查询检索方法利用大语言模型从不同角度生成多个查询,以应对给定用户输入查询中的复杂问题和多个子问题,具有优势。

对于每个查询,它都会检索一组相关文档,并将所有查询的唯一联合取出来,以获取一组更大的潜在相关文档。

通过生成同一问题的多个视角,多查询检索器 可能能够克服基于距离的检索的一些限制,并获得更丰富的一组结果。

MultiQuery Retriever

Hyde 或 Query2doc
无论是 Hyde 还是 Query2doc,它们都是类似的查询重写优化。由于搜索查询通常很短、模糊或缺乏必要的背景信息,LLMs 可以提供相关的信息来引导检索系统,因为它们通过在数万亿个标记上进行预训练,记住了大量的知识和语言模式。

图,展示标准方法和Hyde方法之间的差异

图片来源:无需相关标签的精确零样本密集检索

StepBack-prompt
StepBack-prompt 方法鼓励语言模型超越具体示例,专注于更广泛的概念和原则。

此模板复制了“Step-Back”提示技术,该技术通过首先提出一个“退一步”的问题来提高对复杂问题的处理能力。此技术可以与标准的问题回答RAG应用结合使用,通过检索原始问题和退一步问题的相关信息。以下是一个“Step-Back”提示的例子。

图片来源: TAKE A STEP BACK: 通过抽象激发大型语言模型的推理

微调嵌入

微调嵌入模型会显著影响RAG系统中检索内容的相关性。这一过程涉及定制嵌入模型以增强特定领域上下文中检索的相关性,特别是在处理不断演变或罕见术语的专业领域中。

生成用于训练和评估的合成数据集
关键思想是,可以使用像GPT-3.5-turbo这样的语言模型来根据文档片段生成问题,从而生成用于微调的训练数据。这允许我们以可扩展的方式生成合成的正样本对(查询,相关文档),而无需人工标注。最终的数据集将是问题和文本片段的对。

微调嵌入
在生成的训练数据集上微调任何嵌入模型

使用GPT生成的合成数据集微调嵌入模型

混合搜索探索

RAG 系统通过智能地整合各种技术来优化其性能,包括基于关键词的搜索、语义搜索和向量搜索。

这种方法利用了每种方法的独特优势,以适应不同类型的查询和信息需求,确保一致地检索到高度相关且内容丰富的信息。混合搜索的使用作为检索策略的有力补充,从而提高了RAG管道的整体有效性。

常见示例
最常见的模式是将稀疏检索器(如BM25)与密集检索器(如嵌入相似度)结合使用,因为它们的优势是互补的。这也被称为“混合搜索”。稀疏检索器擅长根据关键词找到相关文档,而密集检索器擅长根据语义相似度找到相关文档。

混合搜索检索

检索后优化
重新排序

在将检索结果发送给大语言模型之前进行重排序,显著提升了RAG的性能。

向量相似度搜索得分高并不意味着它总是具有最高的相关性。

核心概念是重新排列文档记录,将最相关的项目放在前面,从而限制文档的总数。这不仅解决了检索过程中上下文窗口扩展的难题,还提高了检索效率和响应速度。

增加查询引擎中的 similarity_top_k 以检索更多上下文段落,在重新排序后可以减少到 top_n。

使用Cohere Reranker重新排序检索到的文档

提示压缩

检索到的文档中的噪声会损害RAG的性能,因此,与查询最相关的信息可能会被埋在包含大量无关文本的文档中。将整个文档传递给您的应用程序可能会导致更昂贵的LLM调用和较差的响应。

这里重点在于压缩无关的上下文,突出关键段落,并减少整体的上下文长度。

上下文压缩
上下文压缩旨在解决这一问题。其思路很简单:不是立即将检索到的文档原样返回,而是可以根据给定查询的上下文对它们进行压缩,从而只返回相关的信息。“压缩”在这里既指压缩单个文档的内容,也指整体过滤掉不相关的文档。

上下文压缩

Doc Compressor 是一个小的语言模型,用于计算用户查询和检索文档之间的提示互信息,估计元素的重要性。

模块化RAG

模块化RAG整合了各种方法来增强RAG的不同组件,例如引入一个搜索模块进行相似性检索,并在检索器中应用微调方法。

RAG Fusion

RAG Fusion 结合了两种方法:

  • 多查询检索
    利用大语言模型从不同角度生成多个查询,对于解决包含多个子问题的复杂问题很有优势。
  • 重新排序检索到的文档
    重新排序所有检索到的文档,并移除相关性评分低的文档。

图片来源: RAG-FUSION: 一种新的检索增强生成方法

这项高级技术确保搜索结果能够匹配用户的意图,无论这些意图是否明显。它帮助用户找到更加深入和相关的信息。

最终想法

本文讨论了优化RAG管道每一部分的各种技术,以提升整个RAG管道的性能。你可以根据需要在你的RAG管道中使用一种或多种这些技术,使其更加准确和高效。希望这些技术能帮助你为你的应用构建一个更好的RAG管道。

Medium的Boost / AI生活小技巧 / 免费的GPT替代方案 / Video2Worlds
Mlearning.ai 投稿建议如何成为 Mlearning.aimedium.com 的作者


这篇关于提升 RAG 性能的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程