searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Milvus向量数据库及其索引方案分析报告

2024-07-18 09:48:43
431
0

向量数据库索引升级方案

1)通过复制知识库或者知识库内复制向量,使得可以同时使用用多索引IVF_FLAT(省内存性能高、召回较高、可以实时更新索引,nlist=1024,nprobe=64)、HNSW_FLAT(耗内存性能高、召回为ANN方案中最高0.958-1.0、不能实时更新索引、索引初始化速度较慢,M=64,econstruction=64,efsearch=128 )。

2)在大文档库情况下,可以根据检索历史反馈,针对热门文档(不得超过1万个chunk)和新增文档,单独加一路KNN暴力检索(FLAT_IP)。

3)升级到Milvus** **2.3.x,支持Arm64架构机器和Flat on GPU新特性,可以全用FLATIP。

4)针对新增文档和用户库文档改为采用FlatIP/FlatonGPU方案,针对文档较多的组(文档1万以上量级)/管理员库改为采用HNSW与IVFFLAT并行方案。如果内存不够,可以牺牲召回率,只用IVFPQ索引;或者采用DiskANN方案。

5)HNSW需要注意内存占用,想要召回率大于95%一般要设定M值为64或128。需要考虑1000万条chunk向量的存储大小问题:1000w * 4Byte * 1024维 = 38G内存。HNSW 内存的开销较高,通常需要原始向量的 1.5 - 2 倍以上内存,因此有可能需要80G内存。

6)1M数据复合索引最优方案:

IVF4096+HNSW, FLAT,如果再叠加PQ会召回骤降。

在大数据量内存不足的场景下:要求高性能用IVFPQ,要求高召回用DiskANN;

在内存充足的场景下:性能和效果优先,选HNSW;资源优先选IVF_FLAT。

7)合理选择流式插入和批量导入

如果有大量离线写入的场景,建议使用 BulkInsert,原因是 BulkInsert 不会对查询性能造成太大的影响,并且也大大减少了流式写入对消息队列产生的压力。

单次写入超过 100MB 以上,建议选择批式写入;

希望尽可能减少写入对线上查询的影响,建议选择批式写入;

希望写入实时可见,建议选择流式写入;

单次写入小于 10MB 以下,建议选择流式写入。

尽可能批量写入,整体吞吐会更高,建议每次写入的大小控制在 10M,单个 Shard 的流式写入量不建议超过 10M/s,Datanode 多于 Shard 的情况下,部分 DataNode 可能无法获得负载。导入目前支持的文件大小上限是 1GB,接下来会支持更大的导入文件大小上限。不建议频繁导入小文件,会给 compaction 带来比较大的压力。

除了每个节点的 CPU 使用率,内存使用量信息,以下是一些建议你关注的监控指标:

Proxy

查询延迟:milvus_proxy_sq_latency/milvus_proxy_collection_sq_latency

写入 / 删除延迟:milvus_proxy_mutation_latency

写入流量:milvus_proxy_receive_bytes_count

查询返回流量:milvus_proxy_send_bytes_count

QueryNode

加载的数据量:milvus_querynode_entity_num

查询请求排队时间:milvus_querynode_sq_queue_latency

单个 Segment 的查询时间:milvus_querynode_sq_segment_latency

IndexNode

构建索引的时间:milvus_indexnode_build_index_latency

DataNode

Flush 花费的时间:milvus_datanode_save_latency

Compaction 花费的时间:milvus_datanode_compaction_latency

8)谨慎使用标量过滤,删除特性等特性

作为数据库,Milvus 支持了删除、标量过滤、TimeTravel 等高级特性。如果不了解底层原理,使用这些高级功能可能会对稳定性和性能造成比较严重的影响,以下是一些使用注意事项:

Milvus 使用的是前过滤,即先做标量过滤生成 Bitset,在向量检索的过程中基于 Bitset 去除掉不满足条件的 entity。对于 HNSW 这一类的图索引而言,标量过滤并不会加速查询,反而可能导致性能变差。特别是对于过滤性很强的条件(比如 PK=1 这种全局唯一的条件),标量过滤甚至会导致单次查询的时间长于爆搜。针对这种情况,用户也可以选择通过后过滤的方式绕过,先基于 Milvus 查出 TopK 的数据,再基于其他数据库进行过滤。

对于过滤条件相对比较确定的场景,使用 Partition 把数据进行物理分区,在查询的时候指定 Partition 性能更好。

Milvus 的删除是标记删除,在 compaction 时会清理,因此删除的数据依然会占据内存。大量删除也会造成查询性能下降,同时大量 compaction 可能造成建索引压力变大等一系列影响。在需要大量频繁删除的场景,可能需要进行一些 compaction 参数的调整,保证删除的数据能够被及时清理。

Milvus 支持了数据自动过期功能(TTL),可以定时清理过期数据。

