更新时间:2024-11-20 GMT+08:00

向量检索特性介绍

向量检索支持对图像、视频、语料等非结构化数据提取的特征向量数据进行最近邻或近似近邻检索。

原理说明

向量检索从本质上讲,其思维框架和传统的检索方法没有区别。为了提升向量检索的性能,通常需要解决以下两个问题:

  • 减少候选向量集

    和传统的文本检索类似,向量检索也需要某种索引结构来避免在全量的数据上做匹配,传统文本检索是通过倒排索引来过滤掉无关文档,而向量检索是通过对向量建立索引结构来绕过不相关的向量,减小需要考察的范围。

  • 降低单个向量计算的复杂度

    向量检索支持漏斗模型,先对所有向量进行量化和近似计算,筛选出一定量接近检索目标的数据集,然后基于筛选的数据集进行精细的计算和排序。本方法不需要对所有向量都进行复杂的计算,可以有效提高检索效率。

向量检索即在一个给定的向量数据集中,按照某种度量方式,检索出与查询向量相近的K个向量(K-Nearest Neighbor,KNN),但由于KNN计算量过大,通常只关注近似近邻(Approximate Nearest Neighbor,ANN)问题。

功能介绍

云搜索服务的向量检索引擎集成了暴力检索、图索引(HNSW)、乘积量化、IVF-HNSW等多种向量索引,支持欧式、内积、余弦、汉明等多种相似度计算方式,召回率和检索性能均优于开源引擎。能够满足高性能、高精度、低成本、多模态等多种应用场景及需求。

向量检索支持原生Elasticsearch的所有能力,包括分布式、多副本、错误恢复、快照、权限控制等;兼容所有原生Elasticsearch生态,包括集群监测工具Cerebro,可视化工具Kibana,实时数据采集工具Logstash等;提供Python/Java/Go/C++等多种客户端语言支持。

约束限制

  • 仅Elasticsearch 7.6.2、Elasticsearch 7.10.2、OpenSearch 1.3.6集群支持CSS服务的向量检索引擎。
  • 向量检索插件涉及较高的内存计算,内存要求比普通索引高,建议集群选择“内存优化型”的计算规格。
  • 集群数据节点或冷数据节点的内存规格要大于16G,否则无法使用CSS服务的向量检索插件,如果需要开启则请联系技术支持。

向量检索的集群规格规划

向量检索的索引构建与查询均使用堆外内存,所以集群容量与索引类型、总堆外内存大小等因素相关。通过预估全量索引所需的堆外内存大小,可以选择合适的集群规格。由于向量索引内存占用较高,CSS对于内存规格为8GB及以下的集群默认禁用了向量检索插件。

不同类型的索引所需堆外内存大小的预估方式不同,计算公式如下:
  • GRAPH类索引

    mem_needs = (dim x dim_size + neighbros x 4) x num + delta

    如果有实时更新索引的需求,还需要考虑向量索引构建和自动merge所需的堆外内存开销,保守估计需要1.5~2倍mem_needs。

  • PQ类索引

    mem_needs = frag_num x frag_size x num + delta

  • FALT、IVF索引

    mem_needs = dim x dim_size x num + delta

表1 参数说明

参数

说明

dim

向量维度。

neighbors

图节点邻居数,默认值为64。

dim_size

每一维度值所需的字节数,默认为float类型,需要4字节。

num

向量总条数。

delta

元数据大小,该项通常可以忽略。

frag_num

量化编码时的向量分段数,创建索引时如果未配置该值,则由向量维度“dim”决定。

if dim <= 256: 
  frag_num = dim / 4
elif dim <= 512: 
  frag_num = dim / 8
else :
  frag_num = 64

frag_size

量化编码时中心点编码的size,默认为1。

基于上述计算方法,可预估出完整向量索引所需堆外内存的大小。选择集群规格时,还需考虑每个节点的堆内存开销。

节点的堆内存分配策略:每个节点的堆内存大小为节点物理内存的一半,且最大不超过31GB。

例如,基于SIFT10M数据集创建GRAPH索引,其“dim”“128”“dim_size”“4”“neighbors”采用默认值“64”“num”“1000万”,将各值代入上述公式得到GRAPH索引所需堆外内存大小约为7.5GB,计算公式为“mem_needs = (128 x 4 + 64 x 4) x 10000000 ≈ 7.5”

同时考虑到堆内存的开销,单台“8U 16G”规格的机器可以满足该场景的需求。如果实际场景还有实时写入或更新的需求,则需要考虑申请更大的内存规格。