人工智能 AI RAG 工程实现全流程

  1. RAG

    1.1

    RAG概述

RAG是为了解决LLMs在实际应用中面临的问题(如幻觉、知识更新缓慢和答案缺乏透明度等)所衍生出的一种解决方案。主要通过从外部知识库检索相关信息来辅助大型语言模型回答问题,能显著提高回答的准确性,减少模型产生的幻觉,尤其是在知识密集型任务中(已被证实有效)。

1.1.1 RAG的定义和作用

1 RAG的定义

RAG(Retrieval Augmented Generation),即检索增强生成。它的本质是让模型获取正确的Context(上下文),利用ICL (In Context Learning)的能力,输出正确的响应。它综合利用了固化在模型权重中的参数化知识和存在外部存储中的非参数化知识(知识库、数据库等)。
1 RAG的技术含义

主要是对现有文档进行检索相关信息后再利用检索到的信息来生成最终答案,从而提高预测的质量。

例如,假设一个工程师需要从厚厚的《业务操作手册》中找到相关的业务知识来帮助他完成工作,那么他有三种方式可以使用:
1 最原始:自行查阅《业务操作手册》
1 借助问答机器人:直接咨询自答机器人,但可能有两个麻烦。一是类似于FAQ,一问一答,还需要自行组合所有回答;二是该机器人需要前期需要大量的预训练知识库,工作量极大,不适合大面积推广运用。
1 RAG:直接把《业务操作手册》上传系统,系统直接把它变成索引,以供咨询。且RAG会结合手册相关知识并以专家的口吻为你提供一个富有逻辑性的答案。
1 RAG的两个关键阶段
1 检索阶段:使用编码模型(如BM25、DPR、ColBERT等)根据问题检索相关文档。
1 生成阶段:使用检索到的上下文作为条件生成文本。

RAG的主要流程:数据提取——embedding(向量化)——创建索引——检索——重排序(Rerank)——LLM归纳生成。

1.1.2 RAG的分类

RAG技术可以分成三类,代表了不同的技术复杂度,越复杂也代表实现难度越大。但是可能会收到更好的效果,适应更多的场景。这三类分别是:


1 Naive RAG (RAG)

描述:通过将文本分段并根据用户的Qurey去检索相关段落,输入到模型中生成相应。

问题:
1 文本分段生硬,可能不科学。
1 查询到的分段可能不相关。
1 输入文本可能包含冗余、重复或噪声信息,导致模型输出与期望不一致。
1 Advanced RAG (高级RAG)

描述:针对Naive RAG的不足进行改善,主要在检索过程中进行优化,包括Preretrieval(检索前)、Post-retrieval(检索后)和Retrieval Process(检索中)的改进。

改进办法:
1 检索前:建立多种文档索引,利用滑动窗对文本进行分块。
1 检索中:多路召回,Embedding模型微调等。
1 检索后:重排(Re-rank)等方法。
1 Modular RAG (模块化RAG)

描述:模块化方法并不局限在“检索”-“阅读”的框架,利用大模型自身的"反思"能力等,构建起RAG的新的范式。

特点:
1 不同于单一流水线,具有模块化的设计。
1 利用模型的反思能力,递归调用LLM,实现RAG Agent。
1 被认为是RAG领域的趋势,提供更灵活的处理方式。

1.1.3 RAG vs 微调

1 优化技术的差异:RAG类似于为模型提供教科书,使其能够根据特定查询检索信息。适用于模型需要回答特定查询或处理特定信息检索任务的场景。微调则类似于让学生通过广泛学习来内化知识,适用于模型需要复制特定结构、风格或格式的情况。
1 适用场景:
1 RAG:适用于需要回答具体查询或特定信息检索任务的场景。
1 微调:适用于强调基础模型中的现有知识,修改或定制模型输出,为模型提供复杂指令的场景。
1 互补性:RAG和微调不是相互排斥的,而是可以相互补充,从不同层面增强模型的能力。某些情况下,结合这两种技术可以实现最佳的模型性能。

1.1.4 RAG的优势

1 透明度:通过引用的来源来验证答案的准确性;
1 可扩展性:RAG能够处理大规模数据集而无需更新所有参数和创建训练集,使其在经济上更有效率;
1 定制化能力:通过索引相关文本语料库来定制不同领域的模型,为特定领域提供知识支持;
1 结果的可信度:RAG从最新数据中选择确定性结果,而微调模型在处理动态数据时可能出现幻觉和不准确性,缺乏透明度和可信度。
1 提高答案准确性:通过引用外部知识库中的信息,减少语言模型幻觉问题,以提供更准确的回答;
1 安全性和隐私管理:RAG在数据库中内置了角色和安全控制,可以更好地控制数据使用;
1 保持信息的时效性和准确性:通过结合LLMs的参数化知识和外部知识库的非参数化知识,RAG可以识别最新信息,有效地解决了知识更新的问题。

1.2

RAG框架

RAG有非常多的组件,简单来说可以把RAG——Retrieval Augmented Generation理解为Retrieval And Generation,也就是检索与生成,加上一个数据向量和索引的工作,我们对RAG就可以理解为“索引、检索和生成”。

RAG技术细节概览

1.2.1 数据索引

