索引选不对,成本贵十倍!HNSW与IVF如何做选型

2025-11-27

By 李成龙

索引选不对,成本贵十倍!HNSW与IVF如何做选型

在向量数据库中,我们经常需要在海量高维向量(例如图像特征、文本 Embedding、语音向量)里快速找到最相似的若干个结果。如果没有索引,就只能逐个查询向量和底库向量的计算相似度,这就叫暴力搜索 (brute force),当数据量达到千万、亿级时,暴搜几乎不可用。

为了解决大规模向量检索效率问题,研究者提出了近似最近邻搜索(ANN, Approximate Nearest Neighbor Search) 方法,其中,最经典的一种索引算法就是 IVF(Inverted File)倒排文件索引。

1. 什么是 IVF 向量索引?

IVF(Inverted File,倒排文件)向量索引,是近似最近邻(ANN)搜索算法中的一种,核心是借鉴文本检索的 “倒排索引” 思路。

它通过“聚类”把高维向量空间划分成若干个簇(bucket),每个簇由一个中心向量(centroid)和属于该簇的向量列表组成。

基于这一分类,查询会被分为两个步骤:

  1. 定位 “临近簇”:先找到离查询向量最近的几个簇,排除绝大多数无关向量;

  2. 簇内精算:只在这几个簇里做精确距离计算,不用遍历全库。

靠先筛选、再细算,IVF 把高维向量搜索的计算量砍了大半。其过程就像一座高效图书馆。所有书籍(向量)按类别(簇)分好区,比如人文、历史、科技;读者(查询向量)进门不用瞎转,直接锁定最相关的 2-3 个区域,在小范围里找书,效率自然翻倍。

2. IVF 向量索引构建流程(Build)

IVF 索引的构建过程可以分为三个主要阶段:聚类训练、向量分配和向量压缩编码(可选),整体的构建流程如下图所示:

28-1.webp 28-1.webp

Step 1. 训练质心(Centroids)

首先,对数据集 X 运行 k-means 聚类,将高维向量空间划分为 nlist 个簇(cluster)。每个簇有一个代表点(质心 centroid),存放在质心表 C 中。质心数量 nlist 是一个关键超参数,决定了簇划分的粒度。

k-means 的原理:

  1. 初始化:随机选择 nlist 个向量作为初始质心。

  2. 分配样本:计算每条向量到所有质心的距离,把它分配到最近的簇。

  3. 更新质心:对每个簇,计算簇内向量的平均值作为新的质心。

  4. 迭代收敛:重复分配和更新,直到质心位置基本稳定或达到最大迭代次数。

最终得到的 nlist 个质心,就构成了 IVF 的“索引目录”。这些质心决定了数据的“粗分桶”方式,后续查询时会先用它们来快速缩小搜索范围。训练质心这一步类比图书馆区域分类:nlist 越大,类别分得越细;nlist 越小,每个类别越“大杂烩”。

Step 2. 建立倒排表(Inverted Lists)

每条向量根据“距离哪个质心最近”被分配到对应簇,形成倒排表 List_i。

  • 倒排表记录了属于该簇的所有向量 ID 及其存储信息。

  • 收益:查询时不必遍历全库,而是只看几个最相关的 List。

建立倒排表这一步类比书本被分配到对应主题区域,借书时只查相关区域,不用逛全馆。

Step 3. 向量压缩编码(可选)

为了节省内存和加速计算,常常对簇内向量做压缩编码,常见的压缩编码方式有:

  • SQ8(Scalar Quantization):对向量的每个维度做 8bit 标量量化,对于 float32 的向量,存储空间从 4 字节压缩为 1 字节,实现4:1的压缩比。

  • PQ(Product Quantization):对簇内向量做乘积量化,将高维向量拆分成若干个子空间(例如把 128 维拆成 8 个子向量,每个 16 维)。在每个子空间里,预先训练一个小码本(通常大小为 256),用一个 8 bit 索引来表示该子向量的近似位置。这样,一个 128 维的原始向量(float32 存储需 512 byte),最终只需要 8 个byte(8 个子空间 × 1 byte)就能表示,实现了约 64:1 的压缩比。

