Elasticsearch BBQ 与 OpenSearch FAISS:矢量搜索性能比较

Elasticsearch BBQ 和 OpenSearch FAISS 的性能比较。

从向量搜索到强大的 REST API,Elasticsearch 为开发人员提供了最全面的搜索工具包。探索 GitHub 上的示例笔记本,尝试新事物。您也可以立即开始免费试用在本地运行 Elasticsearch

二进制量化矢量搜索使用 BBQ 的 Elasticsearch 比使用 FAISS 的 OpenSearch 快 5 倍。Elastic 收到了来自社区的请求,希望澄清 Elasticsearch 和 OpenSearch 之间的性能差异,尤其是在语义搜索/矢量搜索领域,因此我们进行了这些性能测试,以提供清晰的、数据驱动的比较。

二进制量化对决

以原始形式存储高维向量会耗费大量内存。量化技术可将这些矢量压缩为紧凑的表示形式,从而大大减少内存占用。然后,搜索在压缩空间内进行,从而降低了计算复杂度,加快了搜索速度,尤其是在大型数据集中。

Elastic 致力于使 Lucene 成为性能一流的矢量引擎。在 Elasticsearch 8.16 中,我们在 Lucene 的基础上引入了更好的二进制量化(BBQ),并在 8.18 和 9.0 中进一步发展。BBQ 基于一种新的标量量化方法,将 float32 维度减少到比特,在保持高排名质量的同时,减少了 ~95% 内存。

另一方面,OpenSearch 使用多种矢量引擎:nmslib(现已废弃)、Lucene 和 FAISS。在 一篇 博客 中,我们比较了 Elasticsearch 和 OpenSearch 的向量搜索。我们使用了三个不同的数据集,并在两种产品上测试了不同的引擎和配置组合。

本博客重点介绍这两种产品目前提供的二进制量化算法。我们使用 BBQ 对 Elasticsearch 进行了测试,并使用FAISS 的二进制量化openai_vectorRally track)对 OpenSearch 进行了测试。

主要目的是评估两种解决方案在相同召回率下的性能。召回是什么意思?召回率是衡量搜索系统成功检索到多少相关结果的指标。

在这项评估中,recall@k 尤为重要,其中k代表所考虑的顶级结果的数量。因此,Recall@10Recall@50 和 Recall@100分别用来衡量有多少真正相关的结果出现在检索结果的前 10、50 和 100 项中。召回率以 0 到 1 的范围表示(或 0% 到 100% 精确度)。这一点很重要,因为我们讨论的是近似 KNN (ANN),而不是精确 KNN,后者的召回率总是 1 (100%).

对于每个k值,我们还指定了n, 即在应用最终排名之前考虑的候选者数量。这意味着,对于 Recall@10、Recall@50 和 Recall@100,系统首先使用二进制量化算法检索n 个候选项,然后对它们进行排序,以确定前k 个结果是否包含预期的相关项。

通过控制n,我们可以分析效率和精度之间的权衡。较高的n通常会增加召回率,因为有更多候选者可供排序,但同时也会增加延迟和 降低 吞吐量。相反,n越小,检索速度越快,但如果初始集合中包含的相关候选信息太少,则可能会降低召回率。

在这次比较中,Elasticsearch 在相同的设置下比 OpenSearch 的延迟更低,吞吐量更高。

方法

完整的配置,以及 Terraform 脚本、Kubernetes 清单和特定的 Rally 轨道,都可在此仓库 openai_vector_bq 下找到。

与之前的基准测试一样,我们使用的 Kubernetes 集群由以下部分组成:

  • 1 个用于 Elasticsearch 9.0 的节点池,包含 3 台e2-standard-32 机器(128GB 内存和 32 个 CPU)
  • 1 个用于 OpenSearch 2.19 的节点池,包含 3 台e2-standard-32 机器(128GB 内存和 32 个 CPU)
  • 1 个用于 Rally 的节点池,包含 2 台e2-standard-4 机器(16GB 内存和 4 个 CPU)

我们建立了一个版本为 9.0 的 Elasticsearch 集群和一个版本为 2.19 的 OpenSearch 集群。

Elasticsearch 和 OpenSearch 都使用了完全相同的设置进行测试:我们使用了经过 一些修改的 openai_vector Rally track,它使用了来自 NQ 数据集 的 250 万份文档,并使用 OpenAI 的 text-embedding-ada-002 模型 生成了丰富的嵌入。

结果报告了在不同召回级别(召回率@10、召回率@50 和召回率@100)下,使用 8 个客户端同时执行搜索操作所测出的延迟和吞吐量。我们只使用一个分片,没有副本。

我们运行了以下 k-n-rescore 组合,例如10-2000-2000,或k:10n:2000rescore:2000将检索 n 个候选者(2000)中的前 k(10),并对 2000 个结果进行重新评分(相当于 "超抽样因子 "1)。每次搜索运行 10.000 次,预热 1000 次:

召回@10

  • 10-40-40
  • 10-50-50
  • 10-100-100
  • 10-200-200
  • 10-500-500
  • 10-750-750
  • 10-1000-1000
  • 10-1500-1500
  • 10-2000-2000

回忆@50

  • 50-150-150
  • 50-200-200
  • 50-250-250
  • 50-500-500
  • 50-750-750
  • 50-1000-1000
  • 50-1200-1200
  • 50-1500-1500
  • 50-2000-2000

Recall@100

  • 100-200-200
  • 100-250-250
  • 100-300-300
  • 100-500-500
  • 100-750-750
  • 100-1000-1000
  • 100-1200-1200
  • 100-1500-1500
  • 100-2000-2000

为了复制基准,Rally-elasticsearch 和 rally-opensearch 的 Kubernetes 清单都将所有相关变量外部化到了 ConfigMap 中,可在此处(ES)和此处(OS)查看。可以自定义search_ops参数,以测试 k、n 和 rescore 的任意组合。

OpenSearch Rally 配置

/k8s/rally-openai_vector-os-bq.yml

Opensearch 索引配置

然后,ConfigMap 中的变量将用于索引配置,某些参数则保持不变。OpenSearch 中的 1 位量化是通过 将压缩级别设置为 "32x " 来配置的

index-vectors-only-mapping-with-docid-mapping.json

Elasticsearch Rally 配置

/k8s/rally-openai_vector-es-bq.yml

Elasticsearch 索引配置

index-vectors-only-mapping-with-docid-mapping.json

实施结果

对结果有多种解释方法。对于延迟和吞吐量,我们绘制了每个召回级别的简化图和详细图。如果我们考虑到每项指标 "越高越好",就很容易发现其中的差异。不过,延迟是负值(实际上越低越好),而吞吐量是正值。在简化图表中,我们使用(召回率/延迟)*10000 (简称 "速度")和 召回率*吞吐量,因此这两个指标都意味着速度越快和吞吐量越大越好。让我们开始吧。

召回 @ 10 - 简化

在这种召回水平下,Elasticsearch BBQ 比 OpenSearch FAISS快 5 倍 (平均快 3.9 倍),吞吐量平均高出 3.2 倍。

召回 @ 10 - 详细

工作latency.mean吞吐量平均值平均调用次数
Elasticsearch-9.0-BBQ10-100-10011.70513.580.89
Elasticsearch-9.0-BBQ10-1000-10027.33250.550.95
Elasticsearch-9.0-BBQ10-1500-150035.93197.260.95
Elasticsearch-9.0-BBQ10-200-20013.33456.160.92
Elasticsearch-9.0-BBQ10-2000-200044.27161.400.95
Elasticsearch-9.0-BBQ10-40-4010.97539.940.84
Elasticsearch-9.0-BBQ10-50-5011.00535.730.85
Elasticsearch-9.0-BBQ10-500-50019.52341.450.93
Elasticsearch-9.0-BBQ10-750-75022.94295.190.94
OpenSearch-2.19-faiss10-100-10035.59200.610.94
OpenSearch-2.19-faiss10-1000-1000156.8158.300.96
OpenSearch-2.19-faiss10-1500-1500181.7942.970.96
OpenSearch-2.19-faiss10-200-20047.91155.160.95
OpenSearch-2.19-faiss10-2000-2000232.1431.840.96
OpenSearch-2.19-faiss10-40-4027.55249.250.92
OpenSearch-2.19-faiss10-50-5028.78245.140.92
OpenSearch-2.19-faiss10-500-50079.4497.060.96
OpenSearch-2.19-faiss10-750-750104.1975.490.96

召回 @ 50 - 简化

在这种召回水平下,Elasticsearch BBQ 比 OpenSearch FAISS 快多达 5 倍 (平均快 4.2 倍),平均 吞吐量多 3.9 倍 。

详细结果 - 召回率 @ 50

任务平均时延吞吐量平均值平均召回率
Elasticsearch-9.0-BBQ50-1000-100025.71246.440.95
Elasticsearch-9.0-BBQ50-1200-120028.81227.850.95
Elasticsearch-9.0-BBQ50-150-15013.43362.900.90
Elasticsearch-9.0-BBQ50-1500-150033.38202.370.95
Elasticsearch-9.0-BBQ50-200-20012.99406.300.91
Elasticsearch-9.0-BBQ50-2000-200042.63163.680.95
Elasticsearch-9.0-BBQ50-250-25014.41373.210.92
Elasticsearch-9.0-BBQ50-500-50017.15341.040.93
Elasticsearch-9.0-BBQ50-750-75031.25248.600.94
OpenSearch-2.19-faiss50-1000-1000125.3562.530.96
OpenSearch-2.19-faiss50-1200-1200143.8754.750.96
OpenSearch-2.19-faiss50-150-15043.64130.010.89
OpenSearch-2.19-faiss50-1500-1500169.4546.350.96
OpenSearch-2.19-faiss50-200-20048.05156.070.91
OpenSearch-2.19-faiss50-2000-2000216.7336.380.96
OpenSearch-2.19-faiss50-250-25053.52142.440.93
OpenSearch-2.19-faiss50-500-50078.9897.820.95
OpenSearch-2.19-faiss50-750-750103.2075.860.96