这一过程通常在离线状态下进行,包括数据清理、提取,将不同文件格式转换为纯文本,然后进行文本分块,并创建索引。
1 数据提取
1 数据清洗:包括数据Loader,提取PDF、word、markdown以及数据库和API等;
1 数据处理:包括数据格式处理,不可识别内容的剔除,压缩和格式化等;
1 元数据提取:提取文件名、时间、章节title、图片alt等信息。
1 分块
1 固定大小的分块方式:一般是256/512个tokens,取决于embedding模型的情况。但该方式会损失很多语义,这对于检索是非常不友好。

弊端例子:
如“我们今天晚上应该去吃个大餐庆祝一下”,很有可能就会被分在两个chunk里面——“我们今天晚上应该”、“去吃个大餐庆祝一下”。
解决办法:
增加冗余量,比如512tokens的,实际保存480tokens,一头一尾去保存相邻的chunk头尾的tokens内容。
1 基于意图的分块方式:
1 句分割:通过句号和换行来做切分,或通过专业的意图包来切分的,常用的意图包有基于NLP的NLTK和spaCy;
1 递归分割:通过分而治之的思想,用递归切分到最小单元的一种方式;
1 特殊分割:还有很多不常见的,用于特殊场景;
1 固定大小的分块方式:同上。
1 影响分块策略的因素:
1 取决于索引类型:包括文本类型和长度,文章和微博推文的分块方式就会很不同;
1 取决于模型类型:使用什么LLM也会有不同,因为ChatGLM、ChatGPT和Claude.ai等的tokens限制长度不一样,会影响分块的尺寸;
1 取决于问答的文本的长度和复杂度:最好问答的文本长度和分块的尺寸差不多,这样会对检索效率更友好;
1 应用类型:RAG的应用是检索、问答和摘要等,都会对分块策略有不同的影响。
1 向量化

向量化是将文本、图像、音频和视频等转化为向量矩阵的过程,也就是变成计算机可以理解的格式,embedding模型的好坏会直接影响到后面检索的质量,特别是相关度。以下是现有可选择的embedding模型:
1 BGE:国人开发的中文embedding模型,在HuggingFace的MTEB(海量文本Embedding基准)上排名前2,实力强劲;
1 M3E:国人开发的中文embedding模型,总体来说也算可以,使用效果主要看具体使用场景;
1 通义千问的embedding模型:1500+维的模型;
1 Text-embedding-ada-002:OpenAI的embedding模型,1536维,应该是目前最好的模型,但在MTEB上排名好像只有第六,且国内不太能用;
1 自己训练embedding模型:基于一个既有embedding模型来训练,一般有希望让它在原来的基础上提升3%-10%的性能。

embedding相关文章:

大模型应用中大部分人真正需要去关心的核心——Embedding

1.2.2 检索环节(Retriever)

主要使用相同的编码模型将用户输入转换为向量,计算问题嵌入和文档块嵌入之间的相似度,选择相似度最高的前K个文档块作为当前问题的增强上下文信息。

(1)预检索过程
1 优化数据索引:提高索引内容的质量,包括增加索引数据的细粒度、优化索引结构、添加元数据、对齐优化和混合检索等。
1 提高索引数据的粒度 :具体来说包括剔除文章中的不相关内容、特殊字符。消除术语和实体的歧义,消除冗余和重复信息。
1 优化索引结构 :包括调整数据块大小、创建多个索引和加入图结构信息,使用图谱结合查询也会提升效果。
1 添加元数据 :这一策略的核心是将引用的元数据,如日期和用途(用于筛选)等,嵌入到数据块中。添加如章节和引用小节等元数据,对于提升检索效率是有益的。当索引被分割成多个块时,如何高效检索便成为关键。通过元数据进行初步筛选可以提高检索的效率和准确性。
1 对齐优化 :意思是怎么准确的理解用户的意图,并保证检索的文档内容与用户意图正确相关。实现方法包括了预先将文档生成假设性问题,并且对问题进行Embedding,来匹配用户的Query。
1 混合检索 :通过智能融合关键字搜索、语义搜索和向量搜索等技术,RAG系统可以利用每种方法的优势,适应不同类型的查询和信息需求,确保一致地检索到最相关和上下文丰富的信息,提高召回率。
1 递归检索和查询引擎:递归检索意味着在初始检索阶段获取较小的文档块以捕获关键语义含义,然后在后续阶段向语言模型提供更多上下文信息的较大块。这种两步检索方法有助于在效率和富有上下文的响应之间找到平衡。
1 StepBack-prompt:将StepBack-prompt方法集成到RAG过程中,鼓励大型语言模型从特定实例中退后,参与对背后的一般概念或原则的推理。实验结果表明,在各种具有挑战性的、推理密集的任务中,结合后向提示的运用能显著提高性能,显示出其在RAG中的自然适应性。
1 嵌入和索引:涉及通过语言模型将文本编码为向量的过程,包括微调嵌入和动态嵌入。
1 微调嵌入:提高检索内容与查询之间的相关性。
1 动态嵌入:基于单词出现的上下文动态调整嵌入。
1 元数据过滤:当我们把索引分成许多chunks的时候,检索效率会成为问题。如果可以通过元数据先进行过滤,就会大大提升效率和相关度。

例如,我们问“帮我整理一下XX部门今年5月份的所有合同中,包含XX设备采购的合同有哪些?”。
如果这时候有元数据,我们就可以去搜索“XX部门+2023年5月”的相关数据,检索量一下子就可能变成了全局的万分之一。
1 图关系检索:如果将很多实体变成node,把它们之间的关系变成relation,就可以利用知识之间的关系获得更准确的回答。(特别是针对一些多跳问题,利用图数据索引会让检索的相关度变得更高。)

