不论是RAG,还是Agent,几乎每个LLM驱动的应用程序都可能会用到向量数据库。那么,向量数据库是什么?与传统数据库有何不同?又如何选择向量数据库呢?本文是老码农关于向量数据库的学习笔记。
首先,我们需要理解什么是向量?
向量是基于不同特征或属性来描述对象的数据表示。每个向量代表一个单独的数据点,例如一个词或一张图片,由描述其许多特性的值的集合组成。这些变量有时被称为“特征”或“维度”。例如,一张图片可以表示为像素值的向量,整个句子也可以表示为单词嵌入的向量。
一些常用的数据向量如下:
向量数据库是一种将数据存储为高维向量的数据库,高维向量是特征或属性的数学表示。每个向量都有一定数量的维度,根据数据的复杂性和粒度,维度可以从几十到几千不等。向量通常是通过对原始数据(如文本、图像、音频、视频等)应用某种变换或嵌入函数来生成的。嵌入函数可以基于各种方法,例如机器学习模型、单词嵌入、特征提取算法。向量数据库采用索引策略来简化向量相似的特定查询。这在机器学习应用程序中特别有用,因为相似性搜索经常用于发现可比较的数据点或生成建议。
向量数据库的主要功能包括:
向量数据库的构建是为了适应向量嵌入的特定结构,并且它们使用索引算法根据向量与查询向量的相似性来有效地搜索和检索向量。
向量数据库的工作原理可以通过CPU和GPU的工作原理进行类比。CPU和GPU分别是计算机的运算和图形处理核心,而向量数据库则是大模型的记忆和存储核心。在大模型学习阶段,向量数据库接收多模态数据进行向量化表示,让大模型在训练时能够更高效地调用和处理数据。通过多线程机制和矩阵运算,GPU提供了强大的计算能力,让大模型的训练变得更加快速和高效。
区别于传统数据库,向量数据库主要有三点不同:数据向量化,向量检索和相似度计算。数据的向量化采用embedding技术,嵌入作为一个桥梁,将非数字数据转换为机器学习模型可以使用的形式,使它们能够更有效地识别数据中的模式和关系。一般的,文本是一维向量,图像是二维矩阵,视频相当于三维矩阵。这些嵌入实质上是存储数据的上下文表示的数字列表(即向量)。在存储层内,数据库以m个向量堆栈的形式存储,每个向量使用n个维度表示一个数据点,总大小为m×n。为了查询性能的原因,这些堆栈通常通过分片进行划分。
向量检索是输入一个向量,从数据库中查找与输入向量最相似的topN个向量返回。要在向量数据库中执行相似性搜索和检索,需要使用表示所需信息或条件的查询向量。查询向量可以从与存储向量相同类型的数据导出,或者从不同类型的数据导出。使用相似性度量来计算两个向量在向量空间中的距离。相似性度量可以基于各种度量,如余弦相似性、欧氏距离、向量内积,hamming距离、jaccard指数。
其中,向量检索算法是向量数据库的核心之一。向量检索可以看为是近似最近邻搜索,通过预先的索引构建来减小数据查询时的搜索空间,加快检索速度。目前主要的几种检索算法有:
向量数据库中的索引可以按照数据结构和压缩级别两个层次进行组织实现。根据数据结构建立索引的分类如下:
根据数据压缩方式建立索引,主要包括平坦压缩和量化压缩。平坦压缩是指以未经修改的形式存储向量的索引,量化中索引的底层向量被分解成由较少字节组成的块(通常通过将浮点数转换为整数)以减少内存消耗和搜索过程中的计算成本。
相似性搜索和检索的结果通常是与查询向量具有最高相似性得分的向量的排序列表。然后,您可以访问与原始源或索引中的每个向量关联的相应原始数据。
根据向量数据库的的实现方式,我们可以将向量数据库大致分为4类:原生的向量数据库、支持向量的全文检索数据库、支持向量的NoSQL数据库和支持向量的关系型数据库。
原生的向量数据库是专门为存储和检索向量而设计的。包括Chroma,LanceDB,Marqo,Milvus/Zilliz,Pinecone,Qdrant,Vald,Vespa,Weaviate等,所管理的数据是基于对象或数据点的向量表示进行组织和索引。这里只介绍其中的三种,具体信息可以参考各自的官网。
Faiss是一个用于高效相似性搜索和密集向量聚类的开源库。Faiss是用C++编写的,带有完整的Python/numpy包装器,一些常用算法都有GPU实现,成为了很多开源向量数据库的基础。
Faiss支持多种向量搜索技术,提供了能够在不同大小的向量集中搜索的算法,甚至可以处理那些超过内存容量的向量集。
Faiss的主要优势之一是速度和可扩展性,即使在具有数十亿个向量的数据集中也可以进行快速搜索。此外,还提供了用于评估和调整参数的辅助代码。
Pinecone是一个基于云的向量数据库,可以开发实时相似性搜索应用,能够以毫秒级的延迟存储和探索高维向量嵌入,适用于推荐系统、图片和视频搜索以及自然语言处理等应用。
Pinecone的主要功能包括自动索引、实时更新、查询自动调整和用于与当前流程进行简单交互的RESTAPI。其架构专为可扩展性和稳健性而构建,可以轻松管理海量数据,同时保持高可用性。
Pinecone是一个可以托管的向量数据库平台,也就是说有商用方案,也有免费使用方案。其主要特点包括:
Pinecone采用了多种安全措施来保护用户的数据安全和隐私。多层次的访问控制机制可以控制用户的访问权限和操作权限,同时采用了数据加密、传输加密等技术来保护数据的安全性,还提供了数据备份和恢复等功能,可以防止数据丢失和损坏。
Pinecone在性能方面表现非常出色,它能够支持高达1百万次的QPS,且具有低延迟和高吞吐量的特点,还具有分布式部署、实时索引构建和高效的向量相似度搜索等优点,可以帮助用户快速处理大规模的向量数据。
此外,Pinecone还支持多种编程语言和框架,如Python、Java、TensorFlow等,使得用户可以轻松地将其集成到自己的应用程序中。
Milvus是一个开源的分布式向量数据库,它具备高可用、高性能、易拓展的特点,用于海量向量数据的实时召回。
Milvus基于Faiss、Annoy、HNSW等向量搜索库构建,可以轻松管理数百万个实体,可以根据不同的数据特点选择最合适的索引算法,核心是解决稠密向量相似度检索的问题。在向量检索的基础上,Milvus支持数据分区分片、数据持久化、增量数据摄取、标量向量混合查询、timetravel等功能,同时大幅优化了向量检索的性能,可满足任何向量检索场景的应用需求。
Milvus还具有分布式部署、高可用性和高扩展性等优点,可以帮助用户快速处理海量的向量数据。它也提供了多种安全措施来保护用户的数据安全和隐私,支持SSL/TLS加密和访问控制等技术,可以防止数据被非法访问和窃取,还提供了数据备份和恢复等功能,可以保护数据的完整性和可用性。
此外,Milvus还提供了多种客户端SDK,如Python、Java、C++等,使得用户可以方便地使用不同的编程语言来访问和操作Milvus。
这类数据库包括Elastic/Lucene、OpenSearch和Solr。它们都具有丰富的文本检索功能,如可定制的标记器,分词器,停用词列表和N-grams等,大部分都基于开源库,且有大型集成的生态系统,包括了向量库。
例如,Elasticsearch,是一个支持各种类型数据的分布式搜索和分析引擎。Elasticsearch在7.3版本中,添加了对向量数据索引的支持,支持混合查询,但是向量检索采用的仍然是暴力计算,性能损耗较大。在8.0版本引入了knnsearch其实就是一种近似最近邻搜索算法,相似度支持欧式距离,点积和余弦相似性,knnsearch底层其实使用的是HNSW。遗憾的是,这种方式无法进行混合检索。
几乎所有这些NoSQL数据库都是最近才通过添加向量搜索扩展而具备向量能力的,所以如果要是使用的话一定要做好测试。Cassandra,Rockset,AzureCosmosDB和MongoDB等都纷纷宣布了增加向量搜索的计划。NoSQL数据库的向量搜索性能可能差别很大,这取决于所支持的向量函数、索引方法和硬件加速。
对于支持向量的NoSQL数据库,探索尝试未尝不可,但在生产环境中使用要慎之又慎。
这些大都是关系型数据库并且支持sql查询,例如SingleStoreDB,PostgreSQL,Clickhouse和Kinetica的pgvector/SupabaseVector等。它们都宣布包含了向量搜索功能,如点积,余弦相似度,欧几里得距离和曼哈顿距离,并且使用相似度分数找到n个最近邻。由于提供了混合查询,可以将向量与其他数据结合起来以获得更有意义的结果。另外,大多数SQL数据库都可以作为服务部署,可以在云上进行完全的管理。
例如,Postgres通过pg_vector和pg_embdding两个插件来实现向量数据库,让PG数据库支持向量索引检索的能力。其索引算法使用的是基于Faiss的IVFFlat索引,提供了优异的召回率。
Chroma是一个Python/TypeScript包装器,基于C++编程语言的有OLAP数据库Clickhouse以及开源向量索引HNSWLib。但如今,快速响应且可扩展的数据库通常使用现代语言如Golang或Rust编写。在专为向量数据库而构建的供应商中,唯一使用Java构建的是Vespa。
Pinecone是完全闭源的,Zilliz也是一个闭源的完全托管的商业解决方案,但它完全建立在Milvus之上,其他向量数据库至少在代码库方面是源代码可用的,具体的许可证决定了代码的可许可性以及如何部署。
众多向量数据库的检索算法都采用了HNSW,其中,Milvus的检索算法支持最为丰富。
向量数据库的典型部署方式包括本地部署和托管/云原生,两者都遵循CS架构。还有一种新的选择是嵌入式模式,其中数据库本身与应用程序代码紧密耦合,以serverless的方式运行。目前,只有Chroma和LanceDB可用作嵌入式数据库。
综上所述,主流向量数据库的部分指标对比如下:
此外,在选择向量数据库时,还需要特别考量以下因素:
传统数据库,如关系数据库,旨在存储结构化数据。这意味着数据被组织到预定义的表、行和列中,确保数据的完整性和一致性。传统数据库往往针对CRUD进行优化,旨在高效地创建、读取、更新和删除数据条目,使其适用于从Web服务到企业软件的各种应用程序。但是,一旦定义了数据库结构,进行更改可能会非常复杂且耗时。这种刚性可确保数据一致性,但灵活性可能不如某些现代数据库的无模式或动态模式性质。
特别地,向量数据库与图数据库的对比如下:
借助向量数据库,我们能够快速加载和存储事件作为嵌入,并使用向量数据库作为为AI模型提供动力的大脑,提供上下文信息,长期记忆检索,语义上的数据关联等等。向量数据库的典型使用方式如下:1.使用embeding技术创建向量2.将这些向量存储到向量数据库3.应用索引策略来组织管理向量4.使用查询向量执行相似性搜索5.从向量数据库中取得相似的向量
由于向量数据库将要查询的数据存储为嵌入向量,并且语言模型(LLM)也将其内部的知识编码为嵌入向量,因此在生成式问答应用中是天生一对。向量数据库充当知识库的功能,而LLM可以直接在嵌入空间中查询数据的子集,一般可以使用以下方法进行操作:
同样,向量数据库也面临着许多与其他数据库技术相同的挑战,需要继续努力提高可扩展性、近似精度、延迟性能和经济性。许多向量数据库在核心数据库能力方面需要提升,例如安全性、弹性、运营支持和工作负载支持的多样化。随着AI应用的成熟,未来需要的不仅仅只限于向量搜索功能。