检索增强生成 (RAG) 流程正在彻底改变我们与大型语言模型 (LLM) 的交互方式。RAG 不再仅仅依赖这些模型中预先训练的知识,而是让 LLM 能够实时访问和利用外部知识源,从而产生更准确、更相关、更有根据的响应。然而,构建有效的 RAG 系统并不是一个即插即用的操作;它是一个经历复杂选择的过程。

检索增强生成 (RAG) 是一种创新方法,它将检索系统的优势与生成模型相结合,允许根据外部知识生成与上下文相关的响应。构建有效的 RAG 流水线涉及多个组件,每个组件都有自己的一组选项、优点和缺点。这篇文章解开了 RAG 流水线的核心组件,探索了它们的选项,并讨论了超参数的关键作用。

1. 数据加载器

数据加载器负责将来自各种来源的数据提取到 RAG 流水线中。以下是一些常见的选项:

DirectoryLoader:从指定目录加载文档。

  • 优点:使用简单;可以处理多种文件类型。
  • 缺点:对于不支持的格式可能需要额外的处理。
  • 示例:从文件夹加载所有 .txt 和 .pdf 文件。

PyPDFLoader:专门用于从 PDF 文件中提取文本。

  • 优点:能很好地处理复杂的 PDF 结构。
  • 缺点:仅限于 PDF 文件;处理扫描文档可能会比较困难。
  • 示例:加载 PDF 格式的科学论文。

WebBaseLoader:直接从网页获取内容。

  • 优点:访问实时信息;对于动态内容有用。
  • 缺点:依赖于互联网访问;可能会面临网络抓取限制问题。
  • 示例:从特定的网址收集信息。

CSVLoader:从 CSV 文件加载数据。

  • 优点:易于使用结构化数据;广泛支持的格式。
  • 缺点:仅限于表格数据;可能需要对复杂结构进行额外解析。
  • 示例:整合目录中的产品信息

2. 分割器

文本分割器将大型文档分解为易于管理的块,以便于处理。选项包括:

RecursiveCharacterTextSplitter:根据字符限制拆分文本,同时保持逻辑边界。

  • 优点:通过递归尝试不同的字符(例如换行符、空格)来分割文本。
  • 缺点:如果句子中间分裂,可能无法保留语义上下文。
  • 例如:将一本书分成段落和句子。

HTMLHeaderTextSplitter/HTMLSectionSplitter:根据标题或部分分割 HTML 文档。

  • 优点:通过按 HTML 标签拆分来保留文档结构。非常适合结构化 HTML 内容。
  • 缺点:不适合非 HTML 文本。
  • 示例:将博客文章分成有意义的部分。

CharacterTextSplitter:将文本分成指定字符长度的块。

  • 优点:简单、快速,按单个指定字符进行分割。
  • 缺点:不理解句子或段落的界限。
  • 示例:通过换行符分割代码。

TokenTextSplitter:根据标记计数拆分文本,对 NLP 任务很有用。

  • 优点:按标记数量拆分文本,对于具有标记限制的 LLM 来说更加一致。
  • 缺点:如果块大小太小,可能会在句子中间分裂。
  • 示例:为具有特定标记限制的模型准备文本

SpacyTextSplitter:利用 spaCy 的 NLP 功能智能地分割文本。

  • 优点:利用 SpaCy 的 NLP 功能将文本分成句子,同时保持语义理解。
  • 缺点:比简单的基于字符的拆分更慢。
  • 示例:以更高的精度处理自然语言文本。

SentenceTransformers:利用不同的 NLP 库根据句子或特定语言的规则进行拆分的各种方法。

  • 优点:设计用于与 SentenceTransformers 无缝协作,确保正确拆分标记以进行向量嵌入。
  • 缺点:需要安装 SentenceTransformers。
  • 示例:在使用 SentenceTransformers 嵌入文本之前对其进行拆分,以获得更好的矢量表示。

NLTKTextSplitter

  • 优点:使用 NLTK(自然语言工具包)执行句子或段落标记,提供更好的语义处理。缺点:需要安装 NLTK;实现起来可能更复杂。示例:拆分文本,同时确保每个块从自然语言角度来看都有意义。