(2)检索过程优化
1 提高检索准确性

在检索器上可以做的优化主要是:
1 更好的语义表达:文档分段优化,例如滑动窗,或者根据文档结构建立分段,以及微调Embedding模型。
1 匹配(对齐)Query和文档:对Query进行重写、分类,Embedding 变换(就是利用模型来实现Query的更优的Embedding表达)等。
1 匹配检索器和LLM:由于每个LLM都有自己的"风格",因此检索到的内容也要符合LLM的风格才能获得最好的效果。
1 获得好的生成

在检索后处理,可以优化的环节有:
1 重排序(ReRank):对检索到的信息进行重新排序,并且根据LLM关注特点,调整输入内容的位置,将最相关的信息放置在提示的边缘。
1 提示压缩(Prompt):通过压缩不相关的上下文、突出关键段落和减少总体上下文长度来提高RAG性能。
1 对LLM进行微调:RAG也是一个子任务,可以通过微调提高LLM在RAG任务上的表现。
1 检索技术
1 相似度检索:相似度算法包括欧氏距离、曼哈顿距离、余弦等,具体可以参考embedding相关文章《大模型应用中大部分人真正需要去关心的核心——Embedding》;
1 关键词检索:传统检索方式,一种是上述提到的元数据过滤,还有一种就是先把chunk做摘要再通过关键词检索找到可能相关的chunk,增加检索效率;
1 SQL检索:是一种更传统的检索方式,对于某些本地化的企业应用,SQL查询是必不可少的一步。
1 查询转换(一种查询检索的方式)
1 子查询:

可以在不同场景中采用各种查询策略,如使用LlamaIndex等框架提供的查询器,采用树查询(从叶子结点,一步步查询,合并),采用向量查询,或者最原始的顺序查询chunks等。
1 HyDE:一种抄作业的方式,生成相似的或者更标准的prompt模板。

使用大型语言模型,HyDE针对查询生成一个假设的文档(答案),嵌入该文档,并利用这种嵌入来检索与假设文档类似的真实文档。

与基于查询的嵌入相似性不同,这种方法强调从答案到答案的嵌入相似性。

弊端:这种方法可能并不总是能够产生有利的结果,特别是在语言模型不熟悉讨论主题的情况下,可能导致生成更多错误实例。

1.2.3 生成(Gen)

Gen使用的框架有Langchain和LlamaIndex,值得关注的是Prompt工程,在Prompt中是有很多决定因素的,这和所处行业的knowhow有关。

主要是将给定的问题和相关文档合并为新的提示,然后由大型语言模型基于提供的信息回答问题。如果有历史对话信息,也可以合并到提示中,用于多轮对话。

如在文旅行业,你要知道游客或者观众一般会怎么提问,真正需要得到的是什么内容。

1.3

模块化RAG(Modular RAG)

模块化RAG结构打破了传统的原始RAG框架(索引、检索和生成),提供了更大的多样性和整个过程的灵活性。

它整合了各种方法来扩展功能模块,如在相似性检索中加入搜索模块,以及在检索器中应用微调方法。此外,特定问题的出现促使重构的RAG模块和迭代方法的出现。

模块化RAG范式正成为RAG领域的主流,允许采用序列化管道或跨多个模块的端到端训练方法。

1.3.1 新模块

1 搜索模块:针对特定场景,将直接搜索引入过程中,使用由LLM生成的代码、查询语言(如SQL、Cypher)或其他自定义工具。
1 记忆模块:利用LLM自身的记忆能力来指导检索。原则是找到与当前输入最相似的记忆。

例如,Self-mem迭代地使用一个检索增强生成器来创建一个无限的记忆池,结合“原始问题”和“对偶问题”。
1 对齐模块:在模块化RAG时代,在检索器中添加一个可训练的Adapter模块可以有效缓解查询和文本之间的对齐问题。
1 验证模块:在检索文档后可以引入额外的验证模块,以评估检索到的文档与查询之间的相关性,增强RAG的鲁棒性。
1 额外生成模块:在检索到的内容中,冗余和噪声是常见问题。额外生成模块利用LLM生成所需的上下文,而不是直接从数据源检索。
1 任务适应模块:专注于转换RAG以适应各种下游任务。

例如,UPRISE自动从预构建的数据池中检索给定零样本任务输入的提示,增强跨任务和模型的通用性。

3.3.2 新模式

模块化RAG的组织方法具有灵活性,允许根据具体问题上下文替换或重新配置RAG过程中的模块。

(1)添加或替换模块
1 模块添加或替换策略:维持检索-阅读的结构,同时引入额外的模块来增强特定功能。

例如,RRR[Ma et al., 2023a] 提出了重写-检索-阅读过程,使用LLM性能作为强化学习中重写器模块的奖励。这允许重写器调整检索查询,提高阅读器的下游任务性能。

类似地,可以在Generate-Read[Yu et al., 2022]方法中选择性地替换模块,其中LLM生成模块替换了检索模块。Recite-Read [Sun et al., 2022] 将外部检索转换为从模型权重中检索,让LLM先记住任务相关信息,再生成输出,以处理知识密集型自然语言处理任务。

(2)调整模块间流程
1 模块间流程调整:强调增强语言模型与检索模型之间的互动