如果需要全量更新一个 Collection 的数据,推荐使用新建表 + 导入数据 + Alias 切换的方案。

制定 Output field 时,如果要获取标量字段,会从对象存储上获取,吞吐和延迟都会受到较大影响。

向量检索索引对比

2.1 索引类型与参数

2.1.1 精准召回

1)LSH也是精准召回,但是对于d>=64的性能即有维度灾难,性能不如FLAT,而我们的向量有1024维。

2.1.2 倒排索引 IVF

1)IVF_FLAT、IVFPQ需要训练聚类,不支持增量索引。

2)IVF 参数

nlist:一般建议 nlist = 4*sqrt(N),对于 Milvus 而言,一个 Segment 默认是 512M 数据,对于 128dim 向量而言,一个 segment 包含 100w 数据,因此最佳 nlist 在 1000 左右。

所以对1024dim的向量。最佳nlist应该为2800左右。

nprobe:nprobe 可以 Search 时调整搜索的数据量,nprobe 越大,recall 越高,但性能越差。具体的 nprobe 需要根据查询的精度要求决定,从 nprobe = 16 开始会是一个不错的尝试。

2.1.3 小世界网络 HNSW

1)支持增量索引。

2)HNSW需要注意内存占用,想要召回率大于95%一般要设定M值为64或128。

3)ef必须大于K

4)常见的ef_construction = 128内存消耗越大。

5)M通常在8-32之间,M越大

2.1.4 量化类索引 PQ、SQ8

1)PQ、IVFPQ需要进行训练量化,不支持增量索引。

2)速度最快,召回率损失较大。

3)对于大数据量、内存不足但是性能要求高的场景

4)IVF_SQ8 相比 IVF,将向量数据从 float32 转换为了 int8,可以减少 4 倍的内存用量,但对召回率有较大影响,如果要求 95% 以上的召回精度不建议使用。

2.1.5 ScaNN

见4.1.1(5) 新增ScaNN索引支持

2.1.6 DiskANN

1)DiskANN 依赖高性能的磁盘索引,借助 NVMe 磁盘缓存全量数据,在内存中只存储了量化后的数据。

2)DiskANN 适用于对于查询 Recall 要求较高,QPS 不高,大数据量,内存不足的场景。

3)DiskANN 的关键参数search_list:

search_list 越大,recall 越高而性能越差。search_list 的大小不应该小于 K。而对于较小的 K,推荐把 search_list 和 K 的比值设置得相对大一些, 这个比值随着 K 增大可以逐渐靠近。

2.1.7 复合索引

将下列各项单一索引方式自由组合,就可以构成复合索引。

向量变换 (Vector transform) :

在索引(PCA、OPQ)之前,应用于向量的预处理步骤。

粗量化器 (Coarse quantizer) :

粗略地将向量集合组织为一个个子域(用于减小搜索范围,包括 IVF、IMI 和 HNSW)。

精细量化器 (Fine quantizer) :

将向量更精细地压缩到更小的域中(用于压缩索引大小,例如 PQ)。

细化 (Refinement) :

搜索时的最后一步,它使用原始向量的距离计算对结果进行重新排序。或者使用其他非穷举的索引。

2.2 ANN-Benchmark

ANN-Benchmark网站对现有流行的向量检索产品进行了性能测试,其测试结果在其官网上展示。

ANN-Benchmark官网

指标:** **

1)Recall/Queries per second** **

1s内召回数量;按照100ms的响应时间计算的话,需要关注1s召回 10 * 100个向量(=下图中1e+2 query(k=10))的召回率。

向量检索测试方案

3.1 效果测试方案

3.1.1 Recall@K指标

例子:单个query 在 4000篇公务文档中的召回率对比:

IVF_Flat,IP 参数为 nlist = 1024, nprobe = 64

公式:

Recall@k = intersect(IVF_Flat(k),FlatIP(k)) / FlatIP(k) ; k = 10,20,30,40, 50,100,200,300,400,500,1000

Recall@10 = 100%

Recall@20 = 90%

Recall@30 = 86.7%

Recall@40 = 85%

Recall@50 = 88%

Recall@100 = 85%

Recall@200 = 80.5%

Recall@300 = 74.7%

Recall@400 = 68.5%

Recall@500 = 63.4%

Recall@1000 = 55.7%

3.1.2 索引软删除对召回率的影响

3.2 性能测试方案

3.2.1 单条Query 召回TopK结果的平均响应时间 与 超时率指标

3.2.2 QPS (QueryPerSecond)

3.2.3 索引构建时间

3.2.4 索引占用内存

3.2.5 索引占用显存(Flat on GPU方案)

3.2.6 索引是否支持增量增加数据,以及增量增加每条数据的响应时间开销

3.2.7 索引是否支持增量软删除数据,以及软删除对QPS、响应时间的影响