KonlpyTextSplitter:

  • 优点:专为韩文文本设计,使用 Konlpy 的标记化功能实现更好的分块。
  • 缺点:仅适用于韩文。
  • 示例:有效处理韩语文档

3. 分块方法

分块是指将文本分成更小的片段。主要方法包括:

固定大小块:将文本分割成预定的长度。

  • 优点:简单、可预测。
  • 缺点:可能会切断重要内容。

基于句子和基于段落的方法:使用自然语言边界进行分块。

  • 优点:保留含义和上下文。
  • 缺点:可变的块大小会使处理复杂化。

语义分块:根据含义而不是大小对文本进行分段。

  • 优点:保持上下文完整性。
  • 缺点:实现起来比较复杂。

滑动窗口方法:创建重叠块以保留跨段的上下文。

  • 优点:确保信息的连续性。
  • 缺点:增加冗余和处理时间。

混合方法:结合多种方法以获得最佳结果。

  • 优点:结合多种分块技术,从而获得具有上下文的良好分块数据。
  • 缺点:实现起来复杂。

关键超参数:

  • chunk_size:每个块的字符或标记的数量。
  • chunk_overlap:连续块之间的重叠。
  • length_function:确定如何计算chunk的长度。
  • trade-offs:较大的块可以捕获更多上下文,但可能会超出模型限制或需要更多计算能力。较小的块可能会丢失关键上下文,也可能无法满足 LLM 标记要求。重叠有助于维护块之间的上下文,但重叠过多会导致数据冗余。

4. 嵌入模型

嵌入将文本转换为密集的矢量表示。选项包括:

词嵌入(例如 Word2Vec):提供传统的词级嵌入。

  • 优点:对于单词级任务来说简单而高效。
  • 缺点:缺乏上下文理解,在RAG中几乎不用
  • 例如:表示“王后”附近“国王”的矢量。

句子嵌入(例如 BERT):捕获句子中单词之间的上下文关系。

  • 优点:更好地理解语义和上下文。
  • 缺点:计算量巨大。
  • 例如:比较“猫坐下”与“猫正在睡觉”。

图嵌入:

  • 优点:嵌入关系数据,适合知识图谱。
  • 缺点:实施复杂。
  • 示例:在社交网络中嵌入节点

图像嵌入:

  • 优点:将图像数据嵌入到向量空间中,以进行基于图像的检索
  • 缺点:需要特定的模型来提取图像特征。
  • 示例:查找相似的产品图像。

具体嵌入模型包括:

  • OpenAIEmbeddings:使用 OpenAI 的 API;广泛使用,对于通用任务有效。
  • OllamaEmbeddings:与 Ollama 集成,实现本地嵌入模型,注重隐私
  • HuggingFaceInstructEmbeddings:使用来自 Hugging Face 的基于指令的模型。
  • HuggingFaceBgeEmbeddings:使用来自 Hugging Face 的 BGE 模型,通常适用于多语言用例。
  • GooglePaLMEmbedding:采用 Google 的 PaLM API,以语义准确性而闻名。
  • CohereEmbeddings:使用 Cohere 强大的嵌入模型,通常用于企业环境。

关键超参数:

  • dimensionality:更高的维度可能捕捉到更多的细微差别,但也可能引入噪音并增加计算量。
  • model_name:根据数据大小和性能标准选择正确的模型至关重要。
  • max_length:限制可嵌入的文本长度,这直接影响块大小。

5.矢量数据库

矢量数据库存储嵌入以实现高效检索。常见的选择包括:

DocArrayInMemorySearch:内存向量搜索。

  • 优点:简单轻量,非常适合小型数据集或原型设计
  • 缺点:不持久,不能处理大量数据。

Pinecone:管理矢量数据库。

  • 优点:完全托管的矢量数据库,可扩展以适应生产,是企业项目的强大选择。
  • 缺点:基于云,因此需要供应商参与。

FAISS(Facebook AI 相似性搜索):Facebook AI 相似性搜索。

  • 优点:搜索高效、快速。
  • 缺点:需要内存,不适用于大型数据集。