DSP[Khattab et al., 2022] 引入了展示-搜索-预测框架,将上下文学习系统视为显式程序而不是终端任务提示,以解决知识密集型任务。

ITER-RETGEN [Shao et al., 2023] 利用生成内容指导检索,迭代执行“检索增强生成”和“生成增强检索”,形成检索-阅读-检索-阅读的流程。

Self-RAG[Asai et al., 2023b] 遵循决定-检索-反思-阅读过程,引入了一个用于主动判断的模块。这种自适应和多样化的方法允许在模块化RAG框架内动态组织模块。

1.4

Retriever 检索器

在RAG(检索增强生成)框架中,"R"代表检索。

在RAG管道中的作用是:从庞大的知识库中检索出最相关的前k个文档。

1.4.1 构建准确的语义空间的办法

(1)块优化
1 在处理外部文档时,第一步是进行分块,以获得细粒度特征,然后将这些块进行嵌入。但嵌入过大或过小的文本块可能无法获得好的结果。因此,找到语料库中文档的最佳块大小对于确保搜索结果的准确性和相关性至关重要。
1 在选择分块策略时,需要考虑的因素包括:被索引内容的特点、所使用的嵌入模型及其最佳块大小、用户查询的预期长度和复杂度,以及特定应用中检索结果的使用方式。

(2)微调嵌入模型
1 获取适当大小的块之后,我们需要通过嵌入模型将块和查询嵌入到语义空间中。优秀的嵌入模型如UAE、Voyage、BGE等已经在大规模语料库上进行了预训练,但在特定领域中可能无法准确表示领域特定的语料库信息。
1 针对特定任务的嵌入模型微调对于确保模型理解用户查询与内容相关性至关重要。微调的嵌入模型对于下游应用是必不可少的。
1 领域知识微调:为了使嵌入模型正确理解领域特定信息,我们需要构建领域特定数据集来微调嵌入模型。
1 下游任务的微调:调整嵌入模型以适应下游任务同样重要。当在下游任务中使用RAG时,一些工作通过利用LLMs的能力对嵌入模型进行了微调。

1.4.2 如何匹配查询和文档的语义空间

(1)查询重写
1 将查询和文档的语义对齐最直观的方式是重写查询。

如Query2Doc[Wang et al., 2023b]和ITER-RETGEN[Shao et al., 2023]所提到的,利用大型语言模型的内在能力生成伪文档,并将原始查询与这个伪文档合并形成新的查询。在HyDE[Gao et al., 2022]中,通过使用文本指示符建立查询向量,使用这些指示符生成一个相关但可能并不存在的“假设”文档,它只需要捕获相关模式。RRR[Ma et al., 2023a]引入了一种新框架,将检索和阅读的顺序颠倒,专注于查询重写。此方法使用大型语言模型生成查询,然后使用网络搜索引擎检索上下文,最后使用小型语言模型作为训练重写器服务于冻结的大型语言模型。STEP-BACKPROMPTING[Zheng et al., 2023]方法可以使大型语言模型进行抽象推理,提取高层次概念和原则,并基于此进行检索。最后,Multi Query Retrieval方法涉及使用大型语言模型生成多个搜索查询,这些查询可以并行执行,检索结果一起输入,这对于依赖多个子问题的单一问题非常有用。

(2)嵌入变换
1 重写查询是一种粗粒度方法,而嵌入变换操作是一种更细粒度实现办法。

在LlamaIndex[Liu, 2023]中,可以在查询编码器后连接一个适配器,并微调适配器以优化查询嵌入的表示,将其映射到更适合特定任务的潜在空间。当查询和外部文档的数据结构不同时,如非结构化查询和结构化外部文档,使查询与文档对齐非常重要。SANTA[Li et al., 2023d]提出了两种预训练方法,使检索器意识到结构化信息:1) 使用结构化数据和非结构化数据之间的自然对齐关系进行对比学习,以进行结构化意识的预训练。2) Masked Entity Prediction,设计了一种以实体为中心的遮蔽策略,并要求语言模型填充被遮蔽的实体。

1.4.3 如何使检索器的输出与LLM的偏好一致

(1)LLM监督训练
1 AAR模型:利用编码器-解码器架构的LM为预训练检索器提供监督信号。该方法通过确定LM偏好的文档,利用FiD跨注意力得分进行微调检索器,最终提高了检索器在目标任务中的性能。
1 REPLUG模型:通过计算检索器和LLM计算检索到的文档的概率分布,然后通过计算KL散度进行监督训练。这一简单而有效的训练方法利用LM作为监督信号,无需特定的跨注意力机制,从而提升了检索模型的性能。

(2)插入适配器
1 PRCA模型:通过训练适配器,根据基于token的自回归策略优化检索器的输出。此方法适用于在微调嵌入模型方面存在挑战性的情况,如使用API实现嵌入功能或本地计算资源不足。
1 TokenFiltering方法:通过计算跨注意力得分,选择得分最高的输入token来过滤token,从而影响检索器的输出。
1 RECOMP模型:提出了抽取和生成压缩器,通过选择相关句子或合成文档信息生成摘要,实现多文档查询的重点摘要。
1 PKG模型:通过指令微调将知识注入白盒模型,直接替换检索器模块,以根据查询直接输出相关文档,从而实现与LLM偏好的一致性。

1.5

Generator 生成器

