跳到主要内容

如何选择合适的索引类型

选择合适的Faiss索引并不简单,下面列出了一些关键问题,帮助你选择最适合的数据结构。本指南主要针对L2距离(欧氏距离)为主的应用场景。

  • 每种索引结构都给出index_factory字符串表示法。
  • 如有参数,给出对应的ParameterSpace参数。

页面底部提供了一个简明决策树。


你是否仅进行少量查询?

如果你计划仅进行少量查询(例如 1000~10000 次),那么索引建立的性能优势不会体现出来。直接计算会更加高效。

这个功能通过 "Flat" 索引实现。如果整个数据集无法一次性加载进内存(RAM),可以分批构建多个小索引,然后合并搜索结果。关于如何合并结果,请参考合并多个搜索结果


你是否需要精确搜索结果

如果需要:"Flat"

唯一能保证完全精确结果的索引是 IndexFlatL2IndexFlatIP(IP 指点积即内积,常用于余弦相似度)。这两种索引为其他索引方法提供了对照基线。Flat 索引不对向量数据做压缩,也不会增加额外开销。

  • 这种类型不支持带 ID 增加(add_with_ids),只支持顺序添加。如果有必要使用 add_with_ids,请选择 "IDMap,Flat"
  • Flat 索引无需训练,也没有参数需要设置。

Supported on GPU: 支持


内存(RAM)是否是一个重要限制?

请注意,Faiss 所有索引都存放在内存中。以下讨论在不需要完全精确结果时,如果内存成为主要约束条件,如何在精度和速度之间做权衡。

如果内存不是限制HNSW_MIVF1024,PQ_Nx4fs,RFlat

  • 如果有大量内存或数据集很小,HNSW(分层近邻小世界图,Hierarchical Navigable Small World)是最佳选择,速度快且精度高。参数 M 表示每个向量的链接数,推荐范围4到64,值越大精度越高但内存消耗也增加。速度和精度的权衡通过efSearch设置。内存使用量约为 d×4+M×2×4d \times 4 + M \times 2 \times 4 字节/向量(dd为向量维度)。
  • HNSW 仅支持顺序插入,不支持add_with_ids,如有需求需加前缀IDMap。无需训练,也不支持向量删除。
  • 另一个选择是 IVF1024,PQ_Nx4fs,RFlat,较快但需两步检索:先用 IVF 粗搜索,再重排,涉及k_factor(重排行数)和nprobe(搜索的簇数量)两个参数。

Supported on GPU: 不支持


如果有限制,则选择 "...,Flat"

  • "..."表示数据集需要先聚类(后文会介绍)。
  • 聚类后,"Flat"只是将向量分桶存储,并未压缩数据,存储空间与原数据相当。
  • 速度和精度权衡通过参数nprobe控制。

Supported on GPU: 支持(聚类方法也须被GPU支持)


如果内存限制较大,选择 OPQ_M_D,...,PQ_Mx4fsr

  • 若存储完整向量开销过大,可用OPQ(正交分组量化,Optimized Product Quantization)和PQ(产品量化,Product Quantization)组合。
  • OPQ先将原始向量降维到 DD,再用 PQ 将向量编码为 MM 个4位码,总存储量为 M/2M/2 字节/向量。

Supported on GPU: 支持


如果极度受限,选择 OPQ_M_D,...,PQ_M

  • PQ 通常将向量压缩为 MM 字节,通常 M64M \le 64。如需更大编码长度可用 SQ(标量量化,Scalar Quantization)。
  • OPQ 用于提前线性转换,便于更好压缩,DD 必须是 MM 的整数倍,且 DdD \le d(最好),建议 D=4MD = 4M
  • OPQ 只在 CPU 上完成,但性能影响极小。

Supported on GPU: 支持


数据集有多大?

数据规模会影响聚类方案(即上文 "..." 部分),数据将被划分为多个桶,检索时只访问少量桶(由nprobe控制)。聚类时建议用数据集的代表性样本进行训练。

若数据量低于 1 百万...,IVF_K,...

K 推荐区间为 4N4 \sqrt{N}16N16 \sqrt{N}NN为向量数量。一般用k-means聚类。训练样本为 30×K30 \times K256×K256 \times K(越多越好)。

Supported on GPU: 支持


若数据量 1M ~ 10M...,IVF65536_HNSW32,...

IVF 与 HNSW 结合,使用 HNSW 进行簇分配。训练样本为 30×6553630 \times 65536256×65536256 \times 65536

Supported on GPU: 不支持(GPU请用上一种IVF方法)


若数据量 10M ~ 100M...,IVF262144_HNSW32,...

同上,只是簇数提升为 262144(2182^{18})。训练会很慢,可以:


若数据量 1亿~10亿...,IVF1048576_HNSW32,...

同理,簇数为 1048576(2202^{20})。训练更慢!


Faiss索引决策树
提示
  • 在实际选择过程中,建议结合你的内存使用、检索精度、处理速度和数据量等需求进行综合权衡。
  • 针对不同的数据集和场景,可以多次测试,选择最合适的索引结构。