Cassandra:分布式 NoSQL 数据库。

  • 优点:可扩展性强,适合大型企业应用。
  • 缺点:需要更复杂的设置和管理。

Chroma:LLM 应用的矢量数据库。

  • 优点:开源,内存友好,有利于开发,拥有强大的社区支持。
  • 缺点:不适合大型数据集和生产。

Weaviate:开源矢量搜索引擎。

  • 优点:完全托管、开源、可扩展、社区良好。
  • 缺点:需要第三方服务。

Milvus:开源矢量数据库。

  • 优点:高度可扩展,专为人工智能和机器学习应用而设计。
  • 缺点:需要深入了解管理基础设施的知识。

pgvector:用于向量搜索的 PostgreSQL 扩展。

  • 优点:PostgreSQL 扩展,如果已经使用 Postgres 的话,这非常棒。
  • 缺点:虽然扩展性很好,但是传统数据库并未针对矢量搜索进行优化。

Qdrant:向量相似性搜索引擎。

  • 优点:开源、提供云选项、适合企业且易于使用。
  • 缺点:需要第三方服务。

Astra DB:托管矢量数据库。

  • 优点:完全托管,基于 Cassandra 构建。非常适合大型企业用例。
  • 缺点:可能非常复杂。

Elasticsearch:搜索和分析引擎。

  • 优点:如果你有使用 elasticsearch 的经验,这是一个不错的选择,可扩展到大型数据集
  • 缺点:成本较高,不适合矢量搜索。

SingleStore:用于交易和分析的统一数据库。

  • 优点:分布式架构允许高效扩展和快速数据检索。
  • 缺点:成本较高且需要技术知识。

关键超参数:

  • index_method:索引向量表示的方法,不同的方法有不同的性能。
  • storage_method:确定向量的存储方式,可能因要求而异。

6. 向量搜索算法

进行查询时,系统会采用矢量搜索算法来查找相关信息。选项包括:

近似最近邻 (ANN) :在高维空间中有效地查找相似的向量。

  • 优点:速度快,适用于大型数据集
  • 缺点:结果是近似匹配,而不是精确结果。
  • 例如:HNSW 算法是一种 ANN 技术。

HNSW和其他方法(如 IVF-PQ 或局部敏感散列 (LSH))也因其速度和准确性的平衡而成为流行的选择。

  • 优点:ANN 的变体,速度快,回忆力好。
  • 缺点:结果近似匹配。

IVF-PQ 或局部敏感哈希 (LSH)

  • 优点:相似性搜索速度快,尤其是在高维空间中。
  • 缺点:近似。

7.检索器

检索器根据查询嵌入识别相关文档或段落。检索器接收用户查询,并利用该查询从向量数据库中获取相关信息。选项包括:

MultiQueryRetriever:使用多个查询进行检索。

  • 优点:生成多种查询变体,增加找到良好相关文档的机会。
  • 缺点:可能会在获取的结果中引入冗余。

SemanticRetrieve:根据语义相似性进行检索。

  • 优点:关注用户查询和向量嵌入之间的语义相似性
  • 缺点:可能不会考虑查询中的特定关键词。

ContextualCompressionRetriever:压缩上下文以实现有效检索。

  • 优点:压缩检索到的文档以仅根据用户查询过滤相关信息,从而减少发送到 LLM 的信息量。
  • 缺点:如果压缩过度,可能会过滤掉相关内容。

LLMChainExtractor:使用 LLM 链进行检索。

  • 优点:使用 LLM 从检索到的文档中提取相关内容,然后将其发送到模型。
  • 缺点:计算成本较高。

EnsembleRetriever:组合多个检索器。

  • 优点:结合多种检索器以获得更好的结果。
  • 缺点:计算成本更高。

BM25Retriever:传统检索方法。

  • 优点:使用 BM25 算法进行基于文本的搜索。
  • 缺点:依赖于关键词匹配,可能会错过语义相关性。

MultiVectorRetriever:使用多个向量进行检索。

  • 优点:可以处理多个向量索引。
  • 缺点:设置更复杂。

ParentDocumentRetriever:根据父文档进行检索。

  • 优点:允许存储带有块的父文档,维护上下文
  • 缺点:加载数据时需要额外的步骤