在RAG(Retrieval-Augmented Generation)模型中,生成器是关键组件之一,其主要任务是将从检索器获取的信息转化为自然流畅的文本。与传统的语言模型相比,RAG的生成器通过充分利用检索到的信息来提高生成文本的准确性和相关性。生成器的输入不仅包括传统的上下文信息,还包括通过检索器获取的相关文本段落。

1.5.1 如何通过后检索处理增强检索结果?

尽管大型未调整的语言模型(如GPT-4)在检索文档知识方面具备强大的内部知识,但其面临上下文长度限制和对冗余信息的易受影响等固有问题。为解决这些问题,研究者们通过后检索处理努力提高检索结果的质量,该过程旨在对检索器获得的文档进行进一步处理、过滤或优化,以更好地满足用户需求或后续任务的要求。

(1)信息压缩
1 针对处理从知识库检索获得的大量信息,现有的一些大模型语言尝试调整上下文长度来解决,但事实上当前的大模型依然面临着上下文限制。因此,在某些特定的情况下,信息压缩是很重要的,主要体现在减少噪声、应对上下文长度限制和增强生成效果等方面。

(2)重排
1 重排的作用是优化检索器检索到的文档集。LLM在增加额外上下文时性能会下降,而重排恰好解决这个问题。其核心思想是通过重新排列文档记录,将最相关的项目放在顶部,从而将文档总数减少到固定数量。这不仅解决了检索过程中可能遇到的上下文窗口扩展问题,还有助于提高检索效率和响应能力。

具体来说,ReRank的过程如下:
1 首先通过检索器(如BM25)对大规模文档进行检索,得到top-k个与query相关性较高的passages。这一步类似于传统检索的过程。
1 对每个检索到的passage,用一个seq2seq的cross-encoder模型(通常是微调过的预训练语言模型如BERT)对对进行打分。该模型会计算query和passage的相关性,考虑其上下文信息,从而得到一个匹配分数。,>
1 根据cross-encoder的打分对passages重新排序,分数最高的passage会被认为与query最相关,从而作为后续生成式QA模型的输入,用于生成最终答案。
1 (可选)为了在召回率和排序质量间做trade-off,还可对初始检索和重排序的结果进行插值,即把BM25和cross-encoder的分数进行加权平均,得到一个综合分数,据此选出最相关的passage。

1.5.2 如何优化生成器以适应输入数据?

在RAG模型中,生成器的优化是关键,其任务是将检索到的信息转换为相关文本以提供最终输出。与大型语言模型(LLM)的生成任务不同,RAG的输入包括查询和检索器检索到的各种文档。为适应这一多元化的输入,特别是对于较小的模型,微调生成器以适应查询和检索文档的输入变得至关重要。在这过程中,进行后检索处理以优化检索到的文档,然后采用微调方法来确保生成的文本既自然又有效地利用检索信息,以更好地满足用户查询需求。

(1)一般优化过程

指的是包含(输入,输出)对的训练数据,旨在训练模型在给定输入x的情况下生成输出y的能力。

(2)利用对比学习

图文对比学习方法主要是为了解决生成输入和输出之间的交互对导致的“暴露偏差”问题,旨在改善模型的训练,使其能够更好地适应不同场景,避免过度适应训练数据中的特定反馈。

(3)优化目标

在处理结构化数据的检索任务时,采用三阶段训练过程,以充分理解结构和语义信息。在检索器的训练阶段,通过对比学习优化查询和文档的嵌入表示,旨在提高模型对结构化数据的理解能力,从而有效地执行检索任务。

1.6

Augmentation in RAG

1.6.1 增强阶段

(1)预训练阶段

如何在预训练阶段使用检索方法来增强预训练语言模型(PTMs)在开放域问答(QA)中的性能?
1 REALM(Arora et al., 2023):
1 目标: 提出模块化、可解释的知识嵌入方法。
1 方法: 采用掩码语言模型(MLM)范式,将预训练和微调看作检索-然后-预测的过程,模拟P(x|y)。
1 RETRO(Borgeaud et al., 2022):
1 目标: 利用检索增强预训练自回归语言模型。
1 方法: 通过检索减少参数数量,在GPT模型基础上增加RETRO编码器和块状交叉注意层,在多方面性能上优于标准GPT模型。
1 Atla(Izacard et al., 2022):
1 目标: 使用T5架构,在预训练和微调引入检索机制。
1 方法: 利用预训练的T5初始化编码器-解码器LM骨架和Contriever初始化密集检索器。
1 COG(Vaze et al., 2021):
1 目标: 通过逐渐复制文本片段形式化生成过程。
1 方法: 使用向量搜索工具和索引计算文本片段的上下文表示,将文本生成任务分解为复制和粘贴操作。
1 RETRO++(Wang et al., 2023a):
1 目标: 探索大型模型是否能够使用RAG方法预训练。
1 特点: 在文本生成质量、事实准确性、低毒性和下游任务准确性方面取得一致改进,尤其在知识密集型任务中表现突出。

(2)微调阶段

