向量数据库基准测试

向量数据库基准测试

在 Qdrant,性能是首要任务。我们始终确保高效利用系统资源,以便您以**最优惠的云成本获得最快、最准确的结果**。因此,从选择 RustI/O 优化无服务器支持二值量化,到我们的fastembed 库,我们所有的决定都基于我们的原则。在本文中,我们将比较 Qdrant 与其他向量搜索引擎的性能表现。

以下是我们设计这些基准测试时遵循的原则

  • 我们进行比较性基准测试,这意味着我们侧重于**相对数值**而非绝对数值。
  • 我们使用经济实惠的硬件,以便您轻松重现结果。
  • 我们在完全相同的机器上运行基准测试,以避免任何可能的硬件偏差。
  • 所有基准测试都是开源的,您可以贡献并改进它们。
测试场景
  1. 单节点上传和搜索基准测试 基准测试
  2. 过滤搜索基准测试 - 基准测试
  3. 内存消耗基准测试 - 即将推出
  4. 集群模式基准测试 - 即将推出

我们的一些实验设计决定在常见问题解答部分中有所描述。如果您想讨论任何与 Qdrant 或这些基准测试相关的问题,请在我们的Discord 频道上联系我们。

单节点基准测试

我们使用不同数据集上的各种配置,对多个向量数据库进行了基准测试,以查看结果可能如何变化。这些数据集可能具有不同的向量维度,并且使用的距离函数也不同。我们还尝试捕捉在使用一些不同的配置参数时可能出现的差异,包括引擎本身和搜索操作的参数。

更新日期:2024年1月/6月

下载原始数据:此处

观察结果

我们上次运行以来,大多数引擎都有所改进。生活和软件都有权衡,但有些引擎表现明显更优

  • **无论我们选择何种精度阈值和指标,Qdrant 在几乎所有场景中都实现了最高的 RPS 和最低的延迟。**它在其中一个数据集上还显示出 4 倍的 RPS 提升。
  • 在许多情况下,Elasticsearch 变得相当快,但在索引时间方面非常慢。存储 1000 万以上 96 维向量时,它可能慢 10 倍!(32 分钟 对比 5.5 小时)
  • Milvus 在索引时间方面最快,并保持了良好的精度。然而,当向量维度更高或向量数量更多时,在 RPS 或延迟方面,它与其它引擎相比稍逊一筹。
  • Redis 能够实现良好的 RPS,但主要是在较低精度下。它在单线程下也实现了低延迟,但随着并行请求的增加,其延迟迅速上升。这种速度提升部分来自于其自定义协议。
  • 自上次运行以来,Weaviate 的改进最小。

如何解读结果

  • 选择您想查看的数据集和指标。
  • 选择一个适合您用例的精度阈值。这很重要,因为 ANN 搜索就是在精度和速度之间进行权衡。这意味着在任何向量搜索基准测试中,**只有在精度相似时才能比较两个结果**。然而,大多数基准测试都忽略了这一关键方面。
  • 表格按所选指标(RPS / 延迟 / p95 延迟 / 索引时间)的值排序,第一个条目始终是该类别的优胜者 🏆

延迟 vs RPS

在我们的基准测试中,我们测试了实践中出现的两种主要搜索使用场景。

  • **每秒请求数 (RPS)**:以单个请求耗时更长(即延迟更高)为代价,每秒处理更多请求。这是网络应用的典型场景,多个用户同时进行搜索。为了模拟这种情况,我们使用多线程并行运行客户端请求,并测量引擎每秒可以处理多少请求。
  • **延迟**:快速响应单个请求,而不是并行处理更多请求。这是对服务器响应时间要求苛刻的应用的典型场景。自动驾驶汽车、工业机器人及其他实时系统是这类应用的典型例子。为了模拟这种情况,我们在单线程中运行客户端,并测量每个请求需要多长时间。

测试数据集

我们的基准测试工具受到了github.com/erikbern/ann-benchmarks 的启发。我们使用以下数据集来测试引擎在 ANN 搜索任务上的性能

数据集向量数维度距离函数
dbpedia-openai-1M-angular100万1536余弦
deep-image-96-angular1000万96余弦
gist-960-euclidean100万960欧氏距离
glove-100-angular120万100余弦

设置

Benchmarks configuration

