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 举例索引构建和检索过程学习 待补充

 

 

 

 

 

 

 

posted on   zhangkele  阅读(185)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示