SelfQueryRetriever:使用自查询进行检索。

  • 优点:允许 LLM 从用户查询中提取查询参数并将其用于检索。
  • 缺点:复杂查询可能会出错。

TimeWeightedVectorStoreRetriever:根据时间加权向量进行检索。

  • 优点:根据时间对文档进行优先排序。
  • 缺点:需要基于时间的文档信息。

8.相似度测量

为了确定检索到的项目之间的相关性,可以采用几种相似度度量:

点积:通过向量乘法计算原始相似度。

  • 优点:计算简单。
  • 缺点:需要标准化的向量。

余弦相似度:确定向量之间的角度差异。

  • 优点:按幅度进行标准化,适合高维数据。
  • 缺点:计算起来比点积更复杂。

欧几里得距离:测量向量之间的直线空间分离。

  • 优点:简单易懂。
  • 缺点:对于高维度或文本嵌入来说效果不佳

曼哈顿距离:计算向量分量之间的绝对差之和。

  • 优点:受异常值的影响较小。
  • 缺点:在文本检索中不太常见

关键超参数:

  • k:要检索的文档数量。
  • similarity_measure:要使用的相似性度量(例如余弦、点积)

9. RAG 中调整超参数的最佳实践

检索增强生成 (RAG) 将检索系统和生成模型的优势结合起来,以生成与上下文相关的输出。为了优化 RAG 流水线的性能,仔细调整超参数至关重要。本博客探讨了超参数调整的最佳实践,涵盖了 RAG 流水线的各个组件,包括模型选择、嵌入策略、检索机制等。

1. 了解 RAG 流水线中的超参数

超参数是影响机器学习模型训练和性能的配置变量。在 RAG 流水线中,超参数可以影响各个阶段,包括数据提取、检索和生成。需要考虑的关键超参数包括:

  • 块大小:确定一次处理多少文本。
  • 前 K 个值:指定从数据库中检索多少个前结果。
  • 嵌入维数:影响数据在向量空间中的表示。
  • 检索阈值:设置检索过程中构成“相关”结果的限制。

2.模型选择和调整

选择正确的检索和生成模型至关重要。以下是一些注意事项:

  • 检索模型:BM25 或密集通道检索 (DPR) 等选项可能很有效。结合稀疏和密集技术的混合模型通常能产生更好的结果。
  • 生成模型:根据应用程序的复杂性和要求选择 GPT-3、BERT 或 T5 等模型。
  • 最佳实践:尝试不同的模型组合,找到适合特定用例的最佳设置

3.超参数调整策略

有几种有效调整超参数的策略:

网格搜索:系统地探索一组预定义的超参数。

  • 优点:全面;测试所有组合。
  • 缺点:计算成本高昂;可能由于“维数灾难”而错过最佳参数

随机搜索:从指定分布中随机抽样超参数。

  • 优点:比网格搜索更有效;无需进行详尽的测试即可获得良好的结果。
  • 缺点:方差较大;有时需要更长时间才能找到最佳性能

贝叶斯优化:使用概率模型根据过去的评估找到最佳超参数。

  • 优点:高效;专注于超参数空间的有前景的领域。
  • 缺点:与简单方法相比,实现起来更复杂

自动超参数调整工具:Ray Tune或等工具Optuna可以通过利用高级算法智能优化超参数,从而简化调整过程

4. 组件特定的调整

RAG 流水线的每个组件都有特定的超参数,可以进行调整以提高性能:

数据加载和分块:

尝试不同的块大小和重叠设置,以找到上下文保留和处理效率之间的最佳平衡

嵌入模型:

根据维度和语义保留选择嵌入模型。微调嵌入也可以显著提高性能

检索参数:

调整与查询转换和高级检索策略相关的参数,以增强检索到的文档的相关性

5. 监控性能并进行迭代

实施更改后,持续监控 RAG 流水线的性能至关重要。使用精度、召回率、F1 分数或用户满意度分数等指标来评估系统在不同超参数设置下的表现。

  • 反馈循环:实施反馈机制,让你能够根据实际使用数据改进模型