当然不对簇内向量进行压缩也是可以的,就是常见的 IVF_FLAT 索引。

通过前面三步的构建,最终生成的 IVF 索引包含三部分:

  1. 质心表 C:存放所有簇的代表向量(中心点向量)。

  2. 倒排表 Lists:每个簇里的成员 ID 与编码。

  3. 编码器及码本(可选):用于存储向量的压缩表示,并通过查表的方式加速近似距离计算。

3. IVF 向量索引查询流程(Search)

有了前面构建好的 质心表 + 倒排表 + 编码器及码本(可选),查询时就可以利用 IVF 索引来加速相似向量搜索。搜索过程可以分为三步,如下图所示:

28-2.webp 28-2.webp

Step 1. 计算查询向量到所有质心的距离

当一个查询向量 q 到来时,首先需要判断它最可能属于哪些簇。

  • 系统会将 q 与质心表 C 中的所有质心计算距离(通常用欧式距离或内积)。

  • 然后对这些质心按距离进行排序,得到一个由近到远的簇列表。

例如,图中显示的排序结果是:C4 < C2 < C1 < C3 < C5。

Step 2. 选择距离最近的 nprobe 个簇

为了避免全表扫描,IVF 只会在 前 nprobe 个最近的簇中继续检索。

  • 参数 nprobe 控制了搜索范围:

    • nprobe 越小,速度快但召回率降低;

    • nprobe 越大,召回率更高但延迟上升。

  • 实际应用中,可以根据延迟预算来动态调整 nprobe。

在图例中,nprobe = 2,因此只会选择 Cluster 2 和 Cluster 4 作为候选簇。

Step 3. 在候选簇内进行精确或近似比较

进入候选簇后,就需要比较查询向量与簇内向量的相似度:

  • 精确比较(IVF_FLAT):直接取出原始向量,与 q 逐个计算距离,得到最准确的结果。

  • 近似比较(IVF_PQ/IVF_SQ8):如果采用了 PQ/SQ8 压缩,如果采用了 PQ/SQ8 压缩,系统会用查表法(lookup table method) 来加速距离计算:在查询开始时,预先计算查询向量与码本的距离,之后只需“查表+加和”即可快速得到近似距离。

最终,来自不同簇的候选结果会被合并排序,输出最相似的 Top-k 向量。

4. 最佳实践

在理解了 IVF 向量索引的构建与搜索流程之后,真正落地到业务时,往往还需要在 性能、精度和内存 三者之间做权衡。下面结合工程实践,给出一些常见的经验指导。

4.1 nlist 的选择

  • nlist 越大:簇划分越细,每个簇更小,搜索时需要扫描的向量更少,速度更快。但代价是索引构建更慢,而且质心表(centroids)占用更多内存。

  • nlist 越小:构建快,但每个簇更“拥挤”,检索时单簇扫描量更大,容易出现性能瓶颈。

  • 经验值:对于百万级数据,通常设定 nlist ≈ √N (N 代表需要创建索引的数据分片中的向量条数)是一个不错的起点。例如 100 万向量,可以选 nlist=1000;对于更大的数据量,千万级或者亿级,在常见的向量数据库系统中,一般都会对数据进行分片,使每个分片的数据量在百万级。因为是创建索引时的参数,设置的时候需要更加谨慎,后期想要修改时,需要重新对数据集构建索引。建议在实际业务中,按照2的指数幂,比如 1024,2048 多测试几组。

4.2 nprobe 的调优

  • nprobe 越大:覆盖的簇越多,召回率越高,但延迟也会线性上升。

  • nprobe 越小:延迟很低,但可能漏掉一些真正的近邻,影响结果质量。

  • 调参建议:在延迟不敏感的情况下,可以动态调整 nprobe(比如从 1–16 逐步试探),观察召回率和延迟曲线,找到“平衡点”。因为是搜索端的参数,可以随时进行调整,修改的代价很低。

4.3 IVF 索引的常见变体