微调阶段的增强方法具有多方面的特点。它们允许同时微调LLM和检索器,提供更好的适应性和灵活性。微调的好处扩展到适应多样化的下游任务,使得模型更为多功能。但这些方法也存在一些局限性,如需要专门准备的数据集以及较大的计算资源。微调阶段的定制性使研究者可以根据具体需求和数据格式调整模型,同时在资源消耗较低的情况下保留了对模型输出风格进行调整的能力。
1 REPLUG(Shi et al., 2023):
1 目标: 将语言模型(LM)视为黑盒,通过可调整的检索模型来增强它。
1 方法: 利用从LM获得的监督信号,改进初始检索模型,提高信息检索效果。
1 UPRISE(Cheng et al., 2023a):
1 目标: 通过在多样任务集上微调,创建轻量级、多功能的检索器。
1 特点: 检索器能为零样本任务提供检索提示,表现出普适性和任务与模型性能之间的改进。
1 微调生成器的方法:
1 Self-Mem(Cheng et al., 2023b): 通过内存池微调生成器。
1 Self-RAG(Asai et al., 2023b): 通过生成反射令牌满足主动检索需求。
1 RADIT(Lin et al., 2023): 通过最大化给定检索增强指令的正确答案的概率来微调生成器和检索器,更新生成器和检索器以最小化文档和查询之间的语义相似性。
1 SURGE(Kang et al., 2023):
1 目标: 引入对比学习的概念,端到端微调检索器和生成器。
1 方法: 使用基于图神经网络(GNN)的上下文感知子图检索器,从正在进行的对话相关的知识图中提取相关知识。

(3)推理阶段

在推理阶段,将检索-生成增强(RAG)方法与大型语言模型(LLM)结合成为了一个流行的研究方向。
1 Naive RAG:
1 特点:在推理阶段整合检索内容。
1 DSP(Khattab et al., 2022):
1 目标:在RAG中引入更丰富的上下文。
1 方法:通过传递自然语言文本在语言模型(LM)和检索模型(RM)之间实现复杂的流程,提供更有信息的上下文,增强生成质量。
1 PKG :
1 目标:为LLMs配备一个知识引导模块,允许访问相关知识而不改变LLMs的参数。
1 优点:使模型能执行更复杂的任务。
1 CREA-ICL(Li et al., 2023b):
1 方法:利用同步检索跨语言知识来帮助获取额外信息。
1 RECITE :
1 方法:通过从LLMs中抽取一个或多个段落来形成上下文。
1 ITRG(Feng et al., 2023a):
1 目标:增强对需要多步推理的任务的适应性。
1 方法:通过迭代检索和搜索正确的推理路径来实现。
1 ITERRETGEN(Shao et al., 2023):
1 方法:采用迭代方法来整合检索和生成,实现“检索增强生成”和“生成增强检索”的交替过程。
1 IRCOT(Trivedi et al., 2022):
1 方法:融合RAG和CoT(Wei et al., 2022)的概念,使用交替的CoT引导检索并使用检索结果来改善CoT。
1 优点:显著提高了GPT-3在各种QA任务上的性能。

1.6.2 数据源增强

数据源是RAG(检索-生成增强)方法有效性的关键因素。不同的数据源提供了不同的知识粒度和维度,需要不同的处理方法。

(1)非结构化数据的增强

非结构化数据主要包括文本数据,通常来自纯文本语料库,如提示数据和跨语言数据。
1 文本粒度方面,检索单元可以是词汇、短语或文档段落,选择更细粒度的检索单元可能提高处理罕见模式的能力。
1 在词汇层面,FLARE采用主动检索策略,仅在LM生成低概率词汇时进行检索。通过生成临时的下一句话以检索相关文档,然后生成下一句话来预测后续句子。
1 在块层面,RETRO使用前一个块来检索最近邻的块,并将此信息与前一个块的上下文信息整合,以指导下一个块的生成。

(2)结构化数据的增强

结构化数据源如知识图谱(KG)提供更高质量的上下文,降低模型幻觉的可能性。
1 RET-LLM [Modarressi et al., 2023] 建个性化知识图谱记忆。
1 SUGRE[Kang et al., 2023] 使用图神经网络(GNN)嵌入从知识图谱中检索的相关子图,防止模型生成上下文不相关的回复。
1 KnowledgeGPT[Wang et al., 2023c] 以代码格式生成知识库(KB)的搜索查询,并包含预定义的KB操作函数。

(3)LLM生成内容的RAG
1 SKR使用标记的训练集将问题分类为已知和未知,只对未知问题应用检索增强。
1 GenRead将LLM生成器替换为检索器,利用生成文档级上下文的一致性提高性能。
1 Selfmem迭代使用检索增强生成器来创建一个无界的内存池。使用内存选择器选择输出作为后续生成的内存。

1.6.3 过程增强

(1)迭代检索
1 多次迭代检索中提供额外参考资料,提高了后续答案生成的鲁棒性,但可能导致语义不连贯和噪声。
1 递归检索和多跳检索用于层次结构丰富的文档或图结构数据的场景。

(2)自适应检索
1 自适应检索方法(如Flare和Self-RAG)优化RAG检索过程,使LLM能够主动判断检索的时机和内容,提高检索信息的效率和相关性。
1 自适应检索允许LLM在需要时主动判断搜索查询,避免不必要的搜索,类似于代理的主动工具调用。

1.7

RAG Evaluation

在探索检索-生成增强(RAG)的发展和优化中,有效评估其性能成为一个核心问题。

1.7.1 评估办法

(1)独立评估

