内存索引
本主题列出了 Milvus 支持的各种类型的内存索引,每种索引最适合的场景,以及用户可以配置的参数,以实现更好的搜索性能。有关磁盘索引,请参阅 磁盘索引。
索引是有效组织数据的过程,它通过显著加快大型数据集上耗时查询的速度,在提高相似性搜索的实用性方面发挥着重要作用。
为了提高查询性能,可以为每个向量字段 指定一种索引类型。
目前,一个向量字段只支持一种索引类型。切换索引类型时,Milvus 会自动删除旧索引。
ANNS 向量索引
Milvus 支持的大多数向量索引类型都使用近似近邻检索(ANNS)算法。与通常非常耗时的精确检索相比,ANNS 的核心理念不再局限于返回最精确的结果,而是只搜索目标的近邻。ANNS 通过在可接受的范围内牺牲精确度来提高检索效率。
根据实现方法,ANNS 向量索引可分为四种类型:基于树、基于图、基于哈希和基于量化。
Milvus 支持的索引
Milvus 支持多种索引类型,这些类型按其处理的 Embedding 类型分为:浮点嵌入 (也称浮点向量或稠密向量)、二进制嵌入 (也称二进制向量)和 稀疏嵌入 (也称稀疏向量)。
浮点嵌入的索引
对于 128 维浮点嵌入(向量),其占用的存储空间为 128 * float 的大小 = 512 字节。而用于浮点嵌入的 距离度量 是欧氏距离(L2)和内积(IP)。
这些类型的索引包括 FLAT,IVF_FLAT,IVF_PQ,IVF_SQ8,HNSW,HNSW_SQ,HNSW_PQ,HNSW_PRQ 和 SCANN,用于基于 CPU 的 ANN 搜索。
二进制嵌入索引
对于 128 维的二进制嵌入,其占用的存储空间为 128 / 8 = 16 字节。而用于二进制嵌入的距离度量是 JACCARD 和 HAMMING。
这类索引包括 BIN_FLAT 和 BIN_IVF_FLAT。
稀疏嵌入式索引
稀疏嵌入式索引仅支持 IP 和 BM25 (用于全文搜索)度量。
稀疏嵌入式支持的索引类型:SPARSE_INVERTED_INDEX。
从 Milvus 2.5.4 起,SPARSE_WAND 已被弃用。建议在保持兼容性的同时,使用 "inverted_index_algo": "DAAT_WAND" 作为等价索引。更多信息,请参阅 稀疏向量。
| 支持的索引 | 分类 | 场景 |
|---|---|---|
| FLAT | N/A |
|
| IVF_FLAT | N/A |
|
| IVF_SQ8 | 基于量化的索引 |
|
| IVF_PQ | 基于量化的索引 |
|
| HNSW | 基于图形的索引 |
|
| HNSW_SQ | 基于量化的索引 |
|
| HNSW_PQ | 基于量化的索引 |
|
| HNSW_PRQ | 基于量化的索引 |
|
| SCANN | 基于量化的索引 |
|
| 支持的索引 | 分类 | 场景 |
|---|---|---|
| BIN_FLAT | 基于量化的索引 |
|
| BIN_IVF_FLAT | 基于量化的索引 |
|
| 支持的索引 | 分类 | 方案 |
|---|---|---|
| SPARSE_INVERTED_INDEX | 倒排索引 |
|
FLAT
对于需要完美精确度且依赖相对较小(百万级别)数据集的向量相似性搜索应用,FLAT 索引是一个不错的选择。FLAT 不压缩向量,是唯一能保证精确搜索结果的索引。FLAT 的结果还可以作为其他召回率低于 100% 的索引所产生结果的比较点。
FLAT 的精确度很高,因为它采用的是穷举搜索方法,这意味着每次查询都要将目标输入与数据集中的每一组向量进行比较。这使得 FLAT 成为我们列表中速度最慢的索引,而且不适合查询海量向量数据。在 Milvus 中,FLAT 索引不需要任何参数,使用它也不需要额外建立索引。
- 搜索参数
| 参数 | 描述 | 范围 |
|---|---|---|
metric_type | [可选] 选择的距离度量。 | 请参阅支持的度量。 |
IVF_FLAT
IVF_FLAT 将向量数据划分为 nlist 个聚类单元,然后比较目标输入向量与每个聚类中心之间的距离。根据系统设置查询的簇数 (nprobe),相似性搜索结果仅根据目标输入与最相似簇中向量的比较结果返回--大大缩短了查询时间。
通过调整 nprobe,可以在特定情况下找到准确性和速度之间的理想平衡。IVF_FLAT 性能测试 的结果表明,随着目标输入向量数 (nq) 和搜索簇数 (nprobe) 的增加,查询时间也会急剧增加。
IVF_FLAT 是最基本的 IVF 索引,每个单元中存储的编码数据与原始数据一致。
- 索引构建参数
| 参数 | 说明 | 范围 | 默认值 |
|---|---|---|---|
nlist | 簇单元数 | [1, 65536] | 128 |
-
搜索参数
-
普通搜索
| 参数 | 说明 | 范围 | 默认值 |
|---|---|---|---|
nprobe | 要查询的单位数 | [1,nlist] | 8 |
- 范围搜索
| 参数 | 说明 | 范围 | 默认值 |
|---|---|---|---|
max_empty_result_buckets | 未返回任何搜索结果的桶的最大数量。 这是一个范围搜索参数,当连续空桶的数量达到指定值时,将终止搜索过程。 增加该值可以提高召回率,但代价是增加搜索时间。 | [1, 65535] | 2 |
IVF_SQ8
IVF_FLAT 不进行任何压缩,因此它生成的索引文件大小与原始的非索引向量数据大致相同。例如,如果原始的 1B SIFT 数据集为 476 GB,那么其 IVF_FLAT 索引文件就会稍小一些(~470 GB)。将所有索引文件加载到内存中将消耗 470 GB 的存储空间。
当磁盘、CPU 或 GPU 内存资源有限时,IVF_SQ8 是比 IVF_FLAT 更好的选择。这种索引类型可以通过执行标量量化(SQ)将每个 FLOAT(4 字节)转换为 UINT8(1 字节)。这样可以减少 70-75% 的磁盘、CPU 和 GPU 内存消耗。对于 1B SIFT 数据集,IVF_SQ8 索引文件仅需 140 GB 的存储空间。
- 索引构建参数
| 参数 | 说明 | 范围 |
|---|---|---|
nlist | 集群单位数 | [1, 65536] |
-
搜索参数
-
普通搜索
| 参数 | 说明 | 范围 | 默认值 |
|---|---|---|---|
nprobe | 要查询的单位数 | [1,nlist] | 8 |
- 范围搜索
| 参数 | 说明 | 范围 | 默认值 |
|---|---|---|---|
max_empty_result_buckets | 未返回任何搜索结果的桶的最大数量。 这是一个范围搜索参数,当连续空桶的数量达到指定值时,将终止搜索过程。 增加该值可以提高召回率,但代价是增加搜索时间。 | [1, 65535] | 2 |
IVF_PQ
PQ (乘积量化)将原始高维向量空间均匀分解为 低维向量空间的笛卡尔乘积,然后对分解后的低维向量空间进行量化。乘积量化不需要计算目标向量与所有单元中心的距离,而是能够计算目标向量与每个低维空间聚类中心的距离,大大降低了算法的时间复杂度和空间复杂度。m
IVF_PQ 先进行 IVF 索引聚类,然后再对向量的乘积进行量化。其索引文件比 IVF_SQ8 更小,但在搜索向量时也会造成精度损失。
索引建立参数和搜索参数随 Milvus Distributed 分布而异。请先选择 Milvus Distributed。
- 索引建立参数
| 参数 | 说明 | 范围 |
|---|---|---|
nlist | 集群单位数 | [1, 65536] |
m | 乘积量化因子数 | dim mod m == 0 |
nbits | [可选项] 每个低维向量的存储位数。 | [1,64] (默认为 8) |
-
搜索参数
-
普通搜索
| 参数 | 说明 | 范围 | 默认值 |
|---|---|---|---|
nprobe | 要查询的单位数 | [1,nlist] | 8 |
- 范围搜索
| 参数 | 说明 | 范围 | 默认值 |
|---|---|---|---|
max_empty_result_buckets | 未返回任何搜索结果的桶的最大数量。 这是一个范围搜索参数,当连续空桶的数量达到指定值时,将终止搜索过程。 增加该值可以提高召回率,但代价是增加搜索时间。 | [1, 65535] | 2 |
SCANN
ScaNN(可扩展近邻)在向量聚类和乘积量化方面与 IVF_PQ 相似。它们的不同之处在于乘积量化的实现细节和使用 SIMD(单指令/多数据)进行高效计算。
- 索引构建参数
| 参数 | 说明 | 范围 |
|---|---|---|
nlist | 集群单位数 | [1, 65536] |
with_raw_data | 是否在索引中包含原始数据 | True 或 False,默认为 True。 |
与 IVF_PQ 不同,默认值适用于 m 和 nbits,以优化性能。
-
搜索参数
-
常用搜索
| 参数 | 说明 | 范围 | 默认值 |
|---|---|---|---|
nprobe | 要查询的单位数 | [1,nlist] | |
reorder_k | 要查询的候选单位数量 | [top_k, ∞] | top_k |
- 范围搜索
| 参数 | 说明 | 范围 | 默认值 |
|---|---|---|---|
max_empty_result_buckets | 未返回任何搜索结果的桶的最大数量。 这是一个范围搜索参数,当连续空桶的数量达到指定值时,将终止搜索过程。 增加该值可以提高召回率,但代价是增加搜索时间。 | [1, 65535] | 2 |
HNSW
HNSW(分层导航小世界图)是一种基于图的索引算法。它根据一定规则为向量数据构建多层导航结构。在这种结构中,上层较为稀疏,节点之间的距离较远;下层较为密集,节点之间的距离较近。搜索从最上层开始,在这一层找到离目标最近的节点,然后进入下一层开始新的搜索。经过多次迭代后,就能快速接近目标位置。
为了提高性能,HNSW 将图中每层节点的最大度数限制为 M。此外,您还可以使用 efConstruction (建立索引时)或 ef (搜索目标时)来指定搜索范围。
- 索引建立参数
| 参数 | 说明 | 范围 | 默认值 |
|---|---|---|---|
M | M 定义图形中传出连接的最大数量。在固定 ef/efConstruction 条件下,M 越大,精度/运行时间越长。 | [2, 2048] | None |
efConstruction | ef_construction 控制索引搜索速度/构建速度的权衡。增加 efConstruction 参数可能会提高索引质量,但也会延长索引编制时间。 | [1, int_max](最大值) | None |
- 搜索参数
| 参数 | 说明 | 范围 | 默认值 |
|---|---|---|---|
ef | 控制查询时间/准确性权衡的参数。ef 越高,搜索越准确,但速度越慢。 | [top_k, int_max] | None |
HNSW_SQ
标量量化(SQ)是一种根据浮点数据的大小将其离散化为一组有限数值的技术。例如,SQ6 表示量化为 (2^6 = 64) 个离散值,其中每个浮点数使用 6 位编码。同样 ,SQ8 将数据量化为 (2^8 = 256) 个离散值,每个浮点数用 8 位表示。这种量化方法既减少了内存占用,又保留了数据的基本结构,从而提高了处理效率。
结合 SQ,HNSW_SQ 可以在索引大小和精确度之间进行可控的权衡,同时保持较高的每秒查询次数(QPS)性能。与标准 HNSW 相比,它只会适度增加索引构建时间。
- 索引构建参数
| 参数 | 说明 | 范围 | 默认值 |
|---|---|---|---|
M | M 定义图形中传出连接的最大数量。在固定 ef/efConstruction 条件下,M 越大,精度/运行时间越长。 | [2, 2048] | None |
efConstruction | ef_construction 控制索引搜索速度/构建速度的权衡。增加 efConstruction 参数可能会提高索引质量,但也会延长索引编制时间。 | [1, int_max](最大值) | None |
sq_type | 标量量化器类型。 | SQ6,SQ8,BF16、FP16 | SQ8 |
refine | 建立索引时是否保留精炼数据。 | true,false | false |
refine_type | 细化索引的数据类型。 | SQ6,SQ8,BF16,FP16、FP32 | None |
- 搜索参数
| 参数 | 说明 | 范围 | 默认值 |
|---|---|---|---|
ef | 控制查询时间/准确性权衡的参数。ef 越高,搜索越准确,但速度越慢。 | [top_k, int_max] | None |
refine_k | refine 相对于k 的放大系数。 | [1,float_max) | 1 |
HNSW_PQ
PQ 的基本思想是将向量分割成 m 个子向量,每个子向量将根据 kmeans 找到2^{nbits} 个中心点,每个子向量将选择最近的中心点作为其近似子向量。然后我们记录所有的中心点,因此每个子向量可以编码为 nbits,长度为 dim 的浮点向量可以编码为m ⋅ nbits位。
与 PQ 相结合,HNSW_PQ 可以在索引大小和准确性之间进行可控的权衡,但在相同的压缩率下,它的 QPS 值和召回率都比 HNSW_SQ 低。与 HNSW_SQ 相比,它建立索引的时间更长。
- 索引建立参数
| 参数 | 说明 | 范围 | 默认值 |
|---|---|---|---|
M | M 定义图形中传出连接的最大数量。在固定 ef/efConstruction 条件下,M 越大,精度/运行时间越长。 | [2, 2048] | None |
efConstruction | ef_construction 控制索引搜索速度/构建速度的权衡。增加 efConstruction 参数可能会提高索引质量,但也会延长索引编制时间。 | [1, int_max](最大值) | None |
m | 将向量分割成的子向量组的个数。 | [1, 65536] | 32 |
nbits | 每个子向量组量化成的比特数。 | [1, 24] | 8 |
refine | 建立索引时是否保留精炼数据。 | true,false | false |
refine_type | 细化索引的数据类型。 | SQ6,SQ8,BF16,FP16、FP32 | None |
- 搜索参数
| 参数 | 说明 | 范围 | 默认值 |
|---|---|---|---|
ef | 控制查询时间/准确性权衡的参数。ef 越高,搜索越准确,但速度越慢。 | [top_k, int_max] | None |
refine_k | refine 相对于k 的放大系数。 | [1,float_max) | 1 |
HNSW_PRQ
PRQ 与 PQ 类似,也是将向量分为 m 组。每个子向量将被编码为 nbits。完成 pq 量化后,它会计算向量与 pq 量化向量之间的残差,并对残差向量应用 pq 量化。总共将进行 nrq 次完整的 pq 量化,因此长度为 dim 的浮点向量将被编码为m ⋅ nbits ⋅ nrqbits。
HNSW_PRQ 与乘积残差量化器(PRQ)相结合,在索引大小和精确度之间提供了更高的可控权衡。与 HNSW_PQ 相比,在相同的压缩率下,HNSW_PRQ 的 QPS 值和召回率几乎相当。与 HNSW_PQ 相比,建立索引的时间可能会增加数倍。
- 索引建立参数
| 参数 | 说明 | 范围 | 默认值 |
|---|---|---|---|
M | M 定义图形中传出连接的最大数量。在固定 ef/efConstruction 条件下,M 越大,精度/运行时间越长。 | [2, 2048] | None |
efConstruction | ef_construction 控制索引搜索速度/构建速度的权衡。增加 efConstruction 参数可能会提高索引质量,但也会延长索引编制时间。 | [1, int_max](最大值) | None |
m | 将向量分割成的子向量组的个数。 | [1, 65536] | 32 |
nbits | 每个子向量组量化成的比特数。 | [1, 24] | 8 |
nrq | 残差子量化器的个数。 | [1, 16] | 2 |
refine | 建立索引时是否保留细化数据。 | true,false | false |
refine_type | 细化索引的数据类型。 | SQ6,SQ8,BF16,FP16、FP32 | None |
- 搜索参数
| 参数 | 说明 | 范围 | 默认值 |
|---|---|---|---|
ef | 控制查询时间/准确性权衡的参数。ef 越高,搜索越准确,但速度越慢。 | [top_k, int_max] | None |
refine_k | refine 相对于k 的放大系数。 | [1,float_max) | 1 |
BIN_FLAT
该索引与 FLAT 完全相同,只是只能用于二进制嵌入。
对于需要完美精确度并依赖于相对较小(百万级别)数据集的向量相似性搜索应用,BIN_FLAT 索引是一个不错的选择。BIN_FLAT 不压缩向量,是唯一能保证精确搜索结果的索引。BIN_FLAT 的结果还可以作为其他召回率低于 100% 的索引所产生结果的比较点。
BIN_FLAT 之所以准确,是因为它采用了穷举搜索方法,这意味着每次查询都要将目标输入与数据集中的向量进行比较。这使得 BIN_FLAT 成为我们列表中速度最慢的索引,不适合查询海量向量数据。Milvus 中的 BIN_FLAT 索引没有参数,使用它不需要数据训练或额外存储。
- 搜索参数
| 参数 | 描述 | 范围 |
|---|---|---|
metric_type | [可选] 选择的距离度量。 | 请参阅支持的度量。 |
BIN_IVF_FLAT
该指标与 IVF_FLAT 完全相同,只是只能用于二进制嵌入。
BIN_IVF_FLAT 将向量数据划分为 nlist 个聚类单元,然后比较目标输入向量与每个聚类中心之间的距离。根据系统设置查询的簇数(nprobe),相似性搜索结果仅根据目标输入与最相似簇中向量的比较结果返回--大大缩短了查询时间。
通过调整 nprobe,可以在特定情况下找到准确性和速度之间的理想平衡。随着目标输入向量数 (nq) 和要搜索的聚类数 (nprobe) 的增加,查询时间也会急剧增加。
BIN_IVF_FLAT 是最基本的 BIN_IVF 索引,每个单元存储的编码数据与原始数据一致。
- 索引建立参数
| 参数 | 说明 | 范围 |
|---|---|---|
nlist | 簇单元数 | [1, 65536] |
-
搜索参数
-
普通搜索
| 参数 | 说明 | 范围 | 默认值 |
|---|---|---|---|
nprobe | 要查询的单位数 | [1,nlist] | 8 |
- 范围搜索
| 参数 | 说明 | 范围 | 默认值 |
|---|---|---|---|
max_empty_result_buckets | 未返回任何搜索结果的桶的最大数量。 这是一个范围搜索参数,当连续空桶的数量达到指定值时,将终止搜索过程。 增加该值可以提高召回率,但代价是增加搜索时间。 | [1, 65535] | 2 |
SPARSE_INVERTED_INDEX
每个维度都会维护一个在该维度上具有非零值的向量列表。在搜索过程中,Milvus 会遍历查询向量的每个维度,并为在这些维度上具有非零值的向量计算分数。
- 索引构建参数
| 参数 | 说明 | 范围 |
|---|---|---|
inverted_index_algo | 用于建立和查询索引的算法。详情请参阅稀疏向量。 | DAAT_MAXSCORE (默认), 、DAAT_WAND TAAT_NAIVE |
bm25_k1 | 控制词频饱和度。数值越大,术语频率在文档排序中的重要性越高。 | [1.2, 2.0] |
bm25_b | 控制文档长度标准化的程度。默认为 0.75。 | [0, 1] |
drop_ratio_build 参数自 Milvus v2.5.4 起已被弃用,在索引构建过程中仍可接受,但将不再对索引产生实际影响。
- 搜索参数
| 参数 | 说明 | 范围 |
|---|---|---|
drop_ratio_search | 在搜索过程中排除的小向量值的比例。该选项可通过指定忽略查询向量中最小值的比例,对搜索过程进行微调。它有助于平衡搜索精度和性能。drop_ratio_search 的值越小,这些小值对最终得分的贡献就越小。通过忽略一些小值,可以提高搜索性能,同时将对精确度的影响降到最低。 | [0, 1] |
常见问题
FLAT 索引和 IVF_FLAT 索引有什么区别?
IVF_FLAT 索引将向量空间划分为 nlist 个簇。如果保持 nlist 的默认值为 16384,Milvus 会比较目标向量与所有 16384 个簇的中心点之间的距离,得到 nprobe 最近的簇。然后,Milvus 再比较目标向量与所选簇中向量之间的距离,得到最近的向量。与 IVF_FLAT 不同,FLAT 直接比较目标向量与每一个向量之间的距离。
因此,当向量总数约等于 nlist 时,IVF_FLAT 和 FLAT 所需的计算方式和搜索性能差别不大。但当向量数增长到 nlist 的 2 倍、3 倍或 n 倍时,IVF_FLAT 索引开始显示出越来越大的优势。
更多信息,请参阅 如何在 Milvus 中选择索引。
下一步
- 进一步了解 Milvus 支持的 相似度指标。