向量检索
功能介绍
人工智能算法可以对物理世界的人/物/场景所产生各种非结构化数据(如语音、图片、视频,语言文字、行为等)进行抽象,变成多维的向量。
这些向量如同数学空间中的坐标,标识着各个实体和实体关系。我们一般将非结构化数据变成向量的过程称为 Embedding
,而非结构化检索则是对这些生成的向量进行检索,从而找到相应实体的过程。
传统的关键词搜索主要依赖于对关键词的匹配,而忽略了查询的含义和语境。但语义搜索的优点在于它可以更好地满足用户的意图,尤其是对于复杂的查询和问题。它能够理解查询的上下文,处理模糊或不完整的查询,并提供更相关和有用的搜索结果。
目前在业务上对向量检索能力进行支持,业界的使用上通常有如下几种:
-
基于开源的向量检索内核(比如faiss/scann/proxima/nmslib等)自己来做服务化,包成一个Restful API形式的在线向量检索服务
-
选用专门的向量检索数据库来支持向量检索的场景
-
选用一个数据库/数仓产品,包含向量检索功能的支持
在绝大多数情况下,使用专用向量数据库的弊都要远远大于利:数据冗余、 大量不必要的数据搬运工作、分布式组件之间缺乏一致性、额外的专业技能带来的复杂度成本、学习成本、以及人力成本、额外的软件许可费用、极其有限的查询语言能力、可编程性、可扩展性、有限的工具链、以及与真正数据库相比更差的数据完整性和可用性。而且在一个分布式的数据库产品里支持向量检索有个好处,可以利用其分布式的能力,可以轻松应对海量向量数据的场景。在支持分布式事务的产品里,对向量的写入、更新和删除同样天然满足分布式事务的强一致性。
ProtonBase 提供向量检索的能力,支持两种索引类型IVFFlat(Inverted File with Flat Quantization)
和HNSW(Hierarchical Navigable Small World)
,实现了高效的向量检索的召回。支持数据的批量导入,实时更新/删除,并且支持条件过滤和向量检索的联合查询。
ProtonBase 通过实现PostgreSQL生态的pgvector
插件进行扩展来支持向量检索的能力,pgvector
有着优雅简单易用的接口,更是继承了PostgreSQL生态的超能力集合。
建表语句
向量数据类型为vector
,最高支持2000维,在声明向量字段的时候需要同时显示标识出其维度信息,内部是个Float类型的数组,这些数组被组成成紧凑的二进制格式以便高效的存储和检索。
CREATE TABLE items
(
id bigserial PRIMARY KEY,
embedding vector(3) -- 定义维度
)
USING columnar;
向量索引
目前距离的度量方式支持三种:
-
<->
- 欧式距离(L2 Distance),索引参数vector_l2_ops
-
<#>
- 内积距离(Inner Product),索引参数vector_ip_ops
-
<=>
- 余弦距离(Cosine Distance),索引参数vector_cosine_ops
根据向量索引类型的不同,在构建的时候可以支持不同的向量索引。
-
IVFFlat
是一种基于倒排索引的近似最近邻搜索算法,用于高效地查询向量之间的相似度。它将向量空间分为若干个划分区域,每个区域都包含一些向量,并创建倒排索引,用于快速地查找与给定向量相似的向量。通过lists参数可以指定聚类的中心点个数。lists数值的选择一般规则为:小于100万行时,lists = rows/1000,大于100万行时,lists = sqrt(rows),能获得比较好的聚类效果。IVFFlat
构建索引速度更快,消耗内存更少,但查询性能略慢。更适合在处理超大数据集时,可以显著减少搜索空间,提高查询效率。 -
HNSW
是一种基于图的索引结构,构建了一个多层次的导航图。HNSW
使用了随机跳跃的方式进行邻近搜索,通过在不同层的图结构中搜索,快速找到相似向量。它消耗内存更多,构建索引更慢,但查询性能更好。在高维数据中表现出更好的查询性能和准确性。
-- 创建欧式距离索引
CREATE INDEX ON items USING split_ivfflat (embedding vector_l2_ops) WITH (lists = 100);
-- 创建内聚距离索引
CREATE INDEX ON items USING split_ivfflat (embedding vector_ip_ops) WITH (lists = 100);
-- 创建余弦距离索引
CREATE INDEX ON items USING split_ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
--导入向量数据
INSERT INTO items (embedding) VALUES ('[1.0,0.0,-1.0]');
注:HNSW方式目前还未正式透出。目前只提供暴力检索
和IVFFlat
的方式。如果不配置索引,会使用暴力检索的方式进行向量检索
查询方式
-- ivfflat.probes 设置考察聚类中心点的个数。该值越大,召回率越高,检索性能越差。当该值等于构建index时指定的lists个数是,退化为暴力检索
-- 全局生效配置
alter system set ivfflat.probes=10;
-- 当前session生效配置,优先级高于全局配置
SET ivfflat.probes = 10;
SELECT *
FROM items
ORDER BY embedding <-> '[3,1,2]'
LIMIT 5;