相同的数据,相同的查询——但采用了不同的搜索策略。拖动查询点,调整 nprobe,然后点击“运行搜索”以观察“IVF ”如何跳过大部分数据。
nprobe 聚类:这些聚类会亮起。所有其他聚类将被完全跳过。权衡:扫描的 nprobe → 扫描的聚类更多 → 召回率更高但速度较慢。更小 nprobe → 速度更快,但可能会遗漏位于未扫描聚类中的真实邻居。尝试将 nprobe = 1 并将查询拖动至簇边界附近,观察召回率如何下降。
IVF (倒排文件)是一种基于聚类的近似最近邻索引。在构建阶段,k-means 将所有向量划分为 nlist 簇,每个簇由其质心表示。在查询时,搜索首先仅将查询向量与各质心进行比对,挑选出最近的 nprobe 簇,并仅扫描这些簇内的向量——跳过其余所有内容。
Milvus 提供了多种IVF 变体,它们在内存占用与精度之间进行权衡: IVF_FLAT 存储原始向量(精度最高), IVF_SQ8 将每个维度压缩为1字节(内存占用减少约4倍,召回率损失较小),以及 IVF_PQ 应用乘积量化以实现更高的压缩率,但召回率代价更大。
nlist (构建时间):k-means聚类的数量。一个常见的起始值是4 × sqrt(N) (针对N个向量)。聚类数量越多,每个聚类规模越小——扫描速度越快,但质心遍历的开销更大,边界效应也会增强。nprobe (查询时间):每次查询需扫描的簇数。这是影响召回率与延迟的主要调节参数——正是上方滑块所控制的。建议从 nlist / 16 ,并逐步增加,直到召回率达到目标值。IVF 构建速度快,除向量本身外内存开销小,且易于理解——但在相同的召回率目标下,HNSW 通常能在内存中更快地响应查询。当您需要频繁重建索引(快速构建至关重要)、内存受限(IVF_SQ8/IVF_PQ )或希望获得可预测且可调的扫描行为时,请选择IVF 。 若需最低的内存查询延迟,请选择HNSW ;当向量完全无法放入RAM 时,请选择DiskANN 。
这三种聚类方式对向量的处理方式相同;它们的区别在于向量在聚类内部的存储方式。IVF_FLAT 保留原始浮点向量(召回率最高)。IVF_SQ8 将每个维度量化为 8 位,在召回率略有损失的情况下,内存占用减少约 4 倍。IVF_PQ 用短的乘积量化码替换向量,以实现最高的压缩率,但召回率损失最大。
一个常见的经验法则是:当向量数为 N 时,nlist = 4 × sqrt(N),随后在查询时调整nprobe 。较大的nprobe 会扫描更多簇:召回率越高,延迟越大。建议从nlist/16 开始,并逐步增加,直到在保留的查询集上召回率达到目标值。
这是由于聚类边界的原因。如果查询点位于聚类边缘附近,其部分真实邻居可能位于相邻的聚类中,而该聚类并未包含在已扫描的nprobe 聚类之中。您可以在可视化中通过将查询点拖动至nprobe =1的边界附近来观察这一现象。
在相同召回率下,HNSW 通常在内存搜索中速度更快,但占用更多内存且构建速度较慢。IVF 构建速度快,当内存紧张时,可与量化技术(SQ8/PQ )配合使用。对于完全超出RAM 限制的数据集,请考虑改用DiskANN 。
深入了解:请阅读《IVF_FLAT 》文档以了解索引参数,或参阅《索引详解》获取完整的决策指南。