召回 @ 100

在这种召回水平下,Elasticsearch BBQ 比 OpenSearch FAISS快 5 倍 (平均快 4.6 倍),吞吐量 平均高 3.9 倍。

详细结果 - Recall @ 100

工作latency.mean吞吐量平均值平均调用次数
Elasticsearch-9.0-BBQ100-1000-100027.82243.220.95
Elasticsearch-9.0-BBQ100-1200-120031.14224.040.95
Elasticsearch-9.0-BBQ100-1500-150035.98193.990.95
Elasticsearch-9.0-BBQ100-200-20014.18403.860.88
Elasticsearch-9.0-BBQ100-2000-200045.36159.880.95
Elasticsearch-9.0-BBQ100-250-25014.77433.060.90
Elasticsearch-9.0-BBQ100-300-30014.61375.540.91
Elasticsearch-9.0-BBQ100-500-50018.88340.370.93
Elasticsearch-9.0-BBQ100-750-75023.59285.790.94
OpenSearch-2.19-faiss100-1000-1000142.9058.480.95
OpenSearch-2.19-faiss100-1200-1200153.0351.040.95
OpenSearch-2.19-faiss100-1500-1500181.7943.200.96
OpenSearch-2.19-faiss100-200-20050.94131.620.83
OpenSearch-2.19-faiss100-2000-2000232.5333.670.96
OpenSearch-2.19-faiss100-250-25057.08131.230.87
OpenSearch-2.19-faiss100-300-30062.76120.100.89
OpenSearch-2.19-faiss100-500-50084.3691.540.93
OpenSearch-2.19-faiss100-750-750111.3369.950.94

烧烤炉的改进

自首次发布以来,BBQ 已经取得了长足的进步。在 Elasticsearch 8.16 上,为了便于比较,我们将 8.16 的基准运行与当前的基准运行放在一起,我们可以看到召回率和延迟从那时起有了怎样的改善。

在 Elasticsearch 8.18 和 9.0 中,我们重写了量化向量的核心算法。因此,8.16 版的 BBQ 已经很不错了,而最新版本则更加出色。您可以在这里这里了解相关信息。简而言之,每个矢量都通过优化的标量量化进行了单独量化。因此,用户可以在不影响性能的情况下获得更高的向量搜索准确性,使 Elasticsearch 的向量检索功能更加强大。

结论

在 Elasticsearch BBQ 和 OpenSearch FAISS 的性能比较中,Elasticsearch 在矢量搜索方面明显优于 OpenSearch,在各种召回级别中,Elasticsearch 的查询速度平均提高了 5 倍,吞吐量提高了 3.9 倍。

主要发现包括

  • Recall@10:与 OpenSearch FAISS 相比,Elasticsearch BBQ 的速度快达 5 倍(平均快 3.9 倍),吞吐量平均高出 3.2 倍。
  • Recall@50:与 OpenSearch FAISS 相比,Elasticsearch BBQ 的速度快达 5 倍(平均快 4.2 倍),吞吐量平均高出 3.9 倍。
  • Recall@100:与 OpenSearch FAISS 相比,Elasticsearch BBQ 的速度快达 5 倍(平均快 4.6 倍),吞吐量平均高出 3.9 倍。

这些结果凸显了 Elasticsearch BBQ 的效率和性能优势,尤其是在高维向量搜索场景中。Elasticsearch 8.16 中引入的更好的二进制量化(BBQ)技术在保持较高排序质量的同时,大幅减少了内存(~95% ),是大规模矢量搜索应用的上佳选择。

在 Elastic,我们坚持不懈地创新,改进 Apache Lucene 和 Elasticsearch,为搜索和检索用例(包括 RAG(检索增强生成))提供最佳的向量数据库。在 Lucene 10 的基础上,我们最近取得的进步大大提高了性能,使矢量搜索比以前更快、更节省空间。本博客就是这种创新的又一例证。

相关内容

准备好打造最先进的搜索体验了吗?

足够先进的搜索不是一个人的努力就能实现的。Elasticsearch 由数据科学家、ML 操作员、工程师以及更多和您一样对搜索充满热情的人提供支持。让我们联系起来,共同打造神奇的搜索体验,让您获得想要的结果。

亲自试用