基准测试配置

  • 这是我们进行本次实验的设置
    • 客户端:8 个 vCPU,16 GiB 内存,64 GiB 存储(Azure Cloud 上的 Standard D8ls v5
    • 服务器:8 个 vCPU,32 GiB 内存,64 GiB 存储(Azure Cloud 上的 Standard D8s v3
  • Python 客户端将数据上传到服务器,等待所有必需的索引构建完成,然后使用配置的线程数执行搜索。我们针对每个引擎重复此过程,采用不同的配置,然后为给定的精度选择最佳配置。
  • 我们在 Docker 中运行所有引擎,并将内存限制为 25GB。这样做是为了确保公平性,避免某些引擎配置过度占用内存。这个 25GB 的限制是完全公平的,因为即使处理最大的 dbpedia-openai-1M-1536-angular 数据集,也很少需要 100万 * 1536 * 4 字节 * 1.5 = 8.6GB 的内存(包括向量 + 索引)。因此,我们决定为所有引擎提供大约 3 倍于需求的内存。

请注意,由于 25GB 内存限制,某些引擎的某些配置在某些数据集上崩溃了。这就是为什么在选择更高的精度阈值时,您可能会看到某些引擎的数据点较少的原因。

过滤搜索基准测试

对搜索结果应用过滤带来了全新的复杂性级别。仅仅对原始数据应用一个算法已经不够了。通过过滤,这变成了一个不同索引之间进行交叉集成的问题。

为了衡量不同搜索引擎在此场景中的表现,我们准备了一套**过滤 ANN 基准数据集** - https://github.com/qdrant/ann-filtering-benchmark-datasets

它与ann-benchmarks 项目中使用的数据集类似,但增加了 Payload 元数据和预先生成的过滤请求。它包含带有各种过滤条件的合成和真实世界数据集,从关键词到地理空间查询。

为什么过滤并非易事?

没有多少 ANN 算法兼容过滤功能。HNSW 是少数支持过滤的算法之一,但搜索引擎集成它的方式各不相同

  • 有些使用**后过滤**,即在 ANN 搜索后应用过滤器。这种方法扩展性不好,因为它要么丢失结果,要么在第一阶段需要大量的候选项。
  • 其他方法使用**预过滤**,这需要将整个数据集的二进制掩码传递给 ANN 算法。这种方法也无法扩展,因为掩码大小随数据集大小线性增长。

除此之外,搜索精度也存在问题。这表现在如果过滤掉太多向量,HNSW 图会变得断开连接。

Qdrant 采用了一种不同的方法,无需预过滤或后过滤,同时解决了精度问题。在我们的可过滤 HNSW 文章中阅读更多关于 Qdrant 方法的信息。

更新日期:2023年2月

下载原始数据:此处

过滤结果

从图表中可以看出,主要有三种模式

  • **速度提升** - 对于某些引擎/查询,过滤搜索比非过滤搜索更快。如果过滤器足够严格,完全避免使用向量索引,就可能发生这种情况。

  • **速度下降** - 一些引擎难以维持高 RPS,这可能与需要为数据集构建过滤掩码有关,如上所述。

  • **精度崩溃** - 一些引擎在某些过滤器下会显著损失精度。这与 HNSW 图变得断开连接,导致搜索变得不可靠有关。

Qdrant 避免了所有这些问题,并且还受益于速度提升,因为它实现了先进的查询规划策略

基准测试常见问题解答

我们是否存在偏见?

可能存在。即使我们努力做到客观,我们也不是所有现有向量数据库的使用专家。我们构建 Qdrant,因此对其了解最多。因此,我们可能忽略了不同向量搜索引擎中的一些重要调整。

然而,我们已尽力做到最好,反复查阅文档,尝试了不同配置的组合,并给予所有引擎同等的表现机会。如果您认为可以做得比我们更好,我们的**基准测试已完全开源,欢迎贡献**!

我们测量什么?

在决定使用哪个数据库时,需要考虑几个因素。当然,其中一些支持不同的功能子集,这可能是做出决定的关键因素。但总的来说,我们都关心搜索精度、速度以及实现这些所需的资源。

有一点很重要——**只有在精度相同时,才能比较向量数据库的速度**。否则,它们可能会通过提供不准确的结果来最大化速度,这是每个人都宁愿避免的。因此,我们的基准测试结果仅在特定的搜索精度阈值下进行比较。

我们如何选择硬件?

在我们的实验中,我们不关注指标的绝对值,而是关注不同引擎之间的相对比较。重要的是我们对所有测试使用了相同的机器。在启动不同引擎之间会擦除机器状态。

我们选择了一台普通机器,您可以轻松地从几乎任何云提供商那里租用。不需要额外的配额或自定义配置。

为什么不与 FAISS 或 Annoy 进行比较?

FAISS 等库为向量搜索实验提供了很棒的工具。但它们距离生产环境的实际使用还有很远的距离。如果您在生产环境中使用 FAISS,最好的情况是您永远不需要实时更新它。最坏的情况是,您必须在其周围构建自定义封装层来支持 CRUD 操作、高可用性、横向扩展、并发访问等等。

一些向量搜索引擎甚至在底层使用 FAISS,但搜索引擎不仅仅是一个索引算法。

不过,我们确实使用了与著名的ann-benchmarks 项目相同的基准数据集,因此出于任何实际原因,您可以调整您的预期。

为什么我们决定使用 Python 客户端进行测试

关于运行基准测试的最佳技术,目前没有共识。您可以自由选择 Go、Java 或 Rust 等系统。但我们使用 Python 进行此测试主要有两个原因

  1. 在生成嵌入向量时,您很可能会使用 Python 和基于 Python 的机器学习框架。
  2. 根据 GitHub 星标数,Python 客户端是所有引擎中最受欢迎的客户端之一。

从用户的角度来看,关键在于使用特定库(在大多数情况下是 Python 客户端)时感知到的延迟。没有人能够,甚至不应该仅仅因为使用某个特定的搜索工具而重新定义整个技术栈。这就是为什么我们决定主要关注数据库作者提供的官方 Python 库。这些库底层可能使用了不同的协议,但最终,我们并不关心数据是如何传输的,只要它最终到达目标位置即可。

关于闭源 SaaS 平台?

有些向量数据库仅作为 SaaS 提供,因此我们无法在与测试其他系统相同的机器上对其进行测试。这使得比较不公平。这就是为什么我们纯粹专注于测试开源向量数据库,以便所有人都能轻松重现基准测试。

这并非最终列表,我们将继续对尽可能多的不同引擎进行基准测试。

如何重现基准测试?

源代码可在Github 上获取,其中包含一个 README.md 文件,描述了针对特定引擎运行基准测试的过程。

如何贡献?

我们将基准测试开源,因为我们相信它必须透明。我们可能配置某个引擎有误,或者只是效率不高。如果您认为可以帮助我们,请查看我们的基准测试仓库