LLM 与 RAG 的发展(综述分析)| 豆包 MarsCode AI 刷题

128 阅读17分钟

更新日期 2024.11.07(后续会随着 RAG 发展保持更新)

参考论文:

  1. 综述论文:arxiv.org/abs/2312.10…

参考文章:

  1. juejin.cn/post/740734…
  2. juejin.cn/post/740733…

名词解释

  • RAG:Retrieval-Augmented Generation,检索增强生成,是通过整合外部数据库的知识,将 LLMs 的内在知识与外部数据库的巨大动态存储库协同合并,比如信息会被编织到 LLM 的提示中,为生成过程提供额外的上下文,来解决诸如幻觉、过时的知识以及不透明、不可追踪的推理过程等挑战。

RAG 就是可以开卷回复的 LLM !!!

  • 优势:添加外部知识库,丰富输入,而无需针对特定任务的应用程序重新训练 LLMs

  • 发展

    1. Transformer 提出阶段(2017):RAG 用于预训练模型吸收额外的知识来增强语言模型,主要针对优化预训练方法
    2. ChatGPT 提出阶段:RAG 的大部分工作集中在推理上,少数致力于微调过程
    3. GPT-4 提出阶段:混合方法,结合了 RAG 和微调的优势,同时研究优化预训练

  • “幻觉” :指的是模型生成的信息与事实不符,或者完全虚构的信息。这种现象通常发生在模型生成的文本中,看似合理、连贯,却缺乏真实的依据或数据支持。

    • 主要表现形式:错误的事实、捏造信息、逻辑不一致
    • 成因:训练数据偏差(包含不准确不完整数据)、模型推理机制(没有真正理解)、外部知识不足(知识库并非实时更新,可能在某些领域中存在过时的信息)
  • 暴露偏差:模型仅针对单独的正确输出示例进行训练,从而限制了其对一系列可能的输出引用序列的暴露,可能会导致模型过度拟合训练集中的特定示例,从而降低其在各种上下文中泛化的能力,从而阻碍模型的实际性能

应用于问答的 RAG 流程的代表性实例

image.png 用户向 ChatGPT 询问最近发生的备受瞩目的事件(即 OpenAI 首席执行官的突然解雇和复职),该事件引起了相当多的公众讨论。 ChatGPT 作为最著名和广泛使用的LLM,受其预训练数据的限制,缺乏对最近事件的了解。 RAG 通过从外部知识库检索最新文档摘录来弥补这一差距。在这种情况下,它会获取与调查相关的精选新闻文章。然后,这些文章与最初的问题一起合并为丰富的提示,使 ChatGPT 能够综合明智的响应。

RAG 核心考虑因素

  1. 检索内容:研究重点是检索的粒度和数据结构化的水平

    • 粗粒度带来更多信息,但精度较低
    • 检索结构化文本可提供更多信息,但会牺牲效率
  2. 何时检索:从单一到自适应和多重检索的策略方法

    • 检索频率越高,信息量越多,效率就越低
  3. 如何使用检索到的数据:在模型架构的各个级别上开发了集成技术,包括输入层、中间层和输出层

RAG 关键步骤

  1. 将语料库划分为离散块,然后利用编码器模型构建向量索引 2. RAG 根据块与查询和索引块的向量相似性来识别和检索块 3. 模型根据从检索到的块中收集的上下文信息合成一个响应

RAG 三方基础

检索、生成和增强技术

索引(Indexing)

索引创建过程是数据准备过程中至关重要的初始步骤,是离线进行的。

核心步骤:

  1. 从数据索引开始,清理和提取原始数据,并将 PDF、HTML、Word 和 Markdown 等各种文件格式转换为标准化纯文本
  2. 通过分块被分割成更小、更易于管理的块
  3. 通过 embedding 模型转换为向量表示(推理效率和模型大小之间的平衡)-> 利于检索阶段的相似性比较
  4. 最后,创建一个索引来将这些文本块及其向量 embeddings 为键值对,从而实现高效且可扩展的搜索功能

检索(Retrieve)

  1. 收到用户查询后,该系统采用与索引阶段相同的 embedding 模型将输入转码为向量表示。
  2. 继续计算查询向量与索引语料库中的向量化块之间的相似性分数。
  3. 系统优先考虑并检索与查询最相似的前 K 个块。
  4. 检索到的块随后被用作解决用户请求的扩展上下文基础。