Milvus版本对比

4.1 Milvus v2.3.x

4.1.1 新特性

1)Flat on GPU

可以加速0.95召回率的IVF-Flat 和 遍历检索FlatIP。需要支持CUDA的GPU设备。

经测试,GPU 版本相较于 CPU HNSW 索引有了 3 倍以上的 QPS 提升,部分数据集有近 10 倍的提升。下表是 GPU-IVF-FLAT 和 HNSW 在 Milvus E2E 上的 QPS 数据,host 的 size 是 8c32g,NVIDIA A100 GPU。NQ 为 100:
Nvidia贡献了Rapid RAFT中的GPU_FLAT和GPU_IVFPQ索引,A100上吞吐量相对于CPU提升10~70倍。

GPU 版 Milvus 在 CPU 版的基础上进行了 GPU 加速:支持同时进行索引创建和搜索计算以提高查询效率。可以在同一时间内使用 GPU 建索引,使用 CPU 搜索向量。

GPU版本Milvus支持的索引类型:浮点型向量

索引类型 CPU 建索引 GPU 建索引 CPU 搜索 GPU 搜索
FLAT N/A N/A ✔️ ✔️
IVF_FLAT ✔️ ✔️ ✔️ ✔️
IVF_SQ8 ✔️ ✔️ ✔️ ✔️
IVF_SQ8H ✔️ ✔️ ✔️ ✔️
IVF_PQ ✔️ ✔️ ✔️ ✔️
RNSG ✔️ ✔️
HNSW ✔️ ✔️
ANNOY ✔️ ✔️

CPU 和 GPU 创建的索引完全一致,只是一般情况下 GPU 的创建索引速度快于 CPU 的创建速度。

top_k > 2048 或nprobe > 2048时,Milvus 由 GPU 查询切换为 CPU 查询。

GPU版本Milvus支持的索引类型:二值型向量

索引类型 CPU 建索引 GPU 建索引 CPU 搜索 GPU 搜索
FLAT N/A N/A ✔️
IVF_FLAT ✔️ ✔️
2)新增RangeSearch

最大返回结果不超16384

3)新增原生cosine距离
4)新增返回原始向量功能

(PQ/SQ8量化索引不支持),但是会有二次查询的性能开销产生

5)新增ScaNN(Faiss-FastScan算法)

在各项 benchmark 中有着不俗的表现,对比 HNSW 有 20% 左右提升,约为 IVFFlat 的 7 倍,同时构建索引速度更快。ScaNN 在算法上跟 IVFPQ 比较类似,聚类分桶,然后桶里的向量使用 PQ 做量化,区别是 ScaNN 对于量化比较激进,搭配上 SIMD 计算效率较高,但是精度损失会比较大,需要有原始向量做 refine 的过程。下表是 ScaNN、HNSW 和 IVFFLAT 在 Cohere1M(768 维)的数据集下的性能表现,数据来自于 VectorDBBench。

6)新增Arm64CPU支持
7)Growing 索引

Milvus 的数据分为两类,分别为已索引的数据和流式数据。对于已索引的数据自然可以使用索引加速查询,但流式数据只能使用逐行暴力检索,对性能影响较大,为了解决此类问题在 2.3.0 中加入了 Growing index,自动为流式数据建立实时索引,保障查询性能。

4.1.2 限制

1)Milvus 2.3 不再支持CentOS,需要改用Ubuntu
2)Milvus限制每个collection(知识库)只能有一个索引

因此要有同时用多索引的需求的话,例如IVF_FLAT(省内存性能高、召回较高)+HNSW_FLAT(耗内存性能高、召回0.958-1.0 ),需要复制多个collections或者在collections里面复制多遍emb。

Number of resources

Resource Limit
Collection 65,536
Connection / proxy 65,536

Number of resources in a collection

Resource Limit
Partition 4,096
Shard 16
Field 64
Index 1
Entity unlimited

4.2 Milvus v2.0.x

开源向量数据库对比

5.1 Milvus Vs Faiss

Faiss不支持Flat、IVF、IDMap以外的删除索引操作;线上Milvus应该是自己实现了一些删除操作。(Milvus软删除数据的布隆过滤器方案)

5.2 Milvus Vs ES

5.3 向量数据库对比

