ブログ

Elasticsearch BBQ vs. OpenSearch FAISS: ベクトル検索パフォーマンス比較

Elasticsearch BBQ と OpenSearch FAISS のパフォーマンス比較。

バイナリ量子化によるベクトル検索: BBQ を使用した Elasticsearch は、 FAISS を使用した OpenSearch よりも 5 倍高速です。Elastic はコミュニティから、特にセマンティック検索/ベクター検索の領域における Elasticsearch と OpenSearch のパフォーマンスの違いを明確にしてほしいというリクエストを受けており、明確でデータに基づいた比較を提供するためにこれらのパフォーマンス テストを実施しました。

Elasticsearch BBQ vs. OpenSearch FAISS - 速度とスループットの再現率の比較

バイナリ量子化対決

高次元ベクトルを元の形式で保存すると、メモリを大量に消費する可能性があります。量子化技術はこれらのベクトルをコンパクトな表現に圧縮し、メモリフットプリントを大幅に削減します。その後、検索は圧縮された空間で実行されるため、計算の複雑さが軽減され、特に大規模なデータセットでは検索が高速化されます。

Elastic は、Lucene を最高のパフォーマンスを発揮するベクター エンジンにすることに注力しています。Elasticsearch 8.16 では Lucene をベースにBetter Binary Quantization (BBQ) を導入し、8.18 および 9.0 でさらに進化させました。BBQ は、float32 次元をビットに削減するスカラー量子化の新しいアプローチに基づいて構築されており、高いランキング品質を維持しながら約 95% のメモリ削減を実現します。

一方、OpenSearch は、nmslib (現在は非推奨)、Lucene、FAISS といった複数のベクター エンジンを使用します。以前のブログでは、ベクトル検索について Elasticsearch と OpenSearch を比較しました。3 つの異なるデータセットを使用し、両方の製品でさまざまなエンジンと構成の組み合わせをテストしました。

このブログでは、現在両方の製品で利用可能なバイナリ量子化アルゴリズムに焦点を当てています。openai_vector Rally トラックを使用して、Elasticsearch と BBQ および OpenSearch と FAISS のバイナリ量子化を テストしました。

主な目的は、同じレベルの再現率で両方のソリューションのパフォーマンスを評価することでした。リコールとはどういう意味ですか?リコールは、検索システムによって関連結果がどれだけ正常に取得されたかを測定する指標です。

この評価では、recall@k が特に重要です。ここで、 k は検討される上位の結果の数を表します。したがって、 Recall@10Recall@50、および Recall@100 は、それぞれ上位 10、50、および 100 件の取得された項目内に表示される実際の関連結果の数を測定します。再現率は 0 ~ 1 (または 0% ~ 100% の精度) のスケールで表されます。これは重要なことです。なぜなら、ここでは再現率が常に 1 (100%) となる正確な KNN ではなく、近似 KNN (ANN) について話しているためです。

kの各値に対して、最終的なランキングを適用する前に考慮される候補の数であるnも指定しました。つまり、Recall@10、Recall@50、および Recall@100 の場合、システムは最初にバイナリ量子化アルゴリズムを使用してn個の候補を取得し、次にそれらをランク付けして、上位k 個の結果に期待される関連項目が含まれているかどうかを判断します。

n を制御することで、効率と精度のトレードオフを分析できます。通常、 nが大きいほど、ランキングに使用できる候補が増えるためリコールは増加しますが、レイテンシも増加し、スループットは低下します。逆に、 nを小さくすると検索速度は上がりますが、初期セットに含まれる関連候補が少なすぎるとリコール率が低下する可能性があります。

この比較では、Elasticsearch は同一の設定で OpenSearch よりも低いレイテンシと高いスループットを示しました。

方法論

完全な構成、Terraform スクリプト、Kubernetes マニフェスト、および特定の Rally トラックは、このリポジトリopenai_vector_bqで入手できます。

以前のベンチマークと同様に、次のもので構成される Kubernetes クラスターを使用しました。

  • Elasticsearch 9.0 用の 1 つのノードプール(3 台のe2-standard-32マシン、128 GB の RAM、32 個の CPU)

  • OpenSearch 2.19 用の 1 つのノード プール (3 台のe2-standard-32マシン (128 GB RAM、32 個の CPU))

  • Rally 用の 1 つのノードプール(2 台のe2-standard-4マシン、16 GB の RAM と 4 つの CPU)

