向量数据库基准测试

对向量数据库进行基准测试

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

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

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

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

单节点基准测试

我们使用不同配置的多个向量数据库在不同数据集上进行基准测试,以检查结果可能如何变化。这些数据集可能具有不同的向量维度,但在所使用的距离函数方面也有所不同。我们还试图捕获在使用一些不同配置参数时可能预期的差异,这些参数既包括引擎本身,也包括单独的搜索操作。

更新时间:2024 年 1 月/6 月

下载原始数据:此处

观察结果

上次运行以来,大多数引擎都得到了改进。生活和软件都有权衡,但有些显然做得更好

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

如何解读结果

  • 选择您要检查的数据集和指标。
  • 选择一个满足您用例的精度阈值。这很重要,因为 ANN 搜索的全部意义在于用精度换取速度。这意味着在任何向量搜索基准测试中,只有在精度相似的情况下才能比较两个结果。然而,大多数基准测试都忽略了这一关键方面。
  • 表格按所选指标(RPS / 延迟 / p95 延迟 / 索引时间)的值排序,第一项始终是该类别的赢家 🏆

延迟与 RPS

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

  • 每秒请求数 (RPS):以更长的单个请求时间(即更高的延迟)为代价,每秒处理更多请求。这是 Web 应用程序的典型场景,其中多个用户同时进行搜索。为了模拟此场景,我们并行运行客户端请求,并测量引擎每秒可以处理多少个请求。
  • 延迟:快速响应单个请求,而不是并行处理更多请求。这是服务器响应时间至关重要的应用程序的典型场景。自动驾驶汽车、制造机器人和其他实时系统是此类应用程序的良好示例。为了模拟此场景,我们以单线程运行客户端并测量每个请求所需的时间。

测试数据集

我们的基准测试工具灵感来自github.com/erikbern/ann-benchmarks。我们使用以下数据集来测试引擎在 ANN 搜索任务中的性能

数据集向量数维度距离
dbpedia-openai-1M-angular100 万1536余弦
deep-image-96-angular1000 万96余弦
gist-960-euclidean100 万960欧几里得
glove-100-angular1.2M100余弦

设置

Benchmarks configuration

基准测试配置

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

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

过滤搜索基准测试

将过滤器应用于搜索结果带来了全新的复杂性。仅仅对纯数据应用一个算法已不再足够。通过过滤,它变成了不同索引交叉集成的问题。

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

它类似于ann-benchmarks 项目中使用的那些,但增加了有效载荷元数据和预生成的过滤请求。它包括带有各种过滤器的合成和真实世界数据集,从关键字到地理空间查询。

为什么过滤并非易事?

并非所有 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 的 ML 框架。
  2. 根据 GitHub 星标,Python 客户端是所有引擎中最受欢迎的客户端之一。

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

封闭源代码 SaaS 平台怎么样?

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

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

如何重现基准测试?

源代码可在 Github 上找到,并附带一个README.md文件,描述了为特定引擎运行基准测试的过程。

如何贡献?

我们将基准测试开源是因为我们相信它必须是透明的。我们可能错误配置了其中一个引擎,或者只是效率低下。如果您认为可以帮助我们,请查看我们的基准测试存储库