独立评估涉及对检索模块和生成模块(即阅读和合成信息)的评估。
1 检索模块:
1 使用度量系统(如搜索引擎、推荐系统或信息检索系统)按照查询或任务对项目排名的有效性的指标来评估RAG检索模块的性能。例如,命中率、MRR、NDCG、精度等。
1 生成模块:
1 通过将检索到的文档补充到查询中形成的增强或合成输入,与通常在端到端评估中评估的最终答案/响应生成不同。生成模块的评估指标主要关注上下文相关性,衡量检索文档与查询问题的相关性。

(2)端到端的评估

端到端评估是对 RAG 模型对特定输入生成的最终响应进行评估,涉及模型生成的答案与输入查询的相关性和一致性。

从内容生成目标的角度来看,评估可以分为无标签内容和有标签内容:
1 无标签内容评估指标包括答案的忠实度、相关性、无害性等;
1 有标签内容评估指标包括准确度和EM。

1.7.2 关键指标和能力

现有的研究缺乏对检索增强生成(RAG)对不同大型语言模型(LLMs)影响的严格评估。而在大多数情况下,对RAG在不同下游任务中的应用以及与不同检索器的结合可能产生不同的结果。

(1) 关键指标
1 忠实度:
1 确保生成的答案与上下文信息一致,不偏离或矛盾,防止幻觉问题。
1 答案相关性:
1 生成的答案需要与提出的问题直接相关。
1 上下文回忆:
1 衡量模型检索全部相关信息的能力。
1 上下文相关性:
1 要求检索到的上下文信息尽可能准确和针对性强,避免无关内容。

(2)关键能力
1 噪声鲁棒性:
1 评估处理噪声文档的效率。
1 负面拒绝:
1 测试模型正确地拒绝无效文档的能力。
1 信息整合:
1 评估模型整合多个文档信息回答更复杂的问题。
1 反事实鲁棒性:
1 测试模型在接收到错误信息的处理能力。

1.7.3 评估框架

(1)RAGAS
1 考虑检索系统、LLM使用和生成本身的能力,使用简单手写提示进行评估。
1 核心评估指标包括答案忠实度、答案相关性和上下文相关性。

https://github.com/explodinggradients/ragas.git

算法原理
1 答案忠实度:使用LLM将答案分解为单独的陈述,并验证每个陈述是否与上下文一致。最终,通过将支持的陈述数量与总陈述数量进行比较来计算“忠实度分数”。
1 答案相关性:使用LLM生成潜在问题,并计算这些问题与原始问题之间的相似度。“答案相关性得分”通过计算所有生成问题与原始问题的平均相似度而得出。
1 上下文相关性:使用LLM提取与问题直接相关的句子,并使用这些句子与上下文中总句子数量的比例作为“上下文相关性得分”。

(2)ARES
1 自动评估RAG系统的上下文相关性、答案忠实度和答案相关性。
1 使用少量手动注释数据和合成数据,利用PDR提供统计置信区间。
1 ARES性能低于RAGAS,但提供了适应新RAG评估设置的可能性。

https://github.com/stanford-futuredata/ARES.git

算法原理
1 生成合成数据集:ARES最初使用语言模型从目标语料库中的文档生成合成问题和答案,以创建正面和负面样本。
1 准备LLM评判:ARES使用合成数据集微调轻量级语言模型,训练它们评估上下文相关性、答案忠实度和答案相关性。
1 使用置信区间排名RAG系统:ARES应用这些评判模型对RAG系统进行评分,并将它们与手动注释的验证集结合使用PPI方法生成置信区间,可靠地估计RAG系统的性能。

1.8

未来展望

1.8.1 RAG的垂直优化

1 长上下文问题:
1 需要进一步研究如何扩展LLMs的上下文窗口,以适应更长的上下文,解决信息丢失和幻觉问题。
1 RAG的鲁棒性:
1 研究者关注提高RAG的鲁棒性,应对检索过程中的无关噪声和与事实相矛盾的情况。
1 RAG与微调的协同:
1 如何协调RAG与微调的关系,充分利用参数化和非参数化的优势,是一个需要解决的问题。
1 RAG的工程实践:
1 在工程实践中,如何提高大规模知识库场景中的检索效率和文档回调率,以及如何确保企业数据安全(例如防止LLMs泄露文档的来源、元数据或其他信息)是需要解决的关键问题。

1.8.2 水平扩展的RAG

1 图像领域:
1 BLIP-2提出使用冻结的图像编码器和大型语言模型进行视觉语言预训练,降低了模型训练成本。
1 代码领域:
1 RBPS用于与代码相关的小规模学习。通过编码或频率分析,自动检索与开发者任务类似的代码示例。
1 结构化知识领域:
1 方法如CoK首先从知识图谱中检索与输入问题相关的事实,然后以提示的形式将这些事实添加到输入中,表现良好。
1 音频和视频领域:
1 GSS方法检索并串联来自口语词汇库的音频片段,立即将MT(机器翻译)数据转换为ST(语音翻译)数据。UEOP在端到端自动语音识别中引入了新的突破,通过引入外部离线策略进行声音到文本的映射。Vid2Seq架构通过引入特殊的时间标记,使语言模型能够在同一输出序列中无缝预测事件边界和文本描述。

1.8.3 RAG 生态

(1)下游任务与评估
1 RAG在各种下游任务中表现良好,包括开放式问题回答和事实验证。未来工作将探索RAG在专业领域知识问答等应用中的适应性。
1 改进RAG的评估体系,包括更准确的评估指标和框架,以提高模型在不同下游任务中的效率和效益。
1 提高RAG模型的可解释性,使用户更好地理解模型的响应机制。

