内存索引
本主题列出了 Milvus 支持的各种内存索引类型、每种索引最适合的场景,以及用户可以配置的参数以获得更好的搜索性能。有关磁盘索引,请参阅 磁盘索引。
索引是高效组织数据的过程,通过大幅加快大型数据集上耗时查询的速度,在使相似性搜索变得有用方面发挥着重要作用。
为了提高查询性能,您可以为每个向量字段指定索引类型。
目前,一个向量字段只支持一种索引类型。当切换索引类型时,Milvus 会自动删除旧的索引。
ANNS 向量索引
Milvus 支持的大多数向量索引类型都使用近似最近邻搜索(ANNS)算法。与通常非常耗时的精确检索相比,ANNS 的核心思想不再局限于返回最准确的结果,而只是搜索目标的邻居。ANNS 通过在可接受范围内牺牲准确性来提高检索效率。
根据实现方法,ANNS 向量索引可以分为四种类型:基于树的、基于图的、基于哈希的和基于量化的。
Milvus 中支持的索引
浮点数 embedding 索引
对于 128 维浮点数 embedding(向量),它们占用的存储空间为 128 * float 的大小 = 512 字节。用于浮点数 embedding 的距离度量是欧几里得距离(L2
)和内积(IP
)。
这些索引类型包括用于基于 CPU 的 ANN 搜索的 FLAT
、IVF_FLAT
、IVF_PQ
、IVF_SQ8
、HNSW
、HNSW_SQ
、HNSW_PQ
、HNSW_PRQ
和 SCANN
。
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
不返回任何搜索结果的桶的最大数量。 \n这是一个范围搜索参数,当连续空桶的数量达到指定值时终止搜索过程。 \n增加此值可以提高召回率,但会增加搜索时间。 [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 字节)。这将磁盘、CPU 和 GPU 内存消耗减少了 70-75%。对于 1B SIFT 数据集,IVF_SQ8 索引文件只需要 140 GB 的存储空间。
-
索引构建参数
参数 描述 范围 nlist
集群单元数量 [1, 65536] -
搜索参数
常规搜索
参数 描述 范围 默认值 nprobe
要查询的单元数量 [1, nlist] 8 范围搜索
参数 描述 范围 默认值 max_empty_result_buckets
不返回任何搜索结果的桶的最大数量。 \n这是一个范围搜索参数,当连续空桶的数量达到指定值时终止搜索过程。 \n增加此值可以提高召回率,但会增加搜索时间。 [1, 65535] 2
IVF_PQ
PQ
(Product Quantization)将原始高维向量空间均匀分解为 m
个低维向量空间的笛卡尔积,然后量化分解的低维向量空间。产品量化不是计算目标向量与所有单元中心之间的距离,而是计算目标向量与每个低维空间的聚类中心之间的距离,大大降低了算法的时间复杂度和空间复杂度。
IVF_PQ 在量化向量的乘积之前执行 IVF 索引聚类。其索引文件甚至比 IVF_SQ8 还要小,但在搜索向量时也会造成准确性损失。
索引构建参数和搜索参数因 Milvus 分发版本而异。请先选择您的 Milvus 分发版本。
-
索引构建参数
参数 描述 范围 nlist
集群单元数量 [1, 65536] m
产品量化的因子数量 dim mod m == 0
nbits
[可选] 每个低维向量存储的位数 [1, 64](默认为 8) -
搜索参数
常规搜索
参数 描述 范围 默认值 nprobe
要查询的单元数量 [1, nlist] 8 范围搜索
参数 描述 范围 默认值 max_empty_result_buckets
不返回任何搜索结果的桶的最大数量。 \n这是一个范围搜索参数,当连续空桶的数量达到指定值时终止搜索过程。 \n增加此值可以提高召回率,但会增加搜索时间。 [1, 65535] 2
SCANN
ScaNN(Scalable Nearest Neighbors)在向量聚类和产品量化方面与 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
不返回任何搜索结果的桶的最大数量。 \n这是一个范围搜索参数,当连续空桶的数量达到指定值时终止搜索过程。 \n增加此值可以提高召回率,但会增加搜索时间。 [1, 65535] 2
HNSW
HNSW(Hierarchical Navigable Small World Graph)是一种基于图的索引算法。它根据一定规则为图像构建多层导航结构。在这种结构中,上层更稀疏,节点之间的距离更远;下层更密集,节点之间的距离更近。搜索从最上层开始,在该层找到最接近目标的节点,然后进入下一层开始另一次搜索。经过多次迭代,可以快速接近目标位置。
为了提高性能,HNSW 将图的每一层上节点的最大度数限制为 M
。此外,您可以使用 efConstruction
(构建索引时)或 ef
(搜索目标时)来指定搜索范围。
-
索引构建参数
参数 描述 范围 默认值 M
M 定义图中最大出度连接数。更高的 M 在固定 ef/efConstruction 时导致更高的准确性/运行时间。 [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 定义图中最大出度连接数。更高的 M 在固定 ef/efConstruction 时导致更高的准确性/运行时间。 [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
相对于 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 定义图中最大出度连接数。更高的 M 在固定 ef/efConstruction 时导致更高的准确性/运行时间。 [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
相对于 k 的精炼放大因子。 [1, float_max) 1
HNSW_PRQ
PRQ 与 PQ 类似,也将向量分为 m
组。每个子向量将被编码为 nbits
。完成 pq 量化后,它将计算向量与 pq 量化向量之间的残差,并对残差向量应用 pq 量化。总共将执行 nrq
次完整的 pq 量化,因此长度为 dim
的浮点向量将被编码为 m * nbits * nrq 位。
结合产品残差量化器(PRQ),HNSW_PRQ 提供了索引大小和准确性之间更高的可控权衡。对于相同的压缩率,它的 QPS 值几乎等同于 HNSW_PQ,召回率更高。与 HNSW_PQ 相比,构建索引的时间可能会增加几倍。
-
索引构建参数
参数 描述 范围 默认值 M
M 定义图中最大出度连接数。更高的 M 在固定 ef/efConstruction 时导致更高的准确性/运行时间。 [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
相对于 k 的精炼放大因子。 [1, float_max) 1
支持的索引 | 分类 | 场景 |
---|---|---|
FLAT | N/A | - 相对较小的数据集 \n- 需要 100% 召回率 |
IVF_FLAT | N/A | - 高速查询 \n- 需要尽可能高的召回率 |
IVF_SQ8 | 基于量化的索引 | - 非常高速的查询 \n- 内存资源有限 \n- 接受召回率的轻微妥协 |
IVF_PQ | 基于量化的索引 | - 高速查询 \n- 内存资源有限 \n- 接受召回率的轻微妥协 |
HNSW | 基于图的索引 | - 非常高速的查询 \n- 需要尽可能高的召回率 \n- 大内存资源 |
HNSW_SQ | 基于量化的索引 | - 非常高速的查询 \n- 内存资源有限 \n- 接受召回率的轻微妥协 |
HNSW_PQ | 基于量化的索引 | - 中等速度查询 \n- 内存资源非常有限 \n- 接受召回率的轻微妥协 |
HNSW_PRQ | 基于量化的索引 | - 中等速度查询 \n- 内存资源非常有限 \n- 接受召回率的轻微妥协 |
SCANN | 基于量化的索引 | - 非常高速的查询 \n- 需要尽可能高的召回率 \n- 大内存资源 |
二进制 embedding 索引
对于 128 维二进制 embedding,它们占用的存储空间为 128 / 8 = 16 字节。用于二进制 embedding 的距离度量是 JACCARD
和 HAMMING
。
这种索引类型包括 BIN_FLAT
和 BIN_IVF_FLAT
。
支持的索引 | 分类 | 场景 |
---|---|---|
BIN_FLAT | 基于量化的索引 | - 依赖相对较小的数据集。 \n- 需要完美的准确性。 \n- 不应用压缩。 \n- 保证精确的搜索结果。 |
BIN_IVF_FLAT | 基于量化的索引 | - 高速查询 \n- 需要尽可能高的召回率 |
BIN_FLAT
此索引与 FLAT 完全相同,只是它只能用于二进制 embedding。
对于需要完美准确性并依赖相对较小(百万级)数据集的向量相似性搜索应用程序,BIN_FLAT 索引是一个不错的选择。BIN_FLAT 不压缩向量,是唯一能够保证精确搜索结果的索引。BIN_FLAT 的结果也可以用作与召回率低于 100% 的其他索引产生的结果进行比较的参考点。
BIN_FLAT 是准确的,因为它采用穷举搜索方法,这意味着对于每个查询,目标输入都与数据集中的向量进行比较。这使得 BIN_FLAT 成为我们列表中最慢的索引,不适合查询大量向量数据。Milvus 中的 BIN_FLAT 索引没有参数,使用它不需要数据训练或额外存储。
-
搜索参数
参数 描述 范围 metric_type
[可选] 选择的距离度量 参见 支持的度量。
BIN_IVF_FLAT
此索引与 IVF_FLAT 完全相同,只是它只能用于二进制 embedding。
BIN_IVF_FLAT 将向量数据分为 nlist
个集群单元,然后比较目标输入向量与每个集群中心之间的距离。根据系统设置查询的集群数量(nprobe
),相似性搜索结果仅基于目标输入与最相似集群中向量之间的比较返回——大大减少了查询时间。
通过调整 nprobe
,可以为给定场景找到准确性和速度之间的理想平衡。随着目标输入向量数量(nq
)和要搜索的集群数量(nprobe
)的增加,查询时间急剧增加。
BIN_IVF_FLAT 是最基本的 BIN_IVF 索引,每个单元中存储的编码数据与原始数据一致。
-
索引构建参数
参数 描述 范围 nlist
集群单元数量 [1, 65536] -
搜索参数
参数 描述 范围 默认值 nprobe
要查询的单元数量 [1, nlist] 8 max_empty_result_buckets
不返回任何搜索结果的桶的最大数量。 \n这是一个范围搜索参数,当连续空桶的数量达到指定值时终止搜索过程。 \n增加此值可以提高召回率,但会增加搜索时间。 [1, 65535] 2
sparse embedding 索引
sparse embedding 索引仅支持 IP
和 BM25
(用于全文搜索)度量。
sparse embedding 支持的索引类型:SPARSE_INVERTED_INDEX
。
从 Milvus 2.5.4 开始,SPARSE_WAND
正在被弃用。建议使用 "inverted_index_algo": "DAAT_WAND"
来实现等效性,同时保持兼容性。有关更多信息,请参阅 Sparse Vector。
支持的索引 | 分类 | 场景 |
---|---|---|
SPARSE_INVERTED_INDEX | 倒排索引 | - 依赖相对较小的数据集。 \n- 需要 100% 召回率。 |
SPARSE_INVERTED_INDEX
每个维度维护一个在该维度具有非零值的向量列表。在搜索期间,Milvus 遍历查询向量的每个维度,并计算在这些维度中具有非零值的向量的分数。
-
索引构建参数
参数 描述 范围 inverted_index_algo
用于构建和查询索引的算法。详情请参阅 Sparse Vector。 DAAT_MAXSCORE
(默认)、DAAT_WAND
、TAAT_NAIVE
bm25_k1
控制词频饱和度。较高的值增加词频在文档排名中的重要性。 [1.2, 2.0] bm25_b
控制文档长度归一化的程度。默认为 0.75。 [0, 1] 备注自 Milvus v2.5.4 起,
drop_ratio_build
参数已被弃用,在索引构建期间仍可接受,但不再对索引产生实际影响。 -
搜索参数
参数 描述 范围 drop_ratio_search
在搜索过程中排除的小向量值的比例。此选项允许通过指定要忽略的查询向量中最小值的比例来微调搜索过程。 [0, 1]
FAQ
FLAT 索引和 IVF_FLAT 索引有什么区别?
IVF_FLAT 索引将向量空间分为 nlist
个集群。如果您保持 nlist
的默认值为 16384,Milvus 比较目标向量与所有 16384 个集群中心的距离,以获得 nprobe
个最近的集群。然后 Milvus 比较目标向量与所选集群中向量的距离,以获得最近的向量。与 IVF_FLAT 不同,FLAT 直接比较目标向量与每个向量的距离。
因此,当向量总数大约等于 nlist
时,IVF_FLAT 和 FLAT 在所需的计算方式和搜索性能方面差别不大。但是随着向量数量增长到 nlist
的两倍、三倍或 n 倍,IVF_FLAT 索引开始显示出越来越大的优势。
更多信息请参见 如何在 Milvus 中选择索引。
下一步
- 了解更多 Milvus 支持的相似性度量。