IVF:只扫描相关向量分桶
先用粗量化器缩小搜索区域,再扫描被选中的倒排列表。
相关概念
工程问题#
大规模 embedding 检索中,扫描全部向量的距离计算与内存访问成本过高。
实际实现#
训练粗量化器后,将向量分配到 nlist 个桶。查询先寻找 nprobe 个候选桶,再对这些桶内的数据计算距离并汇总结果。
处理流程#
- 训练粗量化器并建立分桶
- 按最近中心将向量写入倒排列表
- 查询选择 nprobe 个桶
- 扫描候选列表并合并 top-k
源码片段#
固定版本 · 原文摘录faiss/IndexIVF.cppv1.9.0 · L322–L343
322 quantizer->search(323 n,324 x,325 nprobe,326 coarse_dis.get(),327 idx.get(),328 params ? params->quantizer_params : nullptr);329330 double t1 = getmillisecs();331 invlists->prefetch_lists(idx.get(), n * nprobe);332333 search_preassigned(334 n,335 x,336 k,337 idx.get(),338 coarse_dis.get(),339 distances,340 labels,341 false,342 params,343 ivf_stats);IndexIVF::search · sub_search_func
粗量化器先为每个查询选择 nprobe 个列表编号和距离,预取这些列表,再把已分配候选交给 search_preassigned 扫描。这里展示候选缩减的调用链,实际距离计算由具体 IVF 存储/扫描器实现决定;倒排键是量化单元,不是文本词项。
CPPMIT
收益与取舍#
工程分析带来的收益
- 减少需要扫描的向量数量
- 可与 Flat、PQ 等不同存储编码组合
付出的代价
- 未探测桶中的真近邻可能被遗漏
- 分桶不均衡及数据分布变化会影响成本与召回
可比较的选择
HNSW通过图导航选候选,避免依赖同样的固定分桶,但需要图边和构建开销。
版本与适用范围#
IVF 的倒排键是粗量化单元,不是文本关键词。此案例解释候选缩减,是否压缩向量取决于具体 IVF 变体。