生成(Generation)

  1. 提出的查询和选定的文档块被合成一个新的提示信息,

  2. 大型语言模型的任务根据这个提示信息做出响应。

    • 模型的回答方法可能会根据特定任务的标准而有所不同,从而允许它利用其固有的参数知识或限制其对所提供文档中包含的信息的响应
    • 在持续对话的情况下,任何现有的对话历史都可以集成到提示中,使模型能够有效地进行多轮对话交互

RAG vs Fine-Tuning vs Prompt Engineering

RAGFine-TuningPrompt Engineering
本质根据自身知识并利用外部知识库提供的实时知识依赖 “再次学习” 形成更多自身 “内部专业知识”利用模型已有的内在能力
比喻学生根据目前掌握的知识并带着大量资料参加“开卷考试”学生通过学习更多的资料,随着时间的推移内化新知识学生目前掌握的知识
环境动态静态静态
优点实时性和适应性,可以利用实时的知识更新和高可解释性的外部知识源,适应不同动态的环境和需求允许对模型的行为和风格进行深度定制稳定
缺点更高的延迟和数据检索的道德考虑 出现幻觉可能性更大大量的计算资源来准备和训练数据集大量的计算资源来准备和训练数据集

RAG 范式

朴素 RAG、高级 RAG 和模块化 RAG >

朴素 RAG(Native RAG)

Naive RAG 研究范式代表了最早的方法,在 ChatGPT 广泛采用后不久就得到了重视。 Naive RAG 遵循传统流程,包括索引、检索和生成

  • “检索-读取”框架

缺点

  • 检索质量

    • 精度低:检索到的文档不一定都和查询相关
    • 低召回率:未能检索到所有相关的文档块
    • 过时的信息
  • 响应生成质量

    • 模型缺乏足够上下文的情况下虚构答案
    • 生成的答案和提供的上下文不相关
    • 生成有害或者有偏见的响应
  • 增强过程:  如何有效地将检索到的段落中的上下文与当前生成任务整合??

    • 脱节或不连贯的输出
    • 冗余和重复:多个检索到的段落包含相似信息
    • 难以平衡每个段落价值:多个检索到的段落对生成任务的重要性和相关性不一致
    • 难以协调写作风格和语气的差异
    • 存在模型存在过度依赖增强信息的风险:输出仅仅重复检索到的内容,而不提供新的价值或综合信息

高级 RAG(Advance RAG)

高级 RAG 出现的目的旨在解决基础 RAG 的缺点。在检索质量方面,高级 RAG 实施检索前和检索后策略。为了解决基础 RAG 遇到的索引挑战,高级 RAG 使用滑动窗口、细粒度分段和元数据等技术改进了其索引方法。它还引入了各种方法来优化检索过程。

优化一 —— 预检索(Pre-Retrieval)

优化数据索引,提高索引内容的质量

  • 增强数据粒度

    • method:包括删除不相关的信息、消除实体和术语中的歧义、确认事实的准确性、维护上下文以及更新过时的文档。
    • improvement:文本标准化、一致性、事实准确性和丰富的上下文,以提高 RAG 系统的性能
  • 优化索引结构

    • 调整块的大小 --> 捕获相关上下文
    • 跨多个索引路径进行查询以及合并来自图结构的信息 --> 通过利用图数据索引中的节点之间的关系来捕获相关上下文
  • 添加元数据信息

    • 引用的元数据(例如日期和目的)集成到块中 --> 过滤
    • 合并引用的章节和小节等元数据 --> 提高检索效率。
  • 对齐优化:通过在文档中引入“假设问题”,即创建适合每篇文档适合回答的问题,并将这些问题和文档结合起来。

优化二 —— 检索过程优化(Retrieval)

重点是优化 embedding 模型的能力

  • Fine-tunning Embedding:定制 embedding 模型以增强特定领域上下文中的检索相关性,特别是对于处理不断发展或罕见术语的专业领域。

eg. BAAI 开发的 BGE-large-EN,是高性能嵌入模型的一个例子,可以通过微调来优化检索相关性。可以使用 GPT-3.5-turbo 等语言模型生成用于微调的训练数据,以制定基于文档块的问题,然后将其用作微调对。

  • Dynamic Embedding根据单词使用的上下文进行调整,为每个单词提供不同的向量表示