Elasticsearch BBQ vs Opensearch FAISS方法論のセットアップ

Elasticsearch クラスター バージョン 9.0 を 1 つと OpenSearch クラスター バージョン 2.19 を 1 つセットアップしました。

Elasticsearch と OpenSearch は両方ともまったく同じ設定でテストされました。 つまり、OpenAI の text-embedding-ada-002 モデルを使用して生成された埋め込みが強化された NQ データ セットからの 250 万のドキュメントを使用する、いくつかの変更 を 加え た openai_vector Rally トラック を使用しました。

{
  "source-file": "open_ai_corpus-initial-indexing.json.bz2",
  "document-count": 2580961,
  "compressed-bytes": 32076749416,
  "uncompressed-bytes": 90263571686
}

結果には、8 つの同時クライアントを使用して検索操作を実行し、さまざまなリコール レベル (recall@10、recall@50、recall@100) で測定されたレイテンシとスループットが報告されています。単一のシャードを使用し、レプリカは使用しませんでした。

我々は以下のkn-rescoreの組み合わせを実行した。10-2000-2000、またはk:10n:2000rescore:2000 は、2000 件の結果に対して再スコアを適用して、n 件の候補 (2000) のうち上位 k 件 (10) を取得します (これは「オーバーサンプル係数」が 1 の場合に相当します)。各検索はウォームアップとして 1,000 回実行され、10,000 回実行されました。

リコール@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

  • 2000年10月

リコール@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

リコール@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

apiVersion: v1
kind: ConfigMap
metadata:
  name: rally-params-os
  labels:
    app: rally-opensearch
data:
  user-tags.json: |
    {
      "product": "OpenSearch",
      "product-version": "OpenSearch-2.19.0",
      "product-label": "OpenSearch-2.19-faiss",
      "benchmark-run": "19-feb-recall@100"
    }
  track-params.json: |
    {
      "mapping_type": "vectors-only-mapping-with-docid",
      "standalone_search_clients": 8,
      "standalone_search_iterations": 5000,
      "ann_threshold": 0,
      "vector_mode": "on_disk",
      "compression_level": "32x",
      "vector_method_name": "hnsw",
      "vector_method_engine": "faiss",
      "search_ops": [
        [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]
      ]
    }

Opensearchインデックス設定

ConfigMap の変数はインデックス構成で使用され、一部のパラメータは変更されません。OpenSearch における 1 ビット量子化は、圧縮レベルを「32x」に設定することによって設定されます。

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

{
  "settings": {
    {% if preload_pagecache %}
    "index.store.preload": [
      "vec", "vex", "vem", "veq", "veqm", "veb", "vebm"
    ],
    {% endif %}
    "index.number_of_shards": {{ number_of_shards | default(1) }},
    "index.number_of_replicas": {{ number_of_replicas | default(0) }},
    "index.knn": true,
    "index.knn.advanced.approximate_threshold": {{ ann_threshold | default(15000) }}
  },
  "mappings": {
    "dynamic": false,
    "properties": {
      "docid": {
        "type": "keyword"
      },
      "emb": {
        "type": "knn_vector",
        "dimension": 1536,
        "space_type": "innerproduct",
        "data_type": "float",
        "mode": {{ vector_mode | default("in_memory") | tojson }},
        "compression_level": {{ compression_level | default("32x") | tojson }},
        "method": {
          "name": {{ vector_method_name | default("hnsw") | tojson }},
          "engine": {{ vector_method_engine | default("faiss") | tojson }},
          "parameters": {
            "ef_construction": 100,
            "m": 16
          }
        }
      }
    }
  }
}

Elasticsearch Rallyの設定

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

apiVersion: v1
kind: ConfigMap
metadata:
  name: rally-params-es
  labels:
    app: rally-elasticsearch
