FAISS 三种向量检索方式学习
FAISS(Facebook AI Similarity Search)是一个高效的向量检索库,特别适用于大规模高维数据的相似度搜索。它的核心原理是通过不同类型的索引结构来加速相似度搜索过程。三个基础索引类型是:
1. IndexFlatL2
2. IndexIVFFlat
3. IndexIVFPQ
这些索引有不同的设计和优化目标,适用于不同的数据规模和性能需求。详细解释一下每个索引的原理。
1. IndexFlatL2
原理:
IndexFlatL2 是最简单的索引类型,也可以被看作是一个“暴力搜索”方法。它直接对所有的向量进行精确搜索,计算每个查询向量与数据集中所有向量的L2距离(欧几里得距离)。
优点:
• 精确:返回的结果是精确的,即在给定的查询向量中,最接近的向量会被精确地返回。
• 简单实现:由于没有任何近似方法,所以实现起来非常简单,计算和存储开销较低。
缺点:
• 计算开销高:对于大型数据集(尤其是数百万或更多的向量),计算每个查询与所有数据的L2距离非常慢。因为每次查询都需要扫描所有向量。
适用场景:
• 数据集较小,或者性能要求较低时使用,能够接受线性扫描的计算开销。
2. IndexIVFFlat
原理:
IndexIVFFlat 是一种基于 倒排文件(Inverted File)的近似算法。在这个索引中,首先将所有的向量分成多个簇,每个簇代表了一组相似的向量。簇的划分是基于 K-means 聚类 或类似的聚类算法来实现的。每个簇会有一个“簇中心”,然后将这些簇的中心作为倒排索引的条目。
在查询时,IndexIVFFlat 会首先通过查询向量与各个簇的中心进行匹配,找到最近的簇,然后在这个簇中执行精确的 L2 搜索,而不需要在所有向量中进行全局搜索。
工作流程:
1. 训练阶段:对所有向量进行 K-means 聚类,确定每个簇的中心。
2. 索引阶段:对于每个向量,记录它属于哪个簇。
3. 查询阶段:
• 查询向量首先计算与各个簇中心的距离,选择距离最近的簇。
• 在选定的簇中,执行精确的 L2 搜索,返回最接近的向量。
优点:
• 效率提升:通过将数据划分为多个簇,减少了需要计算的距离数量,使得查询速度大大提升。
• 可扩展性:相比于 IndexFlatL2,IndexIVFFlat 在大规模数据集上的性能更好,尤其是在搜索时只访问部分簇而非整个数据集。
缺点:
• 近似搜索:由于簇划分的关系,返回的结果是近似的,不保证全局精确最邻近向量。
• 需要训练:IndexIVFFlat 需要先进行 K-means 聚类训练,这可能增加时间成本。
适用场景:
• 中等规模的数据集,能够接受一定的近似误差,但要求较高的查询速度。
3. IndexIVFPQ
原理:
IndexIVFPQ 是基于 倒排文件(IVF) 和 量化(Product Quantization, PQ) 技术的组合索引。它在 IndexIVFFlat 的基础上引入了量化(PQ),进一步降低了存储需求并加速了查询。
• 倒排文件部分:与 IndexIVFFlat 一样,首先将数据集划分为多个簇,每个簇有一个中心。
• 量化(Product Quantization, PQ) 部分:每个簇内部的向量进一步被量化。具体来说,PQ 将向量分为多个子向量,并对每个子向量进行量化。每个子向量使用有限的码字表进行近似,从而减少存储需求。
通过使用量化技术,IndexIVFPQ 大幅减少了存储空间和内存占用,同时在查询时通过量化码字的查找可以更高效地进行相似度计算。
工作流程:
1. 训练阶段:
• 执行 K-means 聚类,划分簇。
• 对每个簇内部的向量进行 Product Quantization(PQ),即将每个向量拆分为多个子向量,并对每个子向量进行量化。
2. 索引阶段:为每个向量生成一个量化的编码,存储在倒排索引中。
3. 查询阶段:
• 查询向量首先计算与簇中心的距离,找到最近的簇。
• 在选定的簇中,使用量化编码进行快速近似查找。
优点:
• 更低的存储开销:通过量化,显著降低了内存占用和存储需求,适合大规模数据集。
• 查询效率高:相比于 IndexIVFFlat,IndexIVFPQ 更节省存储和内存,因此在大规模向量搜索时效率更高。
缺点:
• 近似误差:由于量化引入了误差,返回的结果是近似的,精度可能低于精确搜索。
• 训练复杂度:量化技术和倒排索引的结合可能使得训练过程比 IndexIVFFlat 更为复杂。
适用场景:
• 大规模数据集,要求存储和内存占用低,同时能接受一定的近似误差和训练成本。
总结对比:
索引类型 精度 查询速度 存储需求 训练成本 适用场景
IndexFlatL2 精确 慢(暴力搜索) 高(无压缩) 低 小规模数据集,精确查询
IndexIVFFlat 近似 较快(簇划分加速) 中等(簇中心存储) 中等 中规模数据集,要求较快的查询
IndexIVFPQ 近似 非常快(量化加速) 低(量化存储) 高 大规模数据集,存储和内存有限
每种索引方法都在特定的场景中有所优势,选择哪种索引取决于你的数据规模、对精度的需求以及查询速度和存储的平衡。
=============================================================================================================================================
IndexIVFFlat 向量检索的原理和检索过程 举例学习
可以通过一个具体的例子来详细讲解 K-means 聚类 和 倒排存储 在 FAISS 中的应用。这个过程将包括如何将向量数据聚类,如何在倒排索引中存储这些簇的信息,以及如何进行检索。
假设场景:
假设有一个向量数据集,每个向量表示一个 2D 点(二维空间中的坐标),需要通过 K-means 聚类 将这些点分成多个簇,并使用 倒排索引 来加速相似度查询。
数据集:
创建一个简单的二维数据集,包含 10 个点:
Data points (二维向量):
(1.0, 2.0)
(2.0, 3.0)
(3.0, 3.5)
(8.0, 8.0)
(9.0, 8.5)
(10.0, 9.0)
(5.0, 6.0)
(6.0, 5.5)
(7.0, 7.0)
(6.5, 6.5)
这些数据点代表了 10 个向量。假设我们使用 K-means 聚类 将这些点分成 2 个簇。
步骤 1:K-means 聚类
我们先用 K-means 算法将这些点划分为两个簇(K=2)。通过训练 K-means 算法,我们得到如下结果:
• 簇 1:包含 (1.0, 2.0), (2.0, 3.0), (3.0, 3.5), (5.0, 6.0), (6.0, 5.5), (6.5, 6.5)
• 簇 2:包含 (8.0, 8.0), (9.0, 8.5), (10.0, 9.0), (7.0, 7.0)
簇中心(质心)大致为:
• 簇 1 中心:(4.5, 5.0)
• 簇 2 中心:(8.5, 8.0)
步骤 2:倒排索引存储
在 FAISS 中,倒排索引是通过 倒排文件(Inverted File)来实现的。每个簇中心会存储在一个倒排列表中,列表中的每个条目指向属于该簇的向量。
假设我们将上面的向量划分为 2 个簇,并且用倒排索引来存储这些信息,存储结构大概如下:
• 簇 1:
• 簇中心:(4.5, 5.0)
• 向量:[(1.0, 2.0), (2.0, 3.0), (3.0, 3.5), (5.0, 6.0), (6.0, 5.5), (6.5, 6.5)]
• 倒排索引:[0, 1, 2, 6, 7, 9](这些索引表示属于簇 1 的向量在数据集中的位置)
• 簇 2:
• 簇中心:(8.5, 8.0)
• 向量:[(8.0, 8.0), (9.0, 8.5), (10.0, 9.0), (7.0, 7.0)]
• 倒排索引:[3, 4, 5, 8](这些索引表示属于簇 2 的向量)
步骤 3:查询和检索
假设我们要进行一次查询,查询点为 (7.5, 7.5),我们要找到离这个点最近的点。
1. 查询簇中心:首先,我们计算查询点与各个簇中心的距离:
• 查询点 (7.5, 7.5) 与簇 1 中心 (4.5, 5.0) 的距离:
• 查询点 (7.5, 7.5) 与簇 2 中心 (8.5, 8.0) 的距离:
查询点与簇 2 中心的距离更小,因此查询点应当属于簇 2。
2. 访问簇 2 的倒排索引:在簇 2 中,我们有一个倒排索引 [3, 4, 5, 8],这些索引对应的向量是我们需要检查的候选向量。
3. 计算距离:我们接下来计算查询点 (7.5, 7.5) 与簇 2 中的每个向量的距离,找出最接近的向量:
• 与 (8.0, 8.0) 的距离:
• 与 (9.0, 8.5) 的距离:
• 与 (10.0, 9.0) 的距离:
• 与 (7.0, 7.0) 的距离:
最接近的两个向量是 (8.0, 8.0) 和 (7.0, 7.0),它们与查询点的距离都是约 0.707。
4. 返回结果:根据查询,我们会返回最接近的向量 (8.0, 8.0) 和 (7.0, 7.0)。
总结:
在这个例子中,我们通过以下步骤实现了 K-means 聚类 和 倒排存储与检索:
1. 使用 K-means 聚类 将数据划分为两个簇。
2. 为每个簇创建了倒排索引,存储属于该簇的向量的索引。
3. 在查询时,首先计算查询点与簇中心的距离,找到最接近的簇。
4. 在选定的簇中,使用倒排索引快速访问所有可能的候选向量,并计算它们与查询点的距离,最终返回最接近的向量。
通过这种方法,倒排索引能够有效减少搜索空间,从而加速相似度查询。FAISS 在大规模数据集中的实现通常会结合 倒排文件 和 量化技术(如 PQ)来进一步提升查询效率。
=======================================================================================================
IndexIVFPQ 举例索引构建和检索过程学习 待补充
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)