在构建索引过程中,是否对簇内向量做压缩编码,以及使用哪种压缩编码方式,可以派生出 IVF 索引的三种常见变体:

IVF 变体特点适用场景
IVF_Flat簇内原样存储向量,无压缩,精度最高,内存占用最大数据量中等(亿级以内)场景、召回率要求高(95%+)
IVF_PQ簇内向量用乘积量化(PQ)压缩,通过调节压缩比,可使内存大幅下降亿级以上的大规模向量检索,可接受精度损失,64:1压缩后,recall 通常在 70% 左右,不过通过减小压缩比,也可以提升整体recall到90%+
IVF_SQ8采用标量量化,内存占用介于 Flat 与 PQ 之间亿级以上大规模检索,且需要保证较高精度(recall 90%+)

28-3.webp 28-3.webp

4.4 与 HNSW 的对比

IVF 和 HNSW(分层可导航小世界) 都是常见的内存型向量索引,下面通过一张对照表来详细了解两者的区别。

维度IVF(倒排文件)HNSW(分层可导航小世界)
算法思想聚类分桶多层图导航
内存占用较低较高
索引构建速度快(只需聚类)慢(需建多层图)
查询速度(无过滤)快,依赖 nprobe极快,对数级复杂度
查询速度(带过滤)快, 质心层面先筛选簇缩小范围不稳定,尤其是过滤比例较高( 90%+)时,几乎全图上做遍历,比暴搜还慢
召回率与是否量化有关,非量化情况召回率可达95%以上通常更高,98%以上
参数nlist、nprobem、ef_construction、ef_search
适用场景内存有限且需较高查询性能和召回率,带过滤条件的检索内存充足且需极高查询性能和召回率,无过滤或过滤比例不高

28-4.webp 28-4.webp

在实际应用中,过滤条件( “只查某个用户的数据” 或 “限定时间区间内的向量”)非常常见。但是由于算法原理的区别,IVF 比 HNSW 更擅长处理过滤搜索。

  • IVF 优势:IVF 可以先在簇质心层面粗过滤,快速缩小候选集合,再做向量级别的精确比对,因此即便过滤比例很高,性能依旧可控。

  • HNSW 劣势:HNSW 是基于图遍历的搜索,无法在结构层面直接利用过滤条件。当过滤比例低时影响不大,但如果过滤比例很高(比如 90%+ 的数据被过滤掉),会使得图里的数据形成很多孤岛,就可能导致几乎在全图上做遍历,性能比暴力搜索还差。

5. 总结

IVF(Inverted File Index,倒排文件索引)作为向量数据库中最经典的近似最近邻(ANN)方法之一,已经在工业界和学术界得到了广泛应用。它的核心思路是“先粗分,再细排”:通过 k-means 聚类将海量高维向量划分到不同簇中,查询时只需进入最相关的少量候选簇,既避免了全表暴力扫描,又能兼顾速度与精度。通过调节 nlist 与 nprobe,用户可以在不同场景下灵活权衡延迟与召回率。在实际落地中,IVF 索引已经被应用在多类高价值场景:

  • 电商搜索:用户根据一张商品图片,快速在海量底库中找到相似商品。

  • 专利检索:通过一段描述,在亿级专利库中找到语义最相关的专利,比传统关键词搜索更高效。

  • RAG 知识库:根据用户问题,在百万级租户数据中,找出精准的上下文内容。

与 HNSW 等图索引相比,IVF 的优势在于构建速度快、内存消耗低,尤其适合大规模和带过滤条件的检索。在工程实践层面,Milvus 等开源向量数据库已经对 IVF 全系列索引做了完整支持,开发者可以直接调用 IVF_FLAT、IVF_PQ、IVF_SQ8 等索引类型。如果你正在探索如何落地图片搜索、推荐系统或RAG知识库等AI应用,不妨尝试在 Milvus 中体验 IVF 索引,感受高效的向量搜索能力。

  • 李成龙

    李成龙

    准备好开始了吗?

    立刻创建 Zilliz Cloud 集群,存储和检索您的向量。

    免费试用 Zilliz Cloud

    AI Assistant