原文标题:以阿里云OpenSearch为例谈向量检索技术选型
原文作者:阿里云开发者
冷月清谈:
应用场景:
- 非结构化数据(语音、图像、视频)检索
- 大模型知识记忆
- 搜索、推荐、广告
常见方法:
- Brute Force方法:适用于小数据规模或对准确率要求极高的场景
- ANN方法:包括基于树、聚类、量化、哈希和图的算法,以牺牲一定精度换取检索速度
- 基于树:KD-Tree、Annoy
- 基于聚类:层次聚类
- 基于量化:PQ
- 基于哈希:LSH
- 基于图:HNSW
性能优化:
- 构建阶段:优化图的出度入度,利于ANN搜索
- 检索阶段:减少距离计算操作开销和预测检索游走步数,提前终止检索
阿里云OpenSearch优势:
- 支持大规模数据实时检索
- 内置文本、图片向量化
- 索引版本热切换
- 支持GPU加速
- 支持数据源同步
其他产品对比:
- Milvus:开源向量数据库,适用于开源软件需求场景
- ElasticSearch:支持向量检索的检索和分析引擎,适用于开源软件需求场景
- Pinecone:全托管向量数据库,适用于海外用户
怜星夜思:
2、除了HNSW,文章还介绍了其他ANN检索算法,在哪些场景下会优先选择这些算法呢?
3、文章对比了阿里云OpenSearch、Milvus和Elasticsearch的性能,那么在选择向量数据库时,除了性能还需要考虑哪些因素呢?
原文内容
向量检索应用场景
非结构化数据(语音、图像、视频)检索
大模型知识记忆
搜索、推荐、广告
常见向量检索方法
Brute Force方法
ANN方法

基于树的方法
基于聚类的方法
基于量化的方法
基于哈希的方法
基于图的方法
异构计算
向量检索性能优化
HNSW算法分析
图结构
检索过程
|
数据集
|
|
ef 参数
|
召回率
|
有效距离计算占比
|
|
gist
|
10
|
100
|
95.9%
|
58.8%
|
|
10
|
400
|
99.5%
|
31.4%
|
|
|
100
|
200
|
96.7%
|
89.8%
|
|
|
100
|
250
|
97.9%
|
89.7%
|
|
|
sift
|
10
|
50
|
98.4%
|
49.8%
|
|
10
|
75
|
99.3%
|
39.7%
|
|
|
100
|
125
|
98.5%
|
83.9%
|
|
|
100
|
200
|
99.6%
|
71.3%
|
|
|
拍立淘
|
10
|
100
|
98.8%
|
26.9%
|
|
10
|
200
|
99.3%
|
16.6%
|
|
|
100
|
200
|
95.4%
|
72.1%
|
|
|
100
|
500
|
98.4%
|
51.0%
|
从表 1 可以看到,在各种数据集的场景下,HNSW 的检索都存在不必要的计算,部分场景的有效计算甚至不到总计算量的 20%。倘若可以在检索时进行判断,提前终止游走,就可以节省这部分距离计算,从而在不影响召回率的情况下提升 qps。
-
构建阶段的优化:优化图结构,使图的出度入度更加合理,更利于 ANN 搜索;
-
检索阶段的优化:减少距离计算操作的开销,以及预测检索游走时所需的总步数,当到达预期步数时可以提前终止检索,以减少计算开销。
自适应终止算法




