贵阳网站开发zu97小学生简短小新闻摘抄
2 向量相似性搜索与混合搜索
本章内容
- 介绍嵌入(embeddings)、嵌入模型、向量空间和向量相似性搜索
- 向量相似性搜索在 RAG 应用中的作用
- 使用向量相似性搜索实现 RAG 应用的实践指南
- 在 RAG 应用中加入全文搜索,以了解混合搜索方法如何提升检索效果
**构建知识图谱通常是一个迭代过程:你从非结构化数据开始,然后逐步为其添加结构。**当你拥有大量非结构化数据并希望开始利用它们来回答问题时,这种情况尤为常见。
本章将探讨如何使用 RAG 结合非结构化数据来回答问题。我们将研究如何利用向量相似性搜索和混合搜索来查找相关信息,并如何利用这些信息生成答案。在后续章节中,我们将进一步探讨当数据具有一定结构时,可以采用哪些技术来优化检索器(retriever)和生成器(generator),以获得更好的结果。
在数据科学和机器学习领域,嵌入模型和向量相似性搜索是处理复杂数据的重要工具。本章将探讨这些技术如何将文本、图像等复杂数据转换为一种统一的数值表示形式,即“嵌入”。
# 可以对相关的实例进行补充
|相关代码:[https://github.com/tomasonjo/kg-rag/blob/main/notebooks/ch02.ipynb ](https://github.com/tomasonjo/kg-rag/blob/main/notebooks/ch02.ipynb)。
2.1 RAG 架构的组件
在 RAG 应用中,主要有两个组件:检索器(retriever)和生成器(generator)。检索器使用向量相似性搜索来查找相关信息,而生成器则利用这些信息来生成回应。
2.1.1 检索器
检索器是 RAG 应用的第一个组件。其作用是查找相关信息,并将这些信息传递给生成器。RAG 框架本身并未规定检索器应如何查找相关信息,但最常见的方法是使用向量相似性搜索。
向量索引
虽然向量相似性搜索并不严格依赖向量索引,但强烈建议使用。向量索引是一种数据结构(类似于映射表),它以一种便于搜索相似向量的方式存储向量。使用向量索引时,检索方法通常被称为近似最近邻搜索(approximate nearest neighbor search)。这是因为向量索引并不能找到精确的最近邻,而是找到与目标向量非常接近的向量。这是一种在速度与准确性之间的权衡:向量索引比暴力搜索(brute-force search)快得多,但准确性稍低。
向量相似性搜索函数
向量相似性搜索函数是一种以向量作为输入,并返回一组相似向量的函数。该函数可能使用向量索引来查找相似向量,也可能采用其他方法(如暴力搜索)。关键在于,它能够返回一组相似的向量。
[!NOTE]
余弦相似度的公式如下:
Cosine Similarity=A⋅B∥A∥∥B∥=∑i=1nAiBi∑i=1nAi2∑i=1nBi2 \text{Cosine Similarity} = \frac{\mathbf{A} \cdot \mathbf{B}}{\|\mathbf{A}\| \|\mathbf{B}\|} = \frac{\sum_{i=1}^{n} A_i B_i}{\sqrt{\sum_{i=1}^{n} A_i^2} \sqrt{\sum_{i=1}^{n} B_i^2}} Cosine Similarity=∥A∥∥B∥A⋅B=∑i=1nAi2∑i=1nBi2∑i=1nAiBi
其中:
- A\mathbf{A}A 和 B\mathbf{B}B 是两个向量,
- AiA_iAi 和 BiB_iBi 是向量在第 iii 维的分量,
- A⋅B\mathbf{A} \cdot \mathbf{B}A⋅B 表示向量的点积,
- ∥A∥\|\mathbf{A}\|∥A∥ 和 ∥B∥\|\mathbf{B}\|∥B∥ 分别表示向量的模(欧几里得范数)。
[!NOTE]
欧几里得距离的公式如下:
Euclidean Distance=∥A−B∥=∑i=1n(Ai−Bi)2 \text{Euclidean Distance} = \|\mathbf{A} - \mathbf{B}\| = \sqrt{\sum_{i=1}^{n} (A_i - B_i)^2} Euclidean Distance=∥A−B∥=i=1∑n(Ai−Bi)2
其中:
- A\mathbf{A}A 和 B\mathbf{B}B 是两个 nnn 维向量,
- AiA_iAi 和 BiB_iBi 分别是向量在第 iii 维上的分量。
最常见的两种向量相似性搜索函数是余弦相似度(cosine similarity)和欧几里得距离(Euclidean distance)。欧几里得距离反映了文本的内容和强度。余弦相似度是衡量两个向量之间夹角的指标。在文本嵌入的场景中,这个夹角代表了两段文本在语义上的相似程度。余弦相似度函数接收两个向量作为输入,返回一个介于 0 到 1 之间的数值:0 表示两个向量完全不同,1 表示完全相同。余弦相似度被认为最适合用于文本聊天机器人。
嵌入模型
对文本进行语义分类后得到的结果称为嵌入(embedding)。**任何希望通过向量相似性搜索进行匹配的文本,都必须先转换为嵌入。**这一过程通过嵌入模型完成,且在整个 RAG 应用中必须保持嵌入模型的一致性。如果需要更换嵌入模型,则必须重新构建整个向量索引。
嵌入是一组数值,其长度称为嵌入维度(embedding dimension)。嵌入维度非常重要,因为它决定了嵌入所能承载的信息量。维度越高,生成嵌入和执行向量相似性搜索时的计算开销就越大。
嵌入是一种将复杂数据表示为更简单、更低维空间中的一组数字的方法。可以将其理解为将数据转换为计算机易于理解和处理的格式。
嵌入模型提供了一种统一的方式来表示不同类型的数据。**嵌入模型的输入可以是任何复杂数据,输出则是一个向量。**例如,在处理文本时,嵌入模型会将词语或句子转换为向量,即一组数字。该模型经过训练,确保这些数字列表能够捕捉原始词语的关键特征,如其含义或上下文。
文本分块
文本分块(Text chunking)是指将文本分割成更小片段的过程。这样做是为了提高检索器的准确性。较小的文本片段意味着嵌入的语义范围更窄、更具体,因此在搜索时检索器能找到更相关的信息。
文本分块至关重要,但要恰当地实现并不容易。你需要思考如何分割文本:是按句子、段落、语义单元,还是其他方式?是使用滑动窗口,还是固定大小?分块的大小应该如何设定?
这些问题没有标准答案,具体取决于应用场景、数据类型和领域。但重要的是要认真思考这些问题,并尝试不同的方法,以找到最适合你应用场景的解决方案。
检索器工作流
当所有组件准备就绪后,检索器的工作流非常简单。它接收一个查询作为输入,使用嵌入模型将其转换为向量,然后利用向量相似性搜索函数查找相似的向量。在最简单的情况下,检索器工作流直接返回源文本块,这些文本块随后被传递给生成器。但在大多数情况下,检索器工作流还需要进行一些后处理,以筛选出最适合传递给生成器的最佳文本块。
2.1.2 生成器
生成器是 RAG 应用的第二个组件**。它利用检索器找到的信息来生成回应。**生成器通常是一个大语言模型(LLM),但与微调或依赖模型的原始知识相比,RAG 的一个优势在于,所使用的模型无需如此庞大。这是因为相关信息已由检索器提供,因此生成器不必“知晓一切”,而只需知道如何利用检索器找到的信息来生成回应。这相比让模型掌握全部知识而言,是一个更小的任务。
因此,我们是利用语言模型的文本生成能力,而非其内部知识。这意味着我们可以使用更小的语言模型,这类模型运行速度更快、成本更低。同时,这也意味着我们可以更信任模型的回应是基于检索器所提供的信息,从而减少虚构内容的产生,降低“幻觉”现象的发生。
2.2 使用向量相似性搜索的 RAG
要实现一个基于向量相似性搜索的 RAG 应用,需要准备几个关键组件。本章将逐一介绍这些组件。目标是展示如何实现一个基于向量相似性搜索的 RAG 应用,以及如何利用检索器找到的信息生成回应。
我们需要将该应用分为两个阶段:
- 数据准备
- 查询时处理
2.2.1 应用数据准备
从前文可知,为了在运行时执行向量相似性搜索,我们需要对数据进行一定处理,使其能够被嵌入模型转换到向量空间中。所需组件包括:
- 文本语料库
- 文本分块函数
- 嵌入模型
- 具备向量相似性搜索能力的数据库
数据将以文本块的形式存储在数据库中,同时向量索引将填充这些文本块的嵌入向量。之后在运行时,当用户提出问题时,该问题将使用与文本块相同的嵌入模型进行向量化,然后利用向量索引查找最相似的文本块。
2.2.2 文本语料库
你可以找你自己喜欢的 然后根据文本内容提出问题,并进行验证。
2.2.3 文本分块
尽管当前的大语言模型具备足够大的上下文窗口,允许我们将整篇论文作为一个单独的文本块处理,但为了获得更好的检索效果,我们将论文分割成更小的片段,每几百个字符作为一个文本块。最佳的分块大小因具体应用场景而异,因此建议尝试不同的分块尺寸以找到最优配置。
在本例中,我们还希望文本块之间存在一定重叠。这是因为某些答案可能跨越多个文本块,引入重叠有助于提高检索的完整性。因此,我们将采用滑动窗口的方式,设置窗口大小为 500 个字符,重叠部分为 40 个字符。这会使索引略微增大,但能显著提升检索器的准确性。
为了帮助嵌入模型更好地理解每个文本块的语义,我们将仅在空格处进行分割,避免在文本块的开头或结尾出现被截断的单词。该函数接收文本、分块大小(字符数)、重叠大小(字符数),以及一个可选参数(指定是否仅在空白字符处分割),最终返回一个文本块列表。