eg. BERT 这样的 Transformer 模型中,同一个单词可以根据周围的单词有不同的向量表示。 OpenAI 的 embeddings-ada-02 模型基于大语言模型(如 GPT)原理开发的,是一种复杂的动态嵌入模型,可以捕获上下文理解。然而,可能还是不如最新的大语言模型(如GPT-4)那样对上下文敏感。

优化三 —— 检索后(Post-Retrieval)

一次性向 LLM 输入所有相关文档可能会超出上下文窗口限制、引入噪音并妨碍对关键信息的关注。为了解决这些问题,需要对检索到的内容进行额外处理

  • 重排(ReRank) :重新排列检索到的信息以将最相关的内容重新定位到提示的边缘

eg. DiversityRanker 根据文档多样性确定重新排序的优先级,而 LostInTheMiddleRanker 交替将最佳文档放置在上下文窗口的开头和结尾。cohereAI rerank、bge-rerank 和 LongLLMLingua 等方法会重新计算相关文本和查询之间的语义相似度,解决了基于向量的语义相似度模拟搜索的挑战

注:该方法已在 LlamaIndex、LangChain 和 HayStack 等框架中实现

  • 信息压缩:压缩无关上下文、突出关键段落、减少整体上下文长度

eg. Selective Context 和 LLMLingua 等方法利用小语言模型来计算提示之间的相互信息或困惑度,估计元素重要性。 Recomp 通过以不同粒度训练压缩器来解决这个问题,而 Long Context 和“Walking in the Memory Maze” 设计总结技术来增强LLM 的关键信息感知,特别是在处理广泛的上下文时。

模块化 RAG(Module RAG)

集成了各种方法来增强功能模块,提供了更大的通用性和灵活性。重构的 RAG 模块和迭代方法已经被开发来解决特定问题。其同时允许跨多个模块的序列化管道或端到端训练方法。

本质上,基础 RAG 和高级 RAG 都可以被认为是由一些固定的模块组成。基础 RAG 主要由“检索”和“读取”模块组成。高级 RAG 的典型模式通过添加“重写”和“重新排序”模块建立在基础 RAG 的基础上。但总体而言,模块化 RAG 具有更大的多样性和灵活性。

变革一 —— 新模块

搜索、内存、融合、路由、预测、任务适配器

  • 搜索模块(Search) :与 基础/高级 RAG 中的相似性检索相比,搜索模块针对特定场景量身定制,并结合了对其他语料库的直接搜索

    • 使用 LLM 生成的代码、SQL 或 Cypher 等查询语言以及其他自定义工具来实现。
    • 搜索的数据源可以包括搜索引擎、文本数据、表格数据和知识图。
  • 内存模块(Memory) :利用 LLM 的内存功能来指导检索,涉及识别与当前输入最相似的记忆

    • Selfmem 利用检索增强生成器迭代创建无界内存池,结合“原始问题”和“双重问题”
    • 通过采用检索增强生成模型,该模型使用自己的输出来改进自身,文本在推理过程中变得更加符合数据分布,而不仅依赖训练数据。
  • 融合(Fusion):通过多查询方法,使用 LLM 将用户查询扩展到多个不同的视角

    • 涉及原始查询和扩展查询的并行向量搜索、智能重新排序以优化结果,以及将最佳结果与新查询配对。
    • 可确保搜索结果与用户的显式和隐式意图紧密结合,从而发现更有洞察力和相关性的信息。
  • 路由(Routing):RAG 系统的检索过程利用不同领域、语言和格式的不同来源,可以根据情况进行替换或合并,可以通过查询路由决定用户查询的后续操作

    • 路由设置包括汇总、搜索特定数据库或将不同路径合并为单个响应。
    • 查询路由器还为查询选择适当的数据存储,其中可能包括各种源,例如向量存储、图形数据库或关系数据库,或索引层次结构,例如用于多文档存储的摘要索引和文档块向量索引
    • 查询路由器的决策是通过 LLMs 调用预定义和执行的,该调用将查询定向到所选索引。
  • 预测(Predict) :利用 LLM 生成必要的上下文(不是直接从数据源检索)

    • 与通过直接检索获得的内容相比,LLM 生成的内容更有可能包含相关信息
    • 解决了检索内容中冗余和噪音的常见问题
  • 任务适配器:侧重于使 RAG 适应各种下游任务。