data:
  user-tags.json: |
    {
      "product": "Elasticsearch",
      "product-version": "Elasticsearch-9.0.0-ade01164",
      "product-label": "Elasticsearch-9.0-BBQ",
      "benchmark-run": "19-feb-recall@100"
    }
  track-params.json: |
    {
      "mapping_type": "vectors-only-mapping-with-docid",
      "standalone_search_clients": 8,
      "standalone_search_iterations": 5000,
      "vector_index_type": "bbq_hnsw",
      "search_ops": [
        [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]
      ]
    }

Elasticsearchインデックス設定

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

{
  "settings": {
    {# non-serverless-index-settings-marker-start #}
    {%- if build_flavor != "serverless" or serverless_operator == true -%}
    {% if preload_pagecache %}
    "index.store.preload": [ "vec", "vex", "vem", "veq", "veqm", "veb", "vebm" ],
    {% endif %}
    "index.number_of_shards": {{ number_of_shards | default(1) }},
    "index.number_of_replicas": {{ number_of_replicas | default(0) }}
    {%- endif -%}
    {# non-serverless-index-settings-marker-end #}
  },
  "mappings": {
    "dynamic": false,
    "properties": {
      "docid": {
        "type": "keyword"
      },
      "emb": {
        "type": "dense_vector",
        "element_type": "float",
        "dims": 1536,
        "index": true,
        "similarity": "dot_product",
        "index_options": {
          "type": {{ vector_index_type | default("bbq_hnsw") | tojson }},
          "ef_construction": 100,
          "m": 16
        }
      }
    }
  }
}

成果

結果を解釈する方法は複数あります。レイテンシとスループットの両方について、リコールの各レベルで簡略化されたグラフと詳細なグラフをプロットしました。各指標について「高いほど良い」と考えると、違いが簡単にわかります。ただし、レイテンシはマイナス(低い方が実際には良い)であり、スループットはプラスです。簡略化されたグラフでは、 (リコール / レイテンシ) * 10000 (単に「速度」と呼びます) とリコール * スループットを使用しました。したがって、両方のメトリックは、速度とスループットが高いほど優れていることを意味します。始めましょう。

10回想 - 簡略化

この再現レベルでは、Elasticsearch BBQ は OpenSearch FAISS よりも最大5 倍高速(平均で 3.9 倍高速) で、平均で3.2 倍のスループットを実現します。

Elasticsearch BBQは、OpenSearch FAISSの速度とスループットと比較して、最大5倍(平均3.9倍)高速で、平均3.2倍のスループットを実現しています。Recall@10
Elasticsearch BBQ は OpenSearch FAISS よりも最大 5 倍高速 (平均 3.9 倍高速) で、平均 3.2 倍のスループットを実現します。

リコール@10 - 詳細

詳細な再現率@10レイテンシ比較 Elasticsearch BBQ vs Opensearch FAISS
Elasticsearch BBQ と Opensearch FAISS の詳細なリコール@10 スループット比較。

タスク

レイテンシ平均

スループット平均

平均再現率

Elasticsearch-9.0-BBQ

10-100-100

11.70

513.58

0.89

Elasticsearch-9.0-BBQ

10-1000-100

27.33

250.55

0.95

Elasticsearch-9.0-BBQ

10-1500-1500

35.93

197.26

0.95

Elasticsearch-9.0-BBQ

10-200-200

13.33

456.16

0.92

Elasticsearch-9.0-BBQ

2000年10月

44.27

161.40

0.95

Elasticsearch-9.0-BBQ

10-40-40

10.97

539.94

0.84

Elasticsearch-9.0-BBQ

10-50-50

11時00分

535.73

0.85

Elasticsearch-9.0-BBQ

10-500-500

19.52

341.45

0.93

Elasticsearch-9.0-BBQ

10-750-750

22.94

295.19

0.94

OpenSearch-2.19-faiss

10-100-100

35.59

200.61

0.94

OpenSearch-2.19-faiss

10-1000-1000

156.81

58.30

0.96

OpenSearch-2.19-faiss

10-1500-1500

181.79

42.97

0.96

OpenSearch-2.19-faiss

10-200-200

47.91

155.16

0.95

OpenSearch-2.19-faiss

2000年10月

232.14

31.84

0.96

OpenSearch-2.19-faiss

10-40-40

27.55

249.25

0.92

OpenSearch-2.19-faiss

10-50-50

28.78

245.14

0.92

OpenSearch-2.19-faiss

10-500-500

79.44

97.06

0.96

OpenSearch-2.19-faiss

10-750-750

104.19

75.49

0.96

50歳の思い出 - 簡略化

この再現率では、Elasticsearch BBQは最大5倍(平均4.2倍)高速で、平均3.9倍のスループットを実現しています。 OpenSearch FAISSよりも。

Recal @50 ベクトルパフォーマンス比較 Elasticsearch BBQ vs Opensearch FAISS
Elasticsearch BBQ は OpenSearch FAISS よりも最大 5 倍高速 (平均 4.2 倍高速) で、平均 3.9 倍のスループットを実現します。

詳細な結果 - 50 回のリコール

Recall@50 Elasticsearch BBQ と Opensearch FAISS のレイテンシ結果を振り返る
Recall@50 Elasticsearch BBQとOpensearch FAISSスループット結果

タスク

レイテンシ平均

スループット平均

平均再現率

Elasticsearch-9.0-BBQ

50-1000-1000

25.71

246.44

0.95

Elasticsearch-9.0-BBQ

50-1200-1200

28.81

227.85

0.95

Elasticsearch-9.0-BBQ

50-150-150

13.43

362.90

0.90

Elasticsearch-9.0-BBQ

50-1500-1500

33.38

202.37

0.95

Elasticsearch-9.0-BBQ

50-200-200

12.99

406.30

0.91

Elasticsearch-9.0-BBQ

50-2000-2000

42.63

163.68

0.95

Elasticsearch-9.0-BBQ

50-250-250

14.41

373.21

0.92

Elasticsearch-9.0-BBQ

50-500-500

17.15

341.04

0.93

Elasticsearch-9.0-BBQ

50-750-750

31.25

248.60

0.94

OpenSearch-2.19-faiss

50-1000-1000

125.35

62.53

0.96

OpenSearch-2.19-faiss

50-1200-1200

143.87

54.75

0.96

OpenSearch-2.19-faiss

50-150-150

43.64

130.01

0.89

OpenSearch-2.19-faiss

50-1500-1500

169.45

46.35

0.96

OpenSearch-2.19-faiss

50-200-200

48.05

156.07

0.91

OpenSearch-2.19-faiss

50-2000-2000

216.73

36.38

0.96

OpenSearch-2.19-faiss

50-250-250

53.52

142.44

0.93

OpenSearch-2.19-faiss

50-500-500

78.98

97.82

0.95

OpenSearch-2.19-faiss

50-750-750

103.20

75.86

0.96

リコール@100

この再現レベルでは、Elasticsearch BBQ は OpenSearch FAISS よりも最大 5 倍高速(平均 4.6 倍高速) で、平均で3.9 倍のスループットを実現します。

Elasticsearch BBQ VS Opensearch FAISS の結果を 100 回思い出す
Elasticsearch BBQとOpensearch FAISSのレイテンシとスループットパフォーマンスの比較

詳細な結果 - 再現率 100

詳細なレイテンシ結果 - リコール率 100 Elasticsearch BBQ vs Opensearch FAISS
詳細なスループット結果 - Elasticsearch BBQ と Opensearch FAISS を 100 で再現。

タスク

レイテンシ平均

スループット平均

平均再現率

Elasticsearch-9.0-BBQ

100-1000-1000

27.82

243.22

0.95

Elasticsearch-9.0-BBQ

100-1200-1200

31.14

224.04

0.95

Elasticsearch-9.0-BBQ

100-1500-1500

35.98

193.99

0.95

Elasticsearch-9.0-BBQ

100-200-200

14.18

403.86

0.88

Elasticsearch-9.0-BBQ

100-2000-2000

45.36

159.88

0.95

Elasticsearch-9.0-BBQ

100-250-250

14.77

433.06

0.90

Elasticsearch-9.0-BBQ

100-300-300

14.61

375.54

0.91

Elasticsearch-9.0-BBQ

100-500-500

18.88

340.37

0.93

Elasticsearch-9.0-BBQ

100-750-750

23.59

285.79

0.94

OpenSearch-2.19-faiss

100-1000-1000

142.90

58.48

0.95

OpenSearch-2.19-faiss

100-1200-1200

153.03

51.04

0.95

OpenSearch-2.19-faiss

100-1500-1500

181.79

43.20

0.96

OpenSearch-2.19-faiss

100-200-200

50.94

131.62

0.83

OpenSearch-2.19-faiss

100-2000-2000

232.53

33.67

0.96

OpenSearch-2.19-faiss

100-250-250

57.08

131.23

0.87

OpenSearch-2.19-faiss

100-300-300

62.76

120.10

0.89

OpenSearch-2.19-faiss

100-500-500

84.36

91.54

0.93

OpenSearch-2.19-faiss

100-750-750

111.33

69.95

0.94

バーベキューの改良

BBQ は最初のリリース以来長い道のりを歩んできました。Elasticsearch 8.16 では、比較のために、8.16 のベンチマーク実行を現在のものと並べて含めており、それ以降、リコールとレイテンシーがどのように改善されたかを確認できます。

Elasticsearch 9.0 BBQのレイテンシリコールの改善をElasticsearch 8.16 BBQとベンチマーク

Elasticsearch 8.18 および 9.0 では、ベクトルを量子化するためのコア アルゴリズムを書き直しました。つまり、8.16 の BBQ は良かったのですが、最新バージョンはさらに良くなっています。それについてはここここで読むことができます。つまり、すべてのベクトルは、最適化されたスカラー分位数を通じて個別に量子化されます。その結果、ユーザーはパフォーマンスを犠牲にすることなくベクトル検索の精度向上の恩恵を受けることができ、Elasticsearch のベクトル検索はさらに強力になります。

まとめ

Elasticsearch BBQ と OpenSearch FAISS のパフォーマンス比較では、Elasticsearch はベクトル検索において OpenSearch を大幅に上回り、さまざまなレベルのリコールで平均最大 5 倍のクエリ速度と 3.9 倍のスループットを達成しています。

主な調査結果は次のとおりです。

  • Recall@10 : Elasticsearch BBQ は、OpenSearch FAISS と比較して最大 5 倍高速 (平均 3.9 倍高速) で、平均 3.2 倍のスループットを実現します。

  • Recall@50 : Elasticsearch BBQ は、OpenSearch FAISS と比較して最大 5 倍高速 (平均で 4.2 倍高速) で、平均で 3.9 倍のスループットを実現します。

  • Recall@100 : Elasticsearch BBQ は、OpenSearch FAISS と比較して最大 5 倍高速 (平均で 4.6 倍高速) で、平均で 3.9 倍のスループットを実現します。

これらの結果は、特に高次元ベクトル検索シナリオにおける Elasticsearch BBQ の効率性とパフォーマンスの利点を強調しています。Elasticsearch 8.16 で導入された Better Binary Quantization (BBQ) 技術は、高いランキング品質を維持しながらメモリを大幅に削減 (約 95%) するため、大規模なベクトル検索アプリケーションに最適です。

Elastic では、RAG (Retrieval Augmented Generation) を含む検索および取得ユースケースに最適なベクター データベースを提供するために、Apache Lucene と Elasticsearch を改良するための革新を絶えず続けています。最近の進歩によりパフォーマンスが劇的に向上し、Lucene 10 から得た成果を基にして、ベクター検索が以前よりも高速かつスペース効率が高くなりました。このブログは、その革新のもう一つの例です。

関連記事

LINQ to Elasticsearch ES|QL:C#を記述してElasticsearchをクエリ

Florian Bernd

Elasticsearch の NLP とベクトル検索によるチャットボット機能の強化

Priscilla Parodi

OpenSearchとElasticsearchの違い:ベクトル検索のパフォーマンス比較

Ugo Sangiorgi

AI盗作:Elasticsearchによる盗作検出

Priscilla Parodi

高度なRAGテクニックパート2:クエリとテスト

Han Xiang Choong

最先端の検索体験を構築する準備はできましたか?

十分に高度な検索は 1 人の努力だけでは実現できません。Elasticsearch は、データ サイエンティスト、ML オペレーター、エンジニアなど、あなたと同じように検索に情熱を傾ける多くの人々によって支えられています。ぜひつながり、協力して、希望する結果が得られる魔法の検索エクスペリエンスを構築しましょう。

はじめましょう