序号 产品名 是否开源 开发者 Github Star数 优点 缺点
1 Milvus Zilliz(上海) 9.1k 索引类型多,社区活跃 不支持数据分片,架构复杂(现在可支持数据分区分片了;已经有分布式架构Mishards )
2 Faiss Facebook 15.9k 性能好,索引类型多, 成熟 不支持服务化
3 HNSWlib nmslib 1.8k 性能好,召回率高 不支持服务化
4 ScaNN Google 21.4k 性能好,召回率高 不支持服务化
5 SPTAG Microsoft 4.1k 性能好 索引类型少
6 Vearch 京东 1.3k 性能好 不能实时更新
7 Zsearch 蚂蚁金服 / 索引类型多 不开源
8 Proxima 阿里达摩院 / 索引类型多 不开源(后来开源了?)
序号 产品 实时更新 过滤功能 CPU和GPU 集群模式 可服务化 开发语言 SDK
1 Milvus Go/Python Python/Go/Java/Node
2 Faiss C++ C++/Python
3 HNSWlib C++ C++/Python
4 ScaNN C++/Python C++/Python
5 SPTAG C++ Python/C#
6 Vearch Go Python
OpenSearch Pinecone Milvus ElasticSearch
首次发布时间 2021年12月31日 2021年1月 2019年10月22日 2023年7月26日
定位 大规模向量实时检索 向量数据库(强调AI模型长期记忆) 向量数据库(集成了Faiss IVF,Faiss HNSW,SPTAG);一种高性能的向量检索引擎,支持多模态数据。它的主要特点是支持高维度向量的索引和搜索,并提供高效的API访问。但是,milvus在处理大规模数据时可能存在一些挑战。 检索和分析引擎(支持向量检索,被Langchain Server支持,自带RRF,自带Okapi-BM25,自带条件向量检索)
开源
运维方式 全托管 全托管 自运维 自运维
向量算法 Linear(暴力检索)QC(聚类)HNSW PQ、LSH、HNSW产品自动选择合适算法 FLAT、IVF_FLAT、IVF_PQ、IVF_SQ8、HNSW、ANNOY Brute-Force kNNHNSW
向量维度 无限制 1-20000维 最大32768 建索引:1024 不建索引:2048
向量化 支持文本、图片向量化 不支持 不支持(支持多模态?) 不支持
标签过滤 支持 支持 支持 支持
全文索引 支持 不支持 不支持 支持
标签向量混合查询 支持 支持 支持;支持在向量检索过程中进行标量字段过滤,实现混合查询;但是标量过滤为前过滤,有损向量召回性能 支持
实时索引构建 支持 支持 支持 支持
索引版本热切换 支持 不支持 不支持 不支持
副本数变更(replica) 支持 支持 支持 支持
分片数变更(shard) 支持 支持 支持 支持
GPU加速 支持(QC) 不支持 支持(IVF系列) 不支持
数据源支持 ODPS、OSS、HDFS
开发接入 Java SDK、Python SDK、GO SDK、REST API Python、NodeJS Client Python、Java、Go、Node、REST API REST API
查询语法 SQL、HA3 自定义SDK 自定义SDK ES Query DSL、SQL
产品优势 简单易用大规模向量数据检索内置文本、图片向量化索引版本热切换GPU加速支持多数据源阿里巴巴内部场景打磨大模型生态结合 简单易用动态算法选择大模型生态结合 依托开源社区生态向量领域品牌影响力大;支持使用Kubernetes部署,支持在云上扩展。其容灾能力能够保证服务的高可用。Milvus依照日志及数据的理念,使用如Pulsar、Kafka等消息队列的技术实现组件间的通信,对组件进行解耦,拥抱云原生;单节点主从式架构 依托开源社区生态检索和分析领域品牌影响力大
OpenSearch Milvus ElasticSearch
测试集 ANN_GIST1M 960维
产品版本 向量检索版2023.8(VectorStore引擎) v2.2.12 v8.9
机器规格 16核64G 16核64G 16核64G
测试工具 wrk压测参数:线程:8 连接数:24 Milvus Python SDK:压测参数:线程:8 连接数:24 wrk 压测参数:线程:8 连接数:24
参数配置 m:64 ef_construction:512 m:64 ef_construction:512 m=64 ef_construction: 512 JVM内存:32G
向量算法 HNSW HNSW HNSW
数据导入耗时 1103s 1437s 7389s
索引大小 3.8G 2.44G 8G
top10 recall@95 查询参数:ef=142 查询参数:ef=40 查询参数:k=10num_candidates=20
QPS QPS: 1619.2 Latency:14.95ms CPU负载:92.4% 内存占用:8.4G QPS: 827.36 Latency: 28.96ms CPU负载:91.3% 内存占用:5.6G(号称QPS为ES的10倍) QPS: 547.63 Latency:46.45ms CPU负载:97% 内存占用:32G(JVM)
top10 recall@99 查询参数:ef=450 查询参数:ef=100 查询参数: k=10 num_candidates=55
QPS: 863.43 Latency:28.16ms CPU负载:95.7% 内存占用:8.4G QPS: 475.61 Latency:50.44ms CPU负载:98.2% 内存占用:5.5G QPS: 305.90 Latency:79.24ms CPU负载:97.5% 内存占用:32G(JVM)
0条评论
0 / 1000
陈****婳
3文章数
1粉丝数
陈****婳
3 文章 | 1 粉丝
原创

Milvus向量数据库及其索引方案分析报告

2024-07-18 09:48:43
431
0

向量数据库索引升级方案

1)通过复制知识库或者知识库内复制向量,使得可以同时使用用多索引IVF_FLAT(省内存性能高、召回较高、可以实时更新索引,nlist=1024,nprobe=64)、HNSW_FLAT(耗内存性能高、召回为ANN方案中最高0.958-1.0、不能实时更新索引、索引初始化速度较慢,M=64,econstruction=64,efsearch=128 )。

2)在大文档库情况下,可以根据检索历史反馈,针对热门文档(不得超过1万个chunk)和新增文档,单独加一路KNN暴力检索(FLAT_IP)。

3)升级到Milvus** **2.3.x,支持Arm64架构机器和Flat on GPU新特性,可以全用FLATIP。

4)针对新增文档和用户库文档改为采用FlatIP/FlatonGPU方案,针对文档较多的组(文档1万以上量级)/管理员库改为采用HNSW与IVFFLAT并行方案。如果内存不够,可以牺牲召回率,只用IVFPQ索引;或者采用DiskANN方案。

5)HNSW需要注意内存占用,想要召回率大于95%一般要设定M值为64或128。需要考虑1000万条chunk向量的存储大小问题:1000w * 4Byte * 1024维 = 38G内存。HNSW 内存的开销较高,通常需要原始向量的 1.5 - 2 倍以上内存,因此有可能需要80G内存。

6)1M数据复合索引最优方案:

IVF4096+HNSW, FLAT,如果再叠加PQ会召回骤降。

在大数据量内存不足的场景下:要求高性能用IVFPQ,要求高召回用DiskANN;

在内存充足的场景下:性能和效果优先,选HNSW;资源优先选IVF_FLAT。

7)合理选择流式插入和批量导入

如果有大量离线写入的场景,建议使用 BulkInsert,原因是 BulkInsert 不会对查询性能造成太大的影响,并且也大大减少了流式写入对消息队列产生的压力。

单次写入超过 100MB 以上,建议选择批式写入;

希望尽可能减少写入对线上查询的影响,建议选择批式写入;

希望写入实时可见,建议选择流式写入;

单次写入小于 10MB 以下,建议选择流式写入。

尽可能批量写入,整体吞吐会更高,建议每次写入的大小控制在 10M,单个 Shard 的流式写入量不建议超过 10M/s,Datanode 多于 Shard 的情况下,部分 DataNode 可能无法获得负载。导入目前支持的文件大小上限是 1GB,接下来会支持更大的导入文件大小上限。不建议频繁导入小文件,会给 compaction 带来比较大的压力。

除了每个节点的 CPU 使用率,内存使用量信息,以下是一些建议你关注的监控指标:

Proxy

查询延迟:milvus_proxy_sq_latency/milvus_proxy_collection_sq_latency

写入 / 删除延迟:milvus_proxy_mutation_latency

写入流量:milvus_proxy_receive_bytes_count

查询返回流量:milvus_proxy_send_bytes_count

QueryNode

加载的数据量:milvus_querynode_entity_num

查询请求排队时间:milvus_querynode_sq_queue_latency

单个 Segment 的查询时间:milvus_querynode_sq_segment_latency

IndexNode

构建索引的时间:milvus_indexnode_build_index_latency

DataNode

Flush 花费的时间:milvus_datanode_save_latency

Compaction 花费的时间:milvus_datanode_compaction_latency

8)谨慎使用标量过滤,删除特性等特性

作为数据库,Milvus 支持了删除、标量过滤、TimeTravel 等高级特性。如果不了解底层原理,使用这些高级功能可能会对稳定性和性能造成比较严重的影响,以下是一些使用注意事项:

Milvus 使用的是前过滤,即先做标量过滤生成 Bitset,在向量检索的过程中基于 Bitset 去除掉不满足条件的 entity。对于 HNSW 这一类的图索引而言,标量过滤并不会加速查询,反而可能导致性能变差。特别是对于过滤性很强的条件(比如 PK=1 这种全局唯一的条件),标量过滤甚至会导致单次查询的时间长于爆搜。针对这种情况,用户也可以选择通过后过滤的方式绕过,先基于 Milvus 查出 TopK 的数据,再基于其他数据库进行过滤。

对于过滤条件相对比较确定的场景,使用 Partition 把数据进行物理分区,在查询的时候指定 Partition 性能更好。

Milvus 的删除是标记删除,在 compaction 时会清理,因此删除的数据依然会占据内存。大量删除也会造成查询性能下降,同时大量 compaction 可能造成建索引压力变大等一系列影响。在需要大量频繁删除的场景,可能需要进行一些 compaction 参数的调整,保证删除的数据能够被及时清理。

Milvus 支持了数据自动过期功能(TTL),可以定时清理过期数据。

如果需要全量更新一个 Collection 的数据,推荐使用新建表 + 导入数据 + Alias 切换的方案。

制定 Output field 时,如果要获取标量字段,会从对象存储上获取,吞吐和延迟都会受到较大影响。

向量检索索引对比

2.1 索引类型与参数

2.1.1 精准召回

1)LSH也是精准召回,但是对于d>=64的性能即有维度灾难,性能不如FLAT,而我们的向量有1024维。

2.1.2 倒排索引 IVF

1)IVF_FLAT、IVFPQ需要训练聚类,不支持增量索引。

2)IVF 参数

nlist:一般建议 nlist = 4*sqrt(N),对于 Milvus 而言,一个 Segment 默认是 512M 数据,对于 128dim 向量而言,一个 segment 包含 100w 数据,因此最佳 nlist 在 1000 左右。

所以对1024dim的向量。最佳nlist应该为2800左右。

nprobe:nprobe 可以 Search 时调整搜索的数据量,nprobe 越大,recall 越高,但性能越差。具体的 nprobe 需要根据查询的精度要求决定,从 nprobe = 16 开始会是一个不错的尝试。

2.1.3 小世界网络 HNSW

1)支持增量索引。

2)HNSW需要注意内存占用,想要召回率大于95%一般要设定M值为64或128。

3)ef必须大于K

4)常见的ef_construction = 128内存消耗越大。

5)M通常在8-32之间,M越大

2.1.4 量化类索引 PQ、SQ8

1)PQ、IVFPQ需要进行训练量化,不支持增量索引。

2)速度最快,召回率损失较大。

3)对于大数据量、内存不足但是性能要求高的场景

4)IVF_SQ8 相比 IVF,将向量数据从 float32 转换为了 int8,可以减少 4 倍的内存用量,但对召回率有较大影响,如果要求 95% 以上的召回精度不建议使用。

2.1.5 ScaNN

见4.1.1(5) 新增ScaNN索引支持

2.1.6 DiskANN

1)DiskANN 依赖高性能的磁盘索引,借助 NVMe 磁盘缓存全量数据,在内存中只存储了量化后的数据。

2)DiskANN 适用于对于查询 Recall 要求较高,QPS 不高,大数据量,内存不足的场景。

3)DiskANN 的关键参数search_list:

search_list 越大,recall 越高而性能越差。search_list 的大小不应该小于 K。而对于较小的 K,推荐把 search_list 和 K 的比值设置得相对大一些, 这个比值随着 K 增大可以逐渐靠近。

2.1.7 复合索引

将下列各项单一索引方式自由组合,就可以构成复合索引。

向量变换 (Vector transform) :

在索引(PCA、OPQ)之前,应用于向量的预处理步骤。

粗量化器 (Coarse quantizer) :

粗略地将向量集合组织为一个个子域(用于减小搜索范围,包括 IVF、IMI 和 HNSW)。

精细量化器 (Fine quantizer) :

将向量更精细地压缩到更小的域中(用于压缩索引大小,例如 PQ)。

细化 (Refinement) :

搜索时的最后一步,它使用原始向量的距离计算对结果进行重新排序。或者使用其他非穷举的索引。

2.2 ANN-Benchmark

ANN-Benchmark网站对现有流行的向量检索产品进行了性能测试,其测试结果在其官网上展示。

ANN-Benchmark官网

指标:** **

1)Recall/Queries per second** **

1s内召回数量;按照100ms的响应时间计算的话,需要关注1s召回 10 * 100个向量(=下图中1e+2 query(k=10))的召回率。

向量检索测试方案

3.1 效果测试方案

3.1.1 Recall@K指标

例子:单个query 在 4000篇公务文档中的召回率对比:

IVF_Flat,IP 参数为 nlist = 1024, nprobe = 64

公式:

Recall@k = intersect(IVF_Flat(k),FlatIP(k)) / FlatIP(k) ; k = 10,20,30,40, 50,100,200,300,400,500,1000

Recall@10 = 100%

Recall@20 = 90%

Recall@30 = 86.7%

Recall@40 = 85%

Recall@50 = 88%

Recall@100 = 85%

Recall@200 = 80.5%

Recall@300 = 74.7%

Recall@400 = 68.5%

Recall@500 = 63.4%

Recall@1000 = 55.7%

3.1.2 索引软删除对召回率的影响

3.2 性能测试方案

3.2.1 单条Query 召回TopK结果的平均响应时间 与 超时率指标

3.2.2 QPS (QueryPerSecond)

3.2.3 索引构建时间

3.2.4 索引占用内存

3.2.5 索引占用显存(Flat on GPU方案)

3.2.6 索引是否支持增量增加数据,以及增量增加每条数据的响应时间开销

