|
概述 检索增强生成(RAG)是一种通过结合外部知识来增强语言模型生成的技术。通常的做法是从大量文件语料库中检索相关信息,并利用这些信息为prompt。
目前LLM遇到的挑战
客户通常拥有大量的私有文件。 提取具体信息无异于大海捞针。 检索效率不高。 模型容易忘记上下文窗口内容。
RAG
RAG 实施方法如下: 优点:
RAG 流水线
此处的检索器可以是以下任何一种,具体取决于是否需要语义检索: 向量数据库:通常,使用 BERT 等模型嵌入查询,以生成密集向量嵌入。或者,TF-IDF 等传统方法可用于稀疏嵌入。然后根据术语频率或语义相似性进行搜索。 图形数据库:从文本中提取的实体关系中构建知识库。此方法很精确,但可能需要精确的查询匹配,这在某些应用程序中可能会受到限制。 常规 SQL 数据库:提供结构化数据存储和检索,但可能缺乏向量数据库的语义灵活性。
下面是使用图数据库与向量数据库进行 RAG 之间的区别。 
与向量数据库相比,图形数据库更适合用于检索增强生成(RAG)。虽然向量数据库使用 LLM 编码的向量对数据进行分区和索引,允许语义相似的向量检索,但它们可能会获取不相关的数据。另一方面,图形数据库从文本中提取的实体关系中构建知识库,使检索简洁明了。但是,它需要精确的查询匹配,这可能会受到限制。一种可能的解决方案是结合两种数据库的优势:在图数据库中用向量表示法对解析的实体关系进行索引,以实现更灵活的信息检索。这种混合模式是否存在还有待观察。检索后,您可能需要通过添加排序层和(或)精细排序层来进一步过滤筛选信息,这样您就可以过滤掉不符合您的业务规则、未针对用户、当前上下文或响应限制进行个性化设置筛选信息。 让我们简明扼要地总结一下 RAG 的过程,然后深入探讨其利弊: 创建向量数据库:RAG 首先会将内部数据集转换为向量,并将其存储到向量数据库中。 用户输入:用户以自然语言提出查询,寻求答案或完成查询。 信息检索:检索机制扫描向量数据库,找出与用户查询(也是嵌入式查询)语义相似的片段。然后将这些片段交给 LLM,以丰富其生成响应的上下文。 组合数据:将从数据库中选择的数据段与用户的初始查询结合起来,创建一个扩展prompt。 生成文本:然后将扩展prompt提供给 LLM,LLM 会制作最终的上下文感知响应。
下图显示了高级RAG的工作。 
LLM 的 RAG 和 Fine Tuning 之间的区别: 检索系统 (RAG) 使 LLM 系统能够访问事实、访问控制、及时的信息。微调不能做到这一点,所以他们不是竞争的关系。 Fine Tuning 也就是微调调整 LLM 的风格、语气和词汇,使你的语言与所需的领域和风格相匹配 总而言之,首先关注 RAG。成功的 LLM 应用程序必须将专有数据连接到 LLM 工作流。一旦您有了第一个完整的应用程序,您就可以添加微调以改进系统的样式和词汇。如果 RAG 与数据的连接构建不正确,微调也无法得到想要的效果。
向量数据库的选择: 
构建 RAG 流水线
下图直观地概述了 RAG 的三个不同步骤:数据提取、检索和合成/响应生成。 
在下面的部分中,我们将介绍这些关键步骤。 数据提取(Ingestion) 分块(Chunking) 分块是将要检索的提示和/或文档划分为更小的、可管理的段或块的过程。这些块可以通过固定大小来定义,例如特定数量的字符、句子或段落。 在RAG中,每个块都被编码到嵌入向量中以供检索。更小、更精确的块会导致用户查询与内容之间的更精细匹配,从而提高检索信息的准确性和相关性。 较大的块可能包含不相关的信息,从而引入噪声并可能降低检索准确性。通过控制块大小,RAG 可以在全面性和精确性之间保持平衡。 因此,下一个自然而然的问题是,如何为您的用例选择正确的块大小?RAG 中块大小的选择至关重要。它需要足够小,以确保相关性并减少噪音,但又要足够大,以保持上下文的完整性。让我们看一下下面引用的Pinecone的几个方法: text="..."#yourtextfromlangchain.text_splitterimportCharacterTextSplittertext_splitter=CharacterTextSplitter(separator="\n\n",chunk_size=256,chunk_overlap=20)docs=text_splitter.create_documents([text])
text="..."#Yourtextdocs=text.split(".")
text="..."#Yourtextfromlangchain.text_splitterimportSpacyTextSplittertext_splitter=SpacyTextSplitter()docs=text_splitter.split_text(text)
递归分块:递归分块是一种迭代方法,它使用各种分隔符分层拆分文本。它通过递归应用不同的条件来适应创建相似大小或结构的块。使用LangChain的示例: text="..."#Yourtextfromlangchain.text_splitterimportRecursiveCharacterTextSplittertext_splitter=RecursiveCharacterTextSplitter(chunk_size=256,chunk_overlap=20)docs=text_splitter.create_documents([text])
NLTK(自然语言工具包):用于语言处理的综合 Python 库。NLTK 包括一个句子分词器,可以有效地将文本拆分为句子。例:
text="..."#Yourtextfromlangchain.text_splitterimportNLTKTextSplittertext_splitter=NLTKTextSplitter()docs=text_splitter.split_text(text) 根据经验,如果没有上下文语境的文本块对人类有意义,那么对语言模型也有意义。因此,为语料库中的文档找到最佳块大小对于确保搜索结果的准确性和相关性至关重要。 嵌入(Embeddings) 一旦你的prompt被适当地分块,下一步就是嵌入它。在 RAG 中嵌入prompt和文档涉及将用户的查询(prompt)和知识库中的文档转换为可以有效比较相关性的格式。此过程对于 RAG 从其知识库中检索最相关信息以响应用户查询的能力至关重要。下面是它一般的工作原理: 可以通过HuggingFace 的大规模文本嵌入基准 (MTEB) 排行榜获取最适合的嵌入模型。有一个问题,即是否可以使用密集嵌入或稀疏嵌入,下面分析每种嵌入类型的特点: 检索 (Retrieval) 让我们看一下两种不同类型的检索:标准检索、句子窗口检索和自动合并检索。这些方法各有优缺点,它们的适用性取决于 RAG 任务的要求,包括数据集的性质、查询的复杂性,以及在响应中特异性和上下文理解之间所需的平衡。 优势: 简单高效:这种方法简单高效,嵌入和合成都使用相同的文本块,简化了检索过程。 数据处理的一致性:它能保持检索和合并阶段所用数据的一致性。
缺点:
有限的上下文理解:LLM 可能需要更大的综合窗口来产生更好的返回,而这种方法可能无法提供足够的综合窗口。 可能存在非最优回复:由于上下文有限,LLM可能没有足够的信息来生成最相关、最准确的回复。
提高检索的针对性:通过将文档分解成更小的单元,可以更精确地检索与查询直接相关的片段。 丰富的语境合成:它围绕检索到的语块重新引入语境进行综合,为 LLM 提供了更广泛的理解,以制定应对措施。 平衡法:这种方法在重点检索和丰富语境之间取得了平衡,有可能提高答复质量。
缺点: 复杂性增加:管理检索和合成的不同流程会增加pipeline的复杂性。 潜在的背景空白:如果补充的周边信息不够全面,就有可能遗漏更广泛的背景。
想法:如果我们能同时尝试多种块大小,并让重新排序器对结果进行修剪,会怎么样? 这样做有两个目的: 流程如下: 以多种不同的方式对同一文档进行分块,例如分块大小为 128、256、512 和 1024。 在检索过程中,我们从每个检索器中获取相关的数据块,从而将它们组合在一起进行检索。 使用重新排序器对结果进行排序/修剪。
下图描述了这一过程。 
重新排名
词法重排:这包括根据查询和检索文档之间的词法相似性重新排序。常见的方法有 BM25 或带有 TF-IDF 向量的余弦相似性。 语义重新排序:这类重新排序使用语义理解来判断文档的相关性。它通常涉及神经模型,如 BERT 或其他基于转换器的模型,以理解上下文和意义,而不仅仅是单词重叠。 学习排名(LTR)方法:这种方法是根据从查询和文档中提取的特征,专门为文档排序任务(点排序、对排序和列表排序)训练一个模型。这可能包括词法、语义和其他特征的混合。 混合方法:这些方法结合了词法和语义法,可能还有用户反馈或特定领域特征等其他信号,以改进重新排序。 神经 LTR 方法在这一阶段最常用,因为候选集仅限于几十个样本。用于重新排序的一些常用神经模型包括 使用 BERT 进行多级文件排序(monoBERT 和 duo BERT) RAG 中的重新排序是指根据检索到的文档或信息片段与给定查询或任务的相关性对其进行评估和排序的过程。 RAG 中使用了不同类型的重新排序技术:
生成回复
RAG pipeline的最后一步是生成反馈给用户的回复。在这一步中,模型将检索到的信息与其预先训练的知识进行综合,以生成连贯且与上下文相关的回复。这一过程包括整合从各种来源收集到的见解,确保准确性和相关性,并制作出不仅信息丰富,而且与用户的原始查询相一致的回复,同时保持自然的对话语气。 需要注意的是,在为 LLM 生成有根据的响应创建扩展prompt(包含检索到的 top-k 块)的同时,在输入序列的开头或结尾处战略性地放置重要信息可以提高 RAG 系统的有效性,从而使系统更加高效。
结论
本文详细介绍了RAG(检索增强生成)的基本概念、工作流程和关键领域,包括数据提取、嵌入、检索和响应生成/合成。文章还探讨了各种检索和重新排序技术,以及如何有效地生成用户反馈。此外,文章还分析了语言模型如何使用长语境。 此外,文章也强调了在处理长文本时,模型的性能可能会受到影响,尤其是当相关信息位于文本的中部时。因此,文章建议在输入序列的开头或结尾处战略性地放置重要信息,以提高RAG系统的有效性。同时,通过改进检索和提示创建步骤,如使用排序阶段,可以将性能提高20%。这些见解对于理解和优化RAG的应用具有重要价值。 |