自适应距离比较算法
。
-
虚无假设H0 : 当前真实距离
。 -
对立假设
。 -
取显著值p为
, 其中c0是常量,而
是一个调出来的经验值。 -
假设H0成立,这样根据Johnson–Lindenstrauss lemma 事件
的概率一定小于显著值p。 -
我们检测 事件 𝑑𝑖𝑠′ > (1 + 𝜖0/ 𝑑) · 𝑟 是否发生,如果发生那么H0不成立,及对立假设
成立,反之亦然。
可以看出随着d的增大近似距离dis'会逐渐更加精确,那么对于
的object会更容易被假设检验识别出来,而且真实距离dis越大的object越容易在更小的d维度就被假设检验识别出来(占大多数的negative DCO),从而大大节省计算量。
实验结果
(a). gist,top 10
(b). sift,top 100
-
在 gist 数据集上,召回率由 99.53% 变为 99.51% 时,qps 由 125.11 上升为 240.61,提升 92.3%;
-
在 sift 数据集上,召回率为 99.88% 时,qps 由 670.40 上升为 814.80,提升 21.5%;
-
在拍立淘数据集上,召回率由 99.20% 变为 99.19% 时,qps 由 80.42 上升为 139.72,提升 73.7%。
典型向量检索产品功能对比
|
阿里云OpenSearch
|
Pinecone
|
Milvus
|
Elastic
|
|
|
首次发布时间
|
2021年12月31日
|
2021年1月
|
2019年10月22日
|
2023年7月26日
|
|
定位
|
大规模向量实时检索
|
向量数据库
(强调AI模型长期记忆)
|
向量数据库
|
检索和分析引擎
(支持向量检索)
|
|
开源
|
否
|
否
|
是
|
是
|
|
运维方式
|
全托管
|
全托管
|
自运维
|
自运维
|
|
向量算法
|
Linear(暴力检索)
QC(聚类)
HNSW
|
PQ、LSH、HNSW
产品自动选择合适算法
|
FLAT、IVF_FLAT、IVF_PQ
IVF_SQ8、HNSW、ANNOY
|
Brute-Force kNN
HNSW
|
|
向量维度
|
无限制
|
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加速
支持多数据源
阿里巴巴内部场景打磨
大模型生态结合
|
简单易用
动态算法选择
大模型生态结合
|
依托开源社区生态
向量领域品牌影响力大
|
依托开源社区生态
检索和分析领域品牌影响力大
|
向量检索性能对比
阿里云OpenSearch vs. Milvus vs. ElasticSearch
|
阿里云OpenSearch
|
Milvus
|
ElasticSearch
|
|
|
测试集
|
ANN_GIST1M 960维(http://corpus-texmex.irisa.fr/)
|
||
|
产品版本
|
向量检索版2023.8(VectorStore引擎)
|
v2.2.12
|
v8.9
|
|
机器规格
|
16核64G
|
16核64G
|
16核64G
|
|
测试工具
|
wrk(https://github.com/wg/wrk)
压测参数:
线程:8 连接数:24
|
Milvus Python SDK:
https://milvus.io/docs/install-pymilvus.md
压测参数:
线程:8 连接数:24
|
wrk(https://github.com/wg/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=10
num_candidates=20
|
|
QPS: 1619.18
Latency(avg):14.95ms
CPU负载:92.4%
内存占用:8.4G
|
QPS: 827.36
Latency(avg): 28.96ms
CPU负载:91.3%
内存占用:5.6G
|
QPS: 547.63
Latency(avg):46.45ms
CPU负载:97%
内存占用:32G(JVM)
|
|
|
top10 recall@99
|
查询参数:
ef=450
|
查询参数:
ef=100
|
查询参数: k=10
num_candidates=55
|
|
QPS: 863.43
Latency(avg):28.16ms
CPU负载:95.7%
内存占用:8.4G
|
QPS: 475.61
Latency(avg):50.44ms
CPU负载:98.2%
内存占用:5.5G
|
QPS: 305.90
Latency(avg):79.24ms
CPU负载:97.5%
内存占用:32G(JVM)
|
|
|
top10 recall@99.5
|
查询参数:
ef=780
|
查询参数:
ef=150
|
查询参数: k=10
num_candidates=80
|
|
QPS: 593.62
Latency(avg):40.66ms
CPU负载:97.3%
内存占用:8.8G
|
QPS: 359.31
Latency(avg): 66.5ms
CPU负载:98.3%
内存占用:5.6G
|
QPS: 244.81
Latency(avg):98.40ms
CPU负载:98.2%
内存占用:32G(JVM)
|
|
异构计算性能对比(阿里云OpenSearch vs. Milvus)
|
阿里云OpenSearch
|
Milvus
|
阿里云OpenSearch
(GPU:RTX 2080Ti)
|
Milvus
(GPU:RTX 2080Ti)
|
|
|
测试集
|
ANN_GIST1M 960维(http://corpus-texmex.irisa.fr/)
|
|||
|
测试工具
|
wrk(https://github.com/wg/wrk)
|
Milvus Python SDK:
https://milvus.io/docs/install-pymilvus.md
|
wrk(https://github.com/wg/wrk)
|
Milvus Python SDK:
https://milvus.io/docs/install-pymilvus.md
|
|
产品版本
|
向量检索版2023.8(VectorStore引擎)
|
v2.3.0 beta
|
向量检索版2023.8(VectorStore引擎)
|
v2.3.0 beta
|
|
产品规格
|
24核92G
|
24核92G
|
24核92G GPU:RTX 2080Ti
|
24核92G GPU:RTX 2080Ti
|
|
参数配置
|
中心点:400*40
|
nlist: 9000
|
中心点:500*50
|
nlist: 9000
|
|
向量算法
|
QC
|
IVF_SQ8
|
QC
|
GPU_IVF_SQ8
|
|
数据导入耗时
|
1056s
|
762.371s
|
1013s
|
435s
|
|
索引大小
|
1090M
|
929M
|
975M
|
1011M
|
|
top10 recall@95
|
查询参数:nq=1,scan_ratio=0.06
QPS: 674.55
Latency(avg):35.58ms
CPU负载:97.4%
内存占用:4.9G
|
查询参数:nq=1,nprobe=80
QPS: 556.12
Latency(avg):43.15ms
CPU负载:97.9%
内存占用:5.3G
|
查询参数:nq=1,scan_ratio=0.06
QPS: 1388.58
Latency(avg):17.25ms
CPU负载:55.6%
内存占用:5.6G
GPU负载:45%
显存占用:1.3G
|
查询参数:nq=1,nprobe=120
QPS: 443.57
Latency(avg):54.05ms
CPU负载:17.1%
内存占用:4.9G
GPU负载:80%
显存占用:3.7G
|
|
-
|
-
|
查询参数:nq=10, scan_ratio=0.06
QPS: 6199.2
Latency(avg):41.25ms
CPU负载:82.2%
内存占用:5.7G
GPU负载:68%
显存占用:1.4G
|
查询参数:nq=10, nprobe=120
QPS: 2186.31
Latency(avg):109.77ms
CPU负载:11.9%
内存占用:4.9G
GPU负载:90%
显存占用:3.7G
|
|
|
top100 recall@95
|
查询参数:nq=1,scan_ratio=0.07
QPS: 611.80
Latency(avg):39.25ms
Latency(p99):53.62ms
CPU负载:98.6%
内存占用:4.9G
|
查询参数:nq=1,nprobe=115
QPS: 457.45
Latency(avg):52.45ms
CPU负载:97.5%
内存占用:6.8G
|
查询参数:nq=1,scan_ratio=0.07
QPS: 1368.13
Latency(avg):17.55ms
CPU负载:54.8%
内存占用:5.6G
GPU负载:47%
显存占用:1.3G
|
查询参数:nq=1,nprobe=200
QPS: 328.12
Latency(avg):73.14ms
CPU负载:14.1%
内存占用:4.9G
GPU负载:85%
显存占用:3.7G
|
|
-
|
-
|
查询参数:nq=10, scan_ratio=0.07
QPS: 6058.2
Latency(avg):43.22ms
CPU负载:74.9%
内存占用:5.6G
GPU负载:75%
显存占用:1.4G
|
查询参数:nq=10, nprobe=200
QPS: 1195.95
Latency(avg):200.68ms
CPU负载:10.4%
内存占用:4.9G
GPU负载:94%
显存占用:3.7G
|
|
对比总结
阿里云开发者社区,千万开发者的选择
阿里云开发者社区,百万精品技术内容、千节免费系统课程、丰富的体验场景、活跃的社群活动、行业专家分享交流,欢迎点击【阅读原文】加入我们。
