3.2.7 索引是否支持增量软删除数据,以及软删除对QPS、响应时间的影响

Milvus版本对比

4.1 Milvus v2.3.x

4.1.1 新特性

1)Flat on GPU

可以加速0.95召回率的IVF-Flat 和 遍历检索FlatIP。需要支持CUDA的GPU设备。

经测试,GPU 版本相较于 CPU HNSW 索引有了 3 倍以上的 QPS 提升,部分数据集有近 10 倍的提升。下表是 GPU-IVF-FLAT 和 HNSW 在 Milvus E2E 上的 QPS 数据,host 的 size 是 8c32g,NVIDIA A100 GPU。NQ 为 100:
Nvidia贡献了Rapid RAFT中的GPU_FLAT和GPU_IVFPQ索引,A100上吞吐量相对于CPU提升10~70倍。

GPU 版 Milvus 在 CPU 版的基础上进行了 GPU 加速:支持同时进行索引创建和搜索计算以提高查询效率。可以在同一时间内使用 GPU 建索引,使用 CPU 搜索向量。

GPU版本Milvus支持的索引类型:浮点型向量

索引类型 CPU 建索引 GPU 建索引 CPU 搜索 GPU 搜索
FLAT N/A N/A ✔️ ✔️
IVF_FLAT ✔️ ✔️ ✔️ ✔️
IVF_SQ8 ✔️ ✔️ ✔️ ✔️
IVF_SQ8H ✔️ ✔️ ✔️ ✔️
IVF_PQ ✔️ ✔️ ✔️ ✔️
RNSG ✔️ ✔️
HNSW ✔️ ✔️
ANNOY ✔️ ✔️

CPU 和 GPU 创建的索引完全一致,只是一般情况下 GPU 的创建索引速度快于 CPU 的创建速度。

top_k > 2048 或nprobe > 2048时,Milvus 由 GPU 查询切换为 CPU 查询。

GPU版本Milvus支持的索引类型:二值型向量

索引类型 CPU 建索引 GPU 建索引 CPU 搜索 GPU 搜索
FLAT N/A N/A ✔️
IVF_FLAT ✔️ ✔️
2)新增RangeSearch

最大返回结果不超16384

3)新增原生cosine距离
4)新增返回原始向量功能

(PQ/SQ8量化索引不支持),但是会有二次查询的性能开销产生

5)新增ScaNN(Faiss-FastScan算法)

在各项 benchmark 中有着不俗的表现,对比 HNSW 有 20% 左右提升,约为 IVFFlat 的 7 倍,同时构建索引速度更快。ScaNN 在算法上跟 IVFPQ 比较类似,聚类分桶,然后桶里的向量使用 PQ 做量化,区别是 ScaNN 对于量化比较激进,搭配上 SIMD 计算效率较高,但是精度损失会比较大,需要有原始向量做 refine 的过程。下表是 ScaNN、HNSW 和 IVFFLAT 在 Cohere1M(768 维)的数据集下的性能表现,数据来自于 VectorDBBench。

6)新增Arm64CPU支持
7)Growing 索引

Milvus 的数据分为两类,分别为已索引的数据和流式数据。对于已索引的数据自然可以使用索引加速查询,但流式数据只能使用逐行暴力检索,对性能影响较大,为了解决此类问题在 2.3.0 中加入了 Growing index,自动为流式数据建立实时索引,保障查询性能。

4.1.2 限制

1)Milvus 2.3 不再支持CentOS,需要改用Ubuntu
2)Milvus限制每个collection(知识库)只能有一个索引

因此要有同时用多索引的需求的话,例如IVF_FLAT(省内存性能高、召回较高)+HNSW_FLAT(耗内存性能高、召回0.958-1.0 ),需要复制多个collections或者在collections里面复制多遍emb。

Number of resources

Resource Limit
Collection 65,536
Connection / proxy 65,536

Number of resources in a collection

Resource Limit
Partition 4,096
Shard 16
Field 64
Index 1
Entity unlimited

4.2 Milvus v2.0.x

开源向量数据库对比

5.1 Milvus Vs Faiss

Faiss不支持Flat、IVF、IDMap以外的删除索引操作;线上Milvus应该是自己实现了一些删除操作。(Milvus软删除数据的布隆过滤器方案)

5.2 Milvus Vs ES

5.3 向量数据库对比

