以下内容是自己在学习Milvus向量数据库时,在Milvus官方网站文档库中对索引的学习整理和翻译,通过自己和借助翻译软件进行了理解整合翻译,有可能有一些地方理解整理的不到位,还望大家理解。
一、内存中索引
本文列出了 Milvus 支持的各种类型的内存索引、每种索引最适合的场景,以及用户可以配置以实现更好的搜索性能的参数。有关磁盘上的索引,请参阅**磁盘上的索引** 。
索引是有效组织数据的过程,它通过显着加速对大型数据集的耗时查询,在使相似性搜索变得有用方面发挥着重要作用。
为了提高查询性能,您可以为每个向量字段指定索引类型。
注:
目前,向量字段仅支持一种索引类型。Milvus在切换索引类型时会自动删除旧索引。
二、ANNS向量索引
Milvus 支持的大多数向量索引类型都使用近似最近邻搜索(ANNS)算法。相较于通常非常耗时的精确检索,ANNS的核心思想不再局限于返回最准确的结果,而只搜索目标的邻居。ANNS通过在可接受的范围内牺牲精度来提高检索效率。
根据实现方法,ANNS向量指数可分为四类:
- 基于树的索引
- 基于图形的索引
- 基于哈希的索引
- 基于量化的指数
内容扩充,有关ANNS向量索引的介绍,可以参考以下链接进行查看学习:
https://cnblogs.com/guohaiwen/p/15394595.html
三、Milvus支持的索引
根据适合的数据类型,Milvus 中支持的索引可以分为两类:
浮点嵌入的索引:
对于 128 维浮点嵌入,它们占用的存储空间为 128 * float 的大小 = 512 字节。用于浮点嵌入的距离度量是欧几里得距离 (L2) 和内积。
这些类型的索引包括用于基于 CPU 的 ANN 搜索的 FLAT、IVF_FLAT、IVF_PQ、IVF_SQ8、HNSW 和 SCANN(beta),以及用于基于 GPU 的 ANN 搜索的 GPU_IVF_FLAT 和 GPU_IVF_PQ。
二进制嵌入的索引:
对于 128 维二进制嵌入,它们占用的存储空间为 128 / 8 = 16 字节。用于二进制嵌入的距离度量是 Jaccard 和 Hamming。
这种类型的索引包括 BIN_FLAT 和 BIN_IVF_FLAT。
下表对 Milvus 支持的索引进行了分类:
浮点嵌入的索引
|--------------|---------|----------------------------------|
| 支持的索引 | 分类 | 场景 |
| FLAT | N/A | 1. 相对较小的数据集 2. 要求100%的召回率 |
| IVF_FLAT | 基于量化的指数 | 1. 高速查询 2. 要求召回率尽可能高 |
| GPU_IVF_FLAT | 基于量化的指数 | 1. 高速查询 2. 要求召回率尽可能高 |
| IVF_SQ8 | 基于量化的指数 | 1. 高速查询 2. 内存资源有限 3. 接受召回率的微小妥协 |
| IVF_PQ | 基于量化的指数 | 1. 超高速查询 2. 内存资源有限 3. 接受召回率的重大妥协 |
| GPU_IVF_PQ | 基于量化的指数 | 1. 超高速查询 2. 内存资源有限 3. 接受召回率的重大妥协 |
| HNSW | 基于图形的索引 | 1. 超高速查询 2. 要求召回率尽可能高 3. 大内存资源 |
| SCANN | 基于量化的指数 | 1. 超高速查询 2. 要求召回率尽可能高 3. 大内存资源 |
二进制嵌入的索引
|--------------|---------|--------------------------------------------------|
| 支持的索引 | 分类 | 场景 |
| BIN_FLAT | 基于量化的指数 | 1. 依赖于相对较小的数据集 2. 需要完美的准确性 3. 不适用压缩 4. 保证准确的搜索结果 |
| BIN_IVF_FLAT | 基于量化的指数 | 1. 高速查询 2. 要求召回率尽可能高 |
3.1、浮点嵌入的索引介绍
3.1.1、FLAT
对于需要完美准确性并依赖于相对较小(百万级)数据集的向量相似性搜索应用程序,FLAT索引是一个不错的选择。FLAT不压缩向量,是唯一可以保证精确搜索结果的索引。FLAT的结果也可以用作其他召回率低100%的指标产生的结果的比较点。
FLAT是准确的,因为它采用了一种详尽的搜索方法,这意味着对于每个查询,目标输入都会与数据集中的每组向量进行比较。这使得FLAT成为我们列表中最慢的索引,不适合查询大量矢量数据。Milvus中的FLAT指数不需要参数,使用它也不需要数据训练。
搜索参数
|-------------|---------------|--------------------------------------------------------------------------|
| 参数 | 描述 | 范围 |
| metric_type | [可选]所选的距离指标 | 请参阅支持的指标 |
3.1.2、IVF_FLAT
IVF_FLAT将向量数据划分为nlist聚类单元,然后比较目标输入向量与每个聚类中心之间的距离。根据系统设置为查询的集群数量(nprobe),仅根据目标输入与最相似集群中的向量之间的比较返回相似性搜索结果,从而大大缩短了查询时间。
通过调整nprobe,可以在给定场景中找到准确性和速度之间的理想平衡。IVF_FLAT性能测试的结果表明,随着目标输入向量(nq)和要搜索的聚类数量(nprobe)的增加,查询时间急剧增加。
IVF_FLAT是最基本的IVF指标,存储在每个单元中的编码数据与原始数据一致。
索引构建参数
|--------|--------|-------------|---------|
| 参数 | 描述 | 范围 | 默认值 |
| nlist | 集群单元数量 | [1,65536] | 128 |
搜索参数
|--------|---------|-------------|---------|
| 参数 | 描述 | 范围 | 默认值 |
| nprobe | 要查询的单位数 | [1,nlist] | 8 |
3.1.3、GPU_IVF_FLAT
与IVF_FLAT类似,GPU_IVF_FLAT也将向量数据划分为nlist聚类单元,然后比较目标输入向量与每个聚类中心之间的距离。根据系统设置为查询的集群数量(nprobe),仅根据目标输入与最相似集群中的向量之间的比较返回相似性搜索结果,从而大大缩短了查询时间。
通过调整nprobe,可以在给定场景中找到准确性和速度之间的理想平衡。IVF_FLAT性能测试的结果表明,随着目标输入向量(nq)和要搜索的聚类数量(nprobe)的增加,查询时间急剧增加。
GPU_IVF_FLAT是最基本的IVF指标,存储在每个单元中的编码数据与原始数据一致。
在进行搜索时,请注意,您可以将针对GPU_IVF_FLAT索引集合的任何搜索的前K值设置为256。
索引构建参数
|--------|--------|-------------|---------|
| 参数 | 描述 | 范围 | 默认值 |
| nlist | 集群单元数量 | [1,65536] | 128 |
搜索参数
|--------|---------|-------------|---------|
| 参数 | 描述 | 范围 | 默认值 |
| nprobe | 要查询的单位数 | [1,nlist] | 8 |
搜索限制
|--------|--------|
| 参数 | 范围 |
| top-k | <=256 |
3.1.4、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] |
3.1.5、IVF_PQ
PQ(乘积量化)将原始高维向量空间均匀分解为m个低维向量空间的笛卡尔积,然后对分解后的低维矢量空间进行量化。乘积量化可以计算目标向量与每个低维空间的聚类中心之间的距离,大大降低了算法的时间复杂度和空间复杂度。
IVF_PQ在量化向量乘积之前执行IVF指数聚类。它的索引文件甚至比IVF_SQ8小,但在搜索向量时也会导致准确性下降。
注:
索引构建参数和搜索参数随Milvus分布而变化。首先选择您的Milvus发行版。
索引构建参数
|--------|-------------------|----------------|
| 参数 | 描述 | 范围 |
| nlist | 集群单元数量 | [1,65536] |
| m | 产品量化因素数量 | dim mod m == 0 |
| nbits | [可选]存储每个低维向量的位数 | [1,16](默认为8) |
搜索参数
|--------|---------|-------------|
| 参数 | 描述 | 范围 |
| nprobe | 要查询的单位数 | [1,nlist] |
3.1.6、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, ∞] |
范围搜索参数
|--------------|-----------|--------------|
| 参数 | 描述 | 范围 |
| radius | 要查询的单位数 | [1,nlist] |
| range_filter | 要查询的候选单位数 | [top_k, ∞] |
3.1.7、GPU_IVF_PQ
PQ(乘积量化)将原始高维向量空间均匀分解为m个低维向量空间的笛卡尔积,然后对分解后的低维矢量空间进行量化。乘积量化可以计算目标向量与每个低维空间的聚类中心之间的距离,大大降低了算法的时间复杂度和空间复杂度。
IVF_PQ在量化向量乘积之前执行IVF指数聚类。它的索引文件甚至比IVF_SQ8小,但在搜索向量时也会导致准确性下降。
注:
索引构建参数和搜索参数随Milvus分布而变化。首先选择您的Milvus发行版。
在进行搜索时,请注意,您可以将针对GPU_IVF_FLAT索引集合的任何搜索的前K值设置为8192。
索引构建参数
|--------|-------------------|----------------|---------|
| 参数 | 描述 | 范围 | 默认值 |
| nlist | 集群单元数量 | [1,65536] | 128 |
| m | 产品量化因素数量 | dim mod m == 0 | 4 |
| nbits | [可选]存储每个低维向量的位数 | [1,16] | 8 |
搜索参数
|--------|---------|-------------|---------|
| 参数 | 描述 | 范围 | 默认值 |
| nprobe | 要查询的单位数 | [1,nlist] | 8 |
搜索限制
|--------|---------|
| 参数 | 范围 |
| top-k | <=1024 |
3.1.8、HNSW
HNSW(Hierarchical Navigable Small World Graph)是一种基于图的索引算法。它根据一定的规则为图像构建多层导航结构。在这种结构中,上层更稀疏,节点之间的距离更远;下层越密集,节点之间的距离越近。搜索从最上层开始,找到该层中最接近目标的节点,然后进入下一层开始另一次搜索。经过多次迭代,它可以快速接近目标位置。
为了提高性能,HNSW将图形每层上的最大节点数限制为M。此外,您可以使用efConstruction(构建索引时)或ef(搜索目标时)指定搜索范围。
索引构建参数
|----------------|---------|---------------|
| 参数 | 描述 | 范围 |
| M | 节点的最大度数 | [2,2048] |
| efConstruction | 搜索范围 | [1,int_max] |
搜索参数
|--------|--------|-------------------|
| 参数 | 描述 | 范围 |
| ef | 搜索范围 | [top_k,int_max] |
3.2、二进制嵌入的索引
3.2.1、BIN_FLAT
此索引与FLAT完全相同,除了它只能用于二进制嵌入。
对于需要完美准确性并依赖于相对较小(百万级)数据集的向量相似性搜索应用程序,BIN_FLAT索引是一个不错的选择。BIN_FLAT不压缩向量,是唯一能保证精确搜索结果的索引。BIN_FLAT的结果也可以用作其他召回率低于100%的指标产生的结果的比较点。
BIN_FLAT是准确的,因为它采用了一种详尽的搜索方法,这意味着对于每个查询,目标输入都会与数据集中的向量进行比较。这使得BIN_FLAT成为我们列表中最慢的索引,不适合查询大量矢量数据。Milvus中没有BIN_FLAT索引的参数,使用它不需要数据训练或额外的存储。
搜索参数
|-------------|---------------|--------------------------------------------------------------------------|
| 参数 | 描述 | 范围 |
| metric_type | [可选]所选的距离指标 | 请参阅支持的指标 |
3.2.2、BIN_IVF_FLAT
该索引与IVF_FLAT完全相同,除了它只能用于二进制嵌入。
BIN_IVF_FLAT将向量数据划分为nlist聚类单元,然后比较目标输入向量与每个聚类中心之间的距离。根据系统设置为查询的集群数量(nprobe),仅根据目标输入与最相似集群中的向量之间的比较返回相似性搜索结果,从而大大缩短了查询时间。
通过调整nprobe,可以在给定场景中找到精度和速度之间的理想平衡。随着目标输入向量(nq)和要搜索的聚类数量(nprobe)的增加,查询时间急剧增加。
BIN_IVF_FLAT是最基本的BIN_IVF索引,存储在每个单元中的编码数据与原始数据一致。
索引构建参数
|--------|--------|-------------|
| 参数 | 描述 | 范围 |
| nlist | 集群单元数量 | [1,65536] |
搜索参数
|--------|---------|-------------|
| 参数 | 描述 | 范围 |
| nprobe | 要查询的单位数 | [1,nlist] |
四、常见问题
FLAT索引和IVF_FLAT索引有什么区别?
答: IVF_FLAT索引将向量空间划分为nlist簇。如果将nlist的默认值保持为16384,Milvus会比较目标向量与所有16384个簇的中心之间的距离,以获得最近的nprobe簇。然后Milvus比较目标向量和所选簇中的向量之间的距离,以获得最近的向量。与IVF_FLAT不同的是,FLAT直接比较目标向量与每个向量之间的距离。
因此,当向量总数近似等于nlist时,IVF_FLAT和FLAT在所需的计算方式和搜索性能方面几乎没有差异。但随着载体数量增长到nlist的两倍、三倍或n倍,IVF_FLAT指数开始显示出越来越大的优势。
有关更多信息,请参阅如何在Milvus中内存索引: