为什么以及何时需要专用向量数据库?
本文最初发表于AIAI,经授权在此转发。
ChatGPT和其他大型语言模型 (LLM) 的日益普及推动了向量搜索技术的兴起,其中包括Milvus和Zilliz Cloud 等专用向量数据库、FAISS 等向量搜索库以及与传统数据库集成的向量搜索插件。然而,选择满足您需求的最佳解决方案可能具有挑战性。就像在高端餐厅和快餐连锁店之间做出选择一样,选择合适的矢量搜索技术取决于您的需求和期望。
在本篇文章中,我将概述矢量搜索及其功能,比较不同的矢量搜索技术,并解释为什么选择专用的矢量数据库至关重要。
什么是向量搜索,它是如何工作的?
向量搜索又称向量相似性搜索,是一种在大量密集向量数据 Collections 中检索与给定查询向量最相似或语义最相关的 top-k 结果的技术。
在进行相似性搜索之前,我们先利用神经网络将文本、图像、视频和音频等非结构化数据转化为称为 Embeddings 向量的高维数值向量。例如,我们可以使用预先训练好的 ResNet-50 卷积神经网络,将鸟类图像转化为 2048 维的嵌入向量 Collections。在此,我们列出前三个和后三个向量元素:[0.1392, 0.3572, 0.1988, ..., 0.2888, 0.6611, 0.2909]
。
Patrice Bouchard 拍摄的鸟类图像
生成嵌入向量后,向量搜索引擎会比较输入查询向量和向量存储中的向量之间的空间距离。它们在空间上的距离越近,相似度就越高。
嵌入运算
流行的向量搜索技术
市场上有多种向量搜索技术,包括 Python 的 NumPy 等机器学习库、FAISS 等向量搜索库、基于传统数据库构建的向量搜索插件,以及 Milvus 和 Zilliz Cloud 等专业向量数据库。
机器学习库
使用机器学习库是实现向量搜索的最简单方法。例如,我们可以使用 Python 的 NumPy 在 20 行代码以内实现近邻算法。
import numpy as np
# Function to calculate euclidean distance
def euclidean_distance(a, b):
return np.linalg.norm(a - b)
# Function to perform knn
def knn(data, target, k):
# Calculate distances between target and all points in the data
distances = [euclidean_distance(d, target) for d in data]
# Combine distances with data indices
distances = np.array(list(zip(distances, np.arange(len(data)))))
# Sort by distance
sorted_distances = distances[distances[:, 0].argsort()]
# Get the top k closest indices
closest_k_indices = sorted_distances[:k, 1].astype(int)
# Return the top k closest vectors
return data[closest_k_indices]
我们可以生成 100 个二维向量,并找到向量 [0.5, 0.5] 的最近邻。
# Define some 2D vectors
data = np.random.rand(100, 2)
# Define a target vector
target = np.array([0.5, 0.5])
# Define k
k = 3
# Perform knn
closest_vectors = knn(data, target, k)
# Print the result
print("The closest vectors are:")
print(closest_vectors)
机器学习库(如 Python 的 NumPy)以低成本提供了极大的灵活性。不过,它们也有一些局限性。例如,它们只能处理少量数据,而且不能确保数据的持久性。
我只建议在以下情况下使用 NumPy 或其他机器学习库进行向量搜索:
- 需要快速建立原型。
- 不关心数据持久性。
- 数据量小于一百万,不需要标量过滤。
- 不需要高性能。
向量搜索库
向量搜索库可以帮助您快速构建高性能的向量搜索原型系统。FAISS 就是一个典型的例子。它是开源的,由 Meta 公司开发,用于高效的相似性搜索和密集向量聚类。FAISS 可以处理任何大小的向量 Collections,甚至可以处理那些无法完全加载到内存中的向量 Collections。此外,FAISS 还提供了评估和参数调整工具。尽管 FAISS 是用 C++ 编写的,但它提供了 Python/NumPy 接口。
下面是基于 FAISS 的向量搜索示例代码:
import numpy as np
import faiss
# Generate some example data
dimension = 64 # dimension of the vector space
database_size = 10000 # size of the database
query_size = 100 # number of queries to perform
np.random.seed(123) # make the random numbers predictable
# Generating vectors to index in the database (db_vectors)
db_vectors = np.random.random((database_size, dimension)).astype('float32')
# Generating vectors for query (query_vectors)
query_vectors = np.random.random((query_size, dimension)).astype('float32')
# Building the index
index = faiss.IndexFlatL2(dimension) # using the L2 distance metric
print(index.is_trained) # should return True
# Adding vectors to the index
index.add(db_vectors)
print(index.ntotal) # should return database_size (10000)
# Perform a search
k = 4 # we want to see 4 nearest neighbors
distances, indices = index.search(query_vectors, k)
# Print the results
print("Indices of nearest neighbors: \n", indices)
print("\nL2 distances to the nearest neighbors: \n", distances)
FAISS 等矢量搜索库易于使用,速度快,足以处理拥有数百万矢量的小规模生产环境。您可以利用量化和 GPU 以及减少数据维度来提高它们的查询性能。
不过,这些库在生产环境中使用时有一些限制。例如,FAISS 不支持实时数据添加和删除、远程调用、多语言、标量过滤、可扩展性或灾难恢复。
不同类型的向量数据库
向量数据库的出现解决了上述库的局限性,为生产应用提供了更全面、更实用的解决方案。
目前战场上有四种类型的向量数据库:
- 集成了向量搜索插件的现有关系型或列型数据库。PG Vector 就是一个例子。
- 支持密集向量索引的传统倒排索引搜索引擎。ElasticSearch就是一个例子。
- 基于向量搜索库构建的轻量级向量数据库。Chroma 就是一个例子。
- 专用向量数据库。这类数据库专门为向量搜索而设计,并自下而上地进行了优化。专用向量数据库通常提供更先进的功能,包括分布式计算、灾难恢复和数据持久性。Milvus就是一个主要的例子。
并非所有的向量数据库都是一样的。每个堆栈都有独特的优势和局限性,因此或多或少适合不同的应用。
与其他解决方案相比,我更喜欢专用向量数据库,因为它们是最高效、最方便的选择,具有众多独特优势。在下面的章节中,我将以 Milvus 为例,解释我偏爱的原因。
专用向量数据库的主要优势
Milvus是一个开源、分布式的专用向量数据库,可以存储、索引、管理和检索数十亿个嵌入向量。它也是用于LLM 检索增强生成的最受欢迎的向量数据库之一。作为专门构建的向量数据库的典范实例,Milvus 与其同行共享许多独特的优势。
数据持久性和低成本存储
虽然防止数据丢失是对数据库的最低要求,但许多单机和轻量级向量数据库并不把数据可靠性放在首位。相比之下,Milvus等专门构建的分布式向量数据库通过分离存储和计算,优先考虑了系统弹性、可扩展性和数据持久性。
此外,大多数利用近似近邻(ANN)索引的向量数据库都需要大量内存来执行向量搜索,因为它们将 ANN 索引纯粹加载到内存中。然而,Milvus 支持磁盘索引,使存储的成本效益比内存索引高十倍以上。
最佳查询性能
与其他向量搜索方案相比,专门的向量数据库可提供最佳的查询性能。例如,Milvus 处理查询的速度比向量搜索插件快十倍。Milvus 使用ANN 算法而不是 KNN 野蛮搜索算法,以实现更快的向量搜索。此外,Milvus 还对索引进行碎片化处理,从而在数据量增加时减少构建索引所需的时间。这种方法使 Milvus 能够轻松处理数十亿向量的实时数据增删。相比之下,其他向量搜索插件只适用于数据量少于数千万、添加和删除不频繁的场景。
Milvus 还支持 GPU 加速。内部测试显示,在搜索数千万数据时,GPU 加速的向量索引可达到 10,000+ QPS,在单机查询性能上比传统的 CPU 索引至少快十倍。
系统可靠性
许多应用使用向量数据库进行在线查询,要求低查询延迟和高吞吐量。这些应用要求在分钟级进行单机故障切换,有些甚至要求在关键场景下进行跨区域灾难恢复。基于 Raft/Paxos 的传统复制策略存在严重的资源浪费问题,并且需要帮助预先分片数据,导致可靠性较差。相比之下,Milvus 采用分布式架构,利用 K8s 消息队列实现高可用性,缩短了恢复时间,节省了资源。
操作符和可观察性
为了更好地服务企业用户,向量数据库必须提供一系列企业级功能,以获得更好的操作符和可观察性。Milvus 支持多种部署方法,包括 K8s Operator 和 Helm 图表、docker-compose 和 pip install,使不同需求的用户都能使用。Milvus 还提供了基于 Grafana、Prometheus 和 Loki 的监控和报警系统,提高了其可观察性。Milvus 采用分布式云原生架构,是业界首个支持多租户隔离、RBAC、配额限制和滚动升级的向量数据库。所有这些方法都使 Milvus 的管理和监控变得更加简单。
在 10 分钟内通过 3 个简单步骤开始使用 Milvus
建立向量数据库是一项复杂的任务,但使用向量数据库就像使用 Numpy 和 FAISS 一样简单。即使是不熟悉人工智能的学生,也能在短短十分钟内基于 Milvus 实现向量搜索。要体验高度可扩展和高性能的向量搜索服务,请遵循以下三个步骤:
- 借助 Milvus部署文档在服务器上部署 Milvus。
- 参考Hello Milvus 文档,仅用 50 行代码实现向量搜索。
- 探索Towhee 的示例文档,深入了解向量数据库的流行用例。
Try Managed Milvus for Free
Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.
Get StartedLike the article? Spread the word