(2)技术栈
1 RAG相关技术栈的发展与RAG相互增强,LangChain、LLamaIndex等成为知名RAG API提供者。
1 新兴技术栈如Flowise AI、HayStack、Meltno和Cohere Coral等提供不同特性,推动整个RAG工具链的发展。
1 传统软件和云服务提供商也扩展了服务范围,例如Weaviate的Verba和亚马逊的Kendra。
1 技术栈的不断发展对RAG技术的推动和应用起到了积极作用。

1.9

Conclusion

全面探讨了RAG技术,强调其融合了LLMs参数化知识和外部知识的特点,解决了幻觉问题,提高了响应的准确性和透明度。而未来工作需要在RAG的垂直优化、水平扩展以及RAG生态系统的发展方向上进行更深入的研究。对未来RAG技术的发展方向进行了全面的探讨,从垂直领域的优化到技术栈的发展,为RAG领域的研究和应用提供了重要的参考。如果以AI应用的视角来看,将来RAG也必然会Agent化,Retriever不过是Agent的工具之一。其次,将来的RAG应用也应该是一个端到端可训练迭代的应用,人为介入的方法越多,这种方法也有可能会被更强的模型能力来取代。

  1. RAG应用初始步骤:

要提取PDF文档的内容,并创建一个让用户可以与PDF交流的完整的RAG(Retrieval-Augmented Generation)应用,需要遵循以下步骤:

2.1 PDF文档内容提取

1 工具选择: 使用像Python中的 PyPDF2 或 PDFMiner 这样的库来提取PDF文件的文本内容。
1 提取过程:
1 读取PDF文件。
1 遍历每一页,提取文本。
1 清理和预处理文本(如去除空白、特殊字符等)。

2.2 构建RAG系统

1 理解RAG: RAG结合了检索(Retrieval)和生成(Generation)模型,用于提供基于文档内容的动态回答。
1 实现步骤:
1 文档数据库: 将提取的PDF文本存储在一个可以进行搜索的数据库中,例如Elasticsearch。
1 检索模型: 实现一个检索模型,当用户提出问题时,它能从数据库中检索相关的文本段落。
1 生成模型: 使用像GPT-3或GPT-4这样的语言生成模型来根据检索到的内容生成回答。
1 集成: 将检索和生成模型集成到一个应用中,以便用户可以直接与之交互。

2.3 用户界面

1 开发一个简单的用户界面,允许用户输入问题并接收回答。
1 可以使用Web框架(如Flask或Django)构建界面。

2.4 测试和优化

1 对系统进行彻底测试,确保它能准确地检索信息并生成有意义的回答。
1 根据用户反馈进行优化。

2.5 注意事项

1 性能: 根据PDF的大小和复杂性,文本提取可能需要不同的处理。
1 数据隐私: 确保遵守数据处理和隐私保护的相关法律规定。
1 资源需求: RAG系统可能需要大量的计算资源,特别是生成模型部分

2.6 代码

Python %pip install pdfplumber from elasticsearch import Elasticsearch import pdfplumber import openai # Elasticsearch连接 es = Elasticsearch(["http://localhost:9200/"]) # 将PDF文档内容索引到Elasticsearch def index_document(file_path): with pdfplumber.open(file_path) as pdf: text = "n".join(page.extract_text() for page in pdf.pages if page.extract_text()) doc_id = file_path.split(‘/’)[-1] es.index(index="pdf_documents", id=doc_id, body={"content": text}) # 从Elasticsearch检索文档 def retrieve_documents(query, max_results=1): response = es.search(index="pdf_documents", query={"match": {"content": query}}, size=max_results) return [hit["_source"]["content"] for hit in response[‘hits’][‘hits’]] def truncate_content(content, max_length=500): return content if len(content) # 使用OpenAI生成答案 openai.api_key = "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" # 替换为你的API密钥 def generate_answer(user_query, documents): # 构建问题和文档的列表 inputs = [f"问题: {user_query}"] for doc in documents: inputs.append(f"文档: {doc}") # 确保整体prompt长度不超过模型限制 if len(inputs) > 4000: inputs = inputs[:4000] response = openai.Completion.create( engine="gpt-3.5-turbo", # 根据需要选择合适的模型 prompt=inputs, max_tokens=50, ) return response.choices[0].text.strip() # 索引PDF文件(仅首次运行时需要) index_document(r"C:UsersRangerDesktopRAG.pdf") # 示例查询 user_question = "RAG的定义是什么?" documents = retrieve_documents(user_question) # 检索与问题匹配的文档内容 answer = generate_answer(user_question,documents) print(answer)

Python InvalidRequestError : This is a chat model and not supported in the v1/completions endpoint. Did you mean to use v1/chat/completions? Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings… InvalidRequestError : This model’s maximum context length is 4097 tokens, however you requested 6982 tokens (6932 in your prompt; 50 for the completion). Please reduce your prompt; or completion length. Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings… APIRemovedInV1 : You tried to access openai.Completion, but this is no longer supported in openai>=1.0.0 – see the README at https://github.com/openai/openai-python for the API. … Alternatively, you can pin your installation to the old version, e.g. pip install openai==0.28 A detailed migration guide is available here: https://github.com/openai/openai-python/discussions/742 Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings…

文中部分内容来自网络

整理者:张新福

7