eg. UPRISE 可自动从预先构建的数据池中检索零样本任务输入的提示,从而增强跨任务和模型的通用性。同时,PROMPTAGATOR 利用 LLM 作为少量查询生成器,并根据生成的数据创建特定于任务的检索器。通过利用 LLMs 的泛化能力,它可以使用最少的示例开发特定于任务的端到端检索器。

变革二 —— 新模式

主要探究 RAG 的新组织范式,目前主要包括涉及添加或替换模块和侧重于调整模块之间的组织流程两种,目的都是为了使得能够定制 RAG 流程以有效地解决各种任务

  • 添加或替换模块:涉及维护检索-读取过程的核心结构,同时集成附加模块以增强特定功能。

eg. RRR 引入了 Rewrite-RetrieveRead 过程,利用 LLM 性能作为重写模块的强化学习激励。这使得重写器能够微调检索查询,从而提高读取器的下游任务性能。类似地,模块可以在诸如 Generate-Read 之类的方法中选择性地交换,其中 LLM 的生成模块取代了检索模块。 Recite-Read 将外部检索转变为模型权重检索,要求 LLM 记住最初特定于任务的信息,然后生成能够处理知识密集型自然语言的输出处理任务。

  • 调整模块之间的流程:重点是增强语言模型和检索模型之间的交互

eg. DSP 引入了 DemonstrateSearch-Predict 框架,将上下文学习系统视为显式程序而不是最终任务提示,从而更有效地处理知识密集型任务。 ITER-RETGEN 方法利用生成的内容来指导检索,在检索-读取-检索-读取流程中迭代地实现“检索增强生成”和“生成增强检索”。该方法展示了一种使用一个模块的输出来改进另一个模块的功能的创新方法。

优化三 —— 管道优化

集成不同的搜索技术、细化检索步骤、结合认知回溯、实施多功能查询策略以及利用 embedding 相似性,共同努力在 RAG 系统中实现检索效率和上下文信息深度之间的平衡

  • 混合搜索探索:智能集成各种技术(包括基于关键字的搜索、语义搜索和向量搜索)来优化其性能。

  • 递归检索和查询引擎:

    1. 初始检索阶段获取较小的块以捕获关键语义。
    2. 在该过程的后期阶段,包含更多上下文信息的更大块被提供给 LLM
  • StepBack-prompt 方法:鼓励 LLM 摆脱特定实例并围绕更广泛的概念和原则进行推理

  • 子查询:根据场景的不同,可以采用各种查询策略

  • HyDE(Hypothetical Document Embeddings)

    • 基于假设:相较于直接查询,通过 LLM 生成的答案在 Embedding 空间中可能更为接近
    • 执行逻辑:使用 LLM,HyDE 创建一个假设文档(答案)来响应查询,Embedding 该文档,并使用生成的 Embedding 来检索与假设文档类似的真实文档
    • 设计原理:关注一个答案到另一个答案的 Embedding 相似性
    • 缺陷:可能不会始终产生理想的结果,特别是当语言模型不熟悉主题时,可能会导致更多错误实例

检索技术发展

从数据源中高效检索相关文档

三个核心问题

  1. 我们如何实现准确的语义表示
  2. 什么方法可以对齐查询和文档的语义空间?
  3. 检索器的输出如何与大语言模型的偏好保持一致

增强语言标识

及查询和文档的多维映射,解决 “如何实现准确的语义表示?” 问题

块优化

  • 原则:确定语料库中文档的最佳块大小对于确保检索结果的准确性和相关性至关重要

  • 考虑因素

    • 索引内容的性质
    • embedding 模型及其最佳块大小
    • 用户查询的预期长度和复杂性
    • 特定应用程序对检索结果的利用
  • 相关技术

    • 滑动窗口技术:通过跨多个检索过程合并全局相关信息来实现分层检索
    • “small2big”方法:在初始搜索阶段利用小文本块,然后向语言模型提供较大的相关文本块进行处理
    • 摘要嵌入技术:根据文档摘要优先考虑前 K 个检索,提供对整个文档上下文的全面理解
    • 元数据过滤技术:利用文档元数据来增强过滤过程
    • 图索引技术:将实体和关系转换为节点和连接,显著提高相关性,特别是在多跳问题的情况下