序号 产品名 是否开源 开发者 Github Star数 优点 缺点
1 Milvus Zilliz(上海) 9.1k 索引类型多,社区活跃 不支持数据分片,架构复杂(现在可支持数据分区分片了;已经有分布式架构Mishards )
2 Faiss Facebook 15.9k 性能好,索引类型多, 成熟 不支持服务化
3 HNSWlib nmslib 1.8k 性能好,召回率高 不支持服务化
4 ScaNN Google 21.4k 性能好,召回率高 不支持服务化
5 SPTAG Microsoft 4.1k 性能好 索引类型少
6 Vearch 京东 1.3k 性能好 不能实时更新
7 Zsearch 蚂蚁金服 / 索引类型多 不开源
8 Proxima 阿里达摩院 / 索引类型多 不开源(后来开源了?)
序号 产品 实时更新 过滤功能 CPU和GPU 集群模式 可服务化 开发语言 SDK
1 Milvus Go/Python Python/Go/Java/Node
2 Faiss C++ C++/Python
3 HNSWlib C++ C++/Python
4 ScaNN C++/Python C++/Python
5 SPTAG C++ Python/C#
6 Vearch Go Python
OpenSearch Pinecone Milvus ElasticSearch
首次发布时间 2021年12月31日 2021年1月 2019年10月22日 2023年7月26日
定位 大规模向量实时检索 向量数据库(强调AI模型长期记忆) 向量数据库(集成了Faiss IVF,Faiss HNSW,SPTAG);一种高性能的向量检索引擎,支持多模态数据。它的主要特点是支持高维度向量的索引和搜索,并提供高效的API访问。但是,milvus在处理大规模数据时可能存在一些挑战。 检索和分析引擎(支持向量检索,被Langchain Server支持,自带RRF,自带Okapi-BM25,自带条件向量检索)
开源
运维方式 全托管 全托管 自运维 自运维
向量算法 Linear(暴力检索)QC(聚类)HNSW PQ、LSH、HNSW产品自动选择合适算法 FLAT、IVF_FLAT、IVF_PQ、IVF_SQ8、HNSW、ANNOY Brute-Force kNNHNSW
向量维度 无限制 1-20000维 最大32768 建索引:1024 不建索引:2048
向量化 支持文本、图片向量化 不支持 不支持(支持多模态?) 不支持
标签过滤 支持 支持 支持 支持
全文索引 支持 不支持 不支持 支持
标签向量混合查询 支持 支持 支持;支持在向量检索过程中进行标量字段过滤,实现混合查询;但是标量过滤为前过滤,有损向量召回性能 支持
实时索引构建 支持 支持 支持 支持
索引版本热切换 支持 不支持 不支持 不支持
副本数变更(replica) 支持 支持 支持 支持
分片数变更(shard) 支持 支持 支持 支持
GPU加速 支持(QC) 不支持 支持(IVF系列) 不支持
数据源支持 ODPS、OSS、HDFS
开发接入 Java SDK、Python SDK、GO SDK、REST API Python、NodeJS Client Python、Java、Go、Node、REST API REST API
查询语法 SQL、HA3 自定义SDK 自定义SDK ES Query DSL、SQL
产品优势 简单易用大规模向量数据检索内置文本、图片向量化索引版本热切换GPU加速支持多数据源阿里巴巴内部场景打磨大模型生态结合 简单易用动态算法选择大模型生态结合 依托开源社区生态向量领域品牌影响力大;支持使用Kubernetes部署,支持在云上扩展。其容灾能力能够保证服务的高可用。Milvus依照日志及数据的理念,使用如Pulsar、Kafka等消息队列的技术实现组件间的通信,对组件进行解耦,拥抱云原生;单节点主从式架构 依托开源社区生态检索和分析领域品牌影响力大
OpenSearch Milvus ElasticSearch
测试集 ANN_GIST1M 960维
产品版本 向量检索版2023.8(VectorStore引擎) v2.2.12 v8.9
机器规格 16核64G 16核64G 16核64G
测试工具 wrk压测参数:线程:8 连接数:24 Milvus Python SDK:压测参数:线程:8 连接数:24 wrk 压测参数:线程:8 连接数:24
参数配置 m:64 ef_construction:512 m:64 ef_construction:512 m=64 ef_construction: 512 JVM内存:32G
向量算法 HNSW HNSW HNSW
数据导入耗时 1103s 1437s 7389s
索引大小 3.8G 2.44G 8G
top10 recall@95 查询参数:ef=142 查询参数:ef=40 查询参数:k=10num_candidates=20
QPS QPS: 1619.2 Latency:14.95ms CPU负载:92.4% 内存占用:8.4G QPS: 827.36 Latency: 28.96ms CPU负载:91.3% 内存占用:5.6G(号称QPS为ES的10倍) QPS: 547.63 Latency:46.45ms CPU负载:97% 内存占用:32G(JVM)
top10 recall@99 查询参数:ef=450 查询参数:ef=100 查询参数: k=10 num_candidates=55
QPS: 863.43 Latency:28.16ms CPU负载:95.7% 内存占用:8.4G QPS: 475.61 Latency:50.44ms CPU负载:98.2% 内存占用:5.5G QPS: 305.90 Latency:79.24ms CPU负载:97.5% 内存占用:32G(JVM)
文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0