<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title><![CDATA[Sachin Frayne - Elasticsearch Labs]]></title>
    <description><![CDATA[Articles and tutorials from the Search team at Elastic]]></description>
    <copyright><![CDATA[© 2026. Elasticsearch B.V. All Rights Reserved]]></copyright>
    <image>
      <title><![CDATA[Sachin Frayne - Elasticsearch Labs]]></title>
      <url>https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1121c0bf0e8a6e65/6a88da6340a1841030ef456f/search-labs-thumbnail.png</url>
      <link>https://www.elastic.co/jp/search-labs/author/sachin-frayne</link>
    </image>
    <link>https://www.elastic.co/jp/search-labs/author/sachin-frayne</link>
    <atom:link href="https://www.elastic.co/jp/search-labs/rss/author/sachin-frayne.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[jp]]></language>
    <lastBuildDate>Mon, 14 Sep 2026 23:54:23 GMT</lastBuildDate>
  <item>
    <title><![CDATA[Elasticsearchのベクトル検索はOpenSearchの最大8倍高速]]></title>
    <description><![CDATA[OpenSearchとElasticsearchのフィルタリングされたベクトル検索ベンチマークを比較し、コンテキストエンジニアリングシステムにおいてベクトル検索のパフォーマンスが重要な理由を探ります。]]></description>
    <content:encoded><![CDATA[<h2>AIエージェントとコンテキストエンジニアリングにおいて検索速度が重要な理由</h2><p>2,000万件の文書コーパスを用いたベンチマークテストの結果、Elasticsearchはフィルタリングされたベクトル検索においてOpenSearchよりも最大8倍高いスループットを実現し、テストしたすべての構成においてより高いRecall@100を達成しました。コンテキストエンジニアリングに必要な要素は高速ベクトル取得だけではありません。ワークフローの反復につれて、チームはハイブリッド検索やフィルタリングなどの強力な関連性制御、操作の簡便性、予測可能なパフォーマンスも必要とするようになります。しかし、エージェントはリクエストごとに取得、推論、取得のループを何度も実行することが多いため、取得の遅延が乗数効果となり、ここでの改善はエンドツーエンドの応答性の向上とコスト削減に直接つながります。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9daec868eed84658/6a170bef6234e0c322db1a19/d5a52a07773f0942c2baa732dacfe782aac0f415-1600x683.png" alt="OpenSearchとElasticsearchの比較：フィルタリングされたベクトル検索のスループットベンチマーク" /><p>コンテキストエンジニアリングにおいて、取得は一度きりのステップではありません。エージェントとアプリケーションは、クエリを洗練させ、事実を検証し、根拠に基づいたコンテキストを構築し、タスクを完了するために、取得 → 推論 → 取得といったループを繰り返し実行します。このパターンは、エージェント型ワークフローや反復型検索拡張生成（RAG）においてよく見られます。検索はユーザーリクエストごとに何度も呼び出される可能性があるため、応答に遅延が生じ、インフラコストが増加します。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt718c72fb858e4c98/6a170bf00e2e496e7241a132/54ac476ff20a3cf93484298c9ae47612c12fc110-800x417.png" alt="コンテキストエンジニアリングは、大規模なコンテキストプールを限定されたLLMコンテキストウィンドウに変換します。" /><h2>ベクトル検索のパフォーマンスが重要な理由</h2><p></p><p>「15インチのノートパソコンが入る、防水性があり、金曜日までに届く60ドル以下の機内持ち込み用バックパックが必要です」という質問に、店員が答える場面を想像してみてください。</p><p>実際の運用環境では、アシスタントがベクトルクエリを1回発行して停止することはほとんどありません。適切なコンテキストを構築するために検索ループを実行し、各ステップは通常、在庫状況、地域、出荷約束、ブランドルール、ポリシー適格性などのフィルターによって制約されます。</p><p><strong>ステップ1：意図を解釈し、制約に変換する。</strong></p><p>エージェントはリクエストを構造化されたフィルタとセマンティッククエリに変換します。例えば、次のようなものです。</p><ul><li><p>フィルター：在庫あり、ユーザーの郵便番号に配達可能、金曜日までに配達、価格60ドル未満、有効な出品</p></li><li><p>ベクトルクエリ：「機内持ち込み用バックパック 15インチノートパソコン対応 防水」</p></li></ul><p><strong>ステップ2：候補を取得し、絞り込む。</strong></p><p>適切な一致を見逃さないように、しばしばバリエーションを加えて検索を繰り返します。</p><ul><li><p>「旅行用バックパック 機内持ち込み可能 ノートパソコン用スリーブ」</p></li><li><p>「防水通勤用バックパック 15インチ」</p></li><li><p>「軽量 機内リュック」</p></li></ul><p>各クエリは同じ適格性フィルターを使用します。なぜなら、無関係な項目や利用できない項目を取得することは、コンテキストの無駄になるからです。</p><p><strong>ステップ3：詳細を確認し、リスクを軽減するために展開する。</strong></p><p>エージェントは、最終的な回答に影響を与える主要な属性を再度確認するために取得を行います。</p><ul><li><p>素材と耐水性に関する記述</p></li><li><p>寸法とノートパソコン収納部の適合性</p></li><li><p>返品ポリシーや保証の制約</p></li><li><p>在庫が少ない場合の代替オプション</p></li></ul><p>これは、取得、推論、取得、組み立てという複数段階のコンテキストエンジニアリングです。</p><h2>コンテキストエンジニアリングにおいてレイテンシと再現率が重要な理由</h2><p>これらのやり取りには、ユーザーセッションごとに数十回のフィルタリングされたデータ取得呼び出しが含まれる場合があります。それにより、呼び出しごとのレイテンシがエンドツーエンドの応答時間に直接的な乗数となり、低い再現率は追加の再試行を強制したり、エージェントが対象アイテムを見逃す原因となり、回答の質を低下させます。</p><p>要点：コンテキストエンジニアリングされたシステムでは、フィルタリングされた近似最近傍法（ANN）は単一のルックアップではありません。これは制約下での反復処理であるため、大規模言語モデル（LLM）が最も目立つ要素である場合でも、ベクトル検索のパフォーマンスはレイテンシ、スループット、コストにすぐに現れます。</p><h2>ベンチマーク</h2><h3>成果</h3><p>グラフ2では、各点が1つのテスト構成を表しています。最も良い結果は左上に表示され、これは低いレイテンシで高い再現率が得られることを意味します。Elasticsearchの結果はOpenSearchよりも常に左上に近く、同じワークロード設定下でより優れた速度と精度を示しています。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb562b30a600cc8e1/6a170bf2cf4f253582b2d1b2/c50d1df00968cac18149a2799e6242fbe49b66a0-1600x990.png" alt=" グラフ2：再現率対平均レイテンシ（再スコア1）。" /><h4>いくつかの重要な洞察</h4><ul><li><p><code>s_n_r_value</code>: <code>size_numCandidates_rescoreOversample</code>の省略形（これらのテストではkとnumCandidatesはnumCandidatesと等しく設定されます）。例えば、 <code>100_500_1</code> size=100、numCandidates=500、k=500、再スコアオーバーサンプル=1 を意味します。</p></li><li><p>再現率：その構成における測定Recall@100</p></li><li><p>平均レイテンシ（ミリ秒）：クエリごとの平均エンドツーエンドレイテンシ</p></li><li><p>スループット：1秒あたりのクエリ数</p></li><li><p>再現率（％）：ElasticsearchとOpenSearchの相対的な再現率向上率（Elasticsearch - OpenSearch）/OpenSearch</p></li><li><p>レイテンシXs：OpenSearchの平均レイテンシをElasticsearchの平均レイテンシで割った値</p></li><li><p>スループットX：Elasticsearchのスループットをオープンサーチのスループットで割った値</p></li></ul><p>エンジン</p><p>`s_n_r_value`</p><p>リコール</p><p>平均レイテンシ（ミリ秒）</p><p>スループット</p><p>再現率（％）</p><p>レイテンシ Xs</p><p>スループット Xs</p><p>Elasticsearch</p><p>100_250_1</p><p>0.7704</p><p>25</p><p>534.75</p><p>9.70％</p><p>2.28</p><p>1.91</p><p>OpenSearch</p><p>100_250_1</p><p>0.7023</p><p>57.08</p><p>279.58</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_500_1</p><p>0.8577</p><p>25.42</p><p>524.14</p><p>7.20%</p><p>2.4</p><p>2</p><p>OpenSearch</p><p>100_500_1</p><p>0.8001</p><p>60.9</p><p>262.12</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_750_1</p><p>0.8947</p><p>29.67</p><p>528.09</p><p>5.72％</p><p>2.25</p><p>2.21</p><p>OpenSearch</p><p>100_750_1</p><p>0.8463</p><p>66.76</p><p>239.11</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_1000_1</p><p>0.9156</p><p>29.65</p><p>534.5</p><p>4.66％</p><p>2.46</p><p>2.44</p><p>OpenSearch</p><p>100_1000_1</p><p>0.8748</p><p>72.88</p><p>219.01</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_1500_1</p><p>0.9386</p><p>31.84</p><p>497.3</p><p>3.38％</p><p>2.71</p><p>2.68</p><p>OpenSearch</p><p>100_1500_1</p><p>0.9079</p><p>86.16</p><p>185.4</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_2000_1</p><p>0.9507</p><p>34.69</p><p>457.2</p><p>2.57%</p><p>2.98</p><p>2.96</p><p>OpenSearch</p><p>100_2000_1</p><p>0.9269</p><p>103.36</p><p>154.55</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_2500_1</p><p>0.9582</p><p>37.9</p><p>418.43</p><p>1.99％</p><p>3.28</p><p>3.26</p><p>OpenSearch</p><p>100_2500_1</p><p>0.9395</p><p>124.29</p><p>128.53</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_3000_1</p><p>0.9636</p><p>41.86</p><p>379.4</p><p>1.62％</p><p>3.46</p><p>3.44</p><p>OpenSearch</p><p>100_3000_1</p><p>0.9482</p><p>144.67</p><p>110.34</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_4000_1</p><p>0.9705</p><p>50.28</p><p>316.21</p><p>1.06%</p><p>3.87</p><p>3.85</p><p>OpenSearch</p><p>100_4000_1</p><p>0.9603</p><p>194.36</p><p>82.22</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_5000_1</p><p>0.9749</p><p>58.77</p><p>270.91</p><p>0.73%</p><p>4.43</p><p>4.41</p><p>OpenSearch</p><p>100_5000_1</p><p>0.9678</p><p>260.33</p><p>61.38</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_6000_1</p><p>0.9781</p><p>66.75</p><p>238.59</p><p>0.52%</p><p>4.91</p><p>4.89</p><p>OpenSearch</p><p>100_6000_1</p><p>0.973</p><p>327.44</p><p>48.81</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_7000_1</p><p>0.9804</p><p>74.64</p><p>213.49</p><p>0.38％</p><p>5.28</p><p>5.27</p><p>OpenSearch</p><p>100_7000_1</p><p>0.9767</p><p>394.24</p><p>40.53</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_8000_1</p><p>0.9823</p><p>82.28</p><p>193.59</p><p>0.27％</p><p>6.86</p><p>6.83</p><p>OpenSearch</p><p>100_8000_1</p><p>0.9797</p><p>564.14</p><p>28.33</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_9000_1</p><p>0.9837</p><p>90.08</p><p>176.96</p><p>0.16%</p><p>7.63</p><p>7.61</p><p>OpenSearch</p><p>100_9000_1</p><p>0.9821</p><p>687.25</p><p>23.25</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_10000_1</p><p>0.9848</p><p>97.64</p><p>163.31</p><p>0.08%</p><p>8.38</p><p>8.36</p><p>OpenSearch</p><p>100_10000_1</p><p>0.984</p><p>818.64</p><p>19.53</p><p></p><p></p><p></p><p>例えば、<code>100_9000_1</code>では、OpenSearchの平均取得時間687ミリ秒に対してElasticsearchは90ミリ秒であり、10ステップの取得ループでは約10×(687-90)=6秒の追加待機時間となります。 </p><p><a href="https://github.com/elastic/competitive-benchmarking-studies/tree/main/es-9.3-vs-os-3.5-vector-search/jingra/results/20260220">全ての結果を</a>ご覧ください。</p><h3>調査手法</h3><p>Pythonを使ってクエリを送信し、対応タイミングやその他の統計を追跡し、以下のクエリをエンジンに送信しました。ベクター検索エンジンのパフォーマンスは、そのコアパラメータ（考慮する候補の数、再スコアリングの積極性、返されるコンテキストの量など）をどのように調整するかによって決まることを覚えておいてください。これらの設定は、再現率（正解を見つける可能性）とレイテンシ（結果を得るまでの速さ）の両方に直接影響します。</p><p>ベンチマークでは、エージェント検索ループで通常調整するのと同じ候補、再スコア、結果サイズの設定を使用し、そのワークロード下でElasticsearchがどのように機能するかを測定しました。その後、同じ設定でOpenSearchをリファレンスとして実行しました。</p><p>OpenSearch</p>GET &lt;INDEX_NAME&gt;/_search
{
  "query": {
    "knn": {
      "&lt;DENSE_VECTOR_FIELD_NAME&gt;": {
        "vector": [...],
        "k": &lt;NUMBER_OF_CANDIDATES&gt;,
        "method_parameters": {
          "ef_search": &lt;NUMBER_OF_CANDIDATES&gt;
        },
        "rescore": {
          "oversample_factor": &lt;OVERSAMPLE&gt;
        },
        "filter": {
          &lt;SOME_FILTER&gt;
        }
      }
    }
  },
  "size": &lt;RESULT_SIZE&gt;,
  "_source": {
    "excludes": [
      "&lt;DENSE_VECTOR_FIELD_NAME&gt;"
    ]
  }
}<ul><li><p><code>"size": &lt;RESULT_SIZE&gt;</code>: クライアントに返されたヒット数。このベンチマークでは、Recall@100を計算するために、結果のサイズは100です。</p></li><li><p><code>"k": &lt;NUMBER_OF_CANDIDATES&gt;</code>: 最近傍候補の数。</p></li><li><p><code>"ef_search": &lt;NUMBER_OF_CANDIDATES&gt;</code>: 検査するベクトルの数。</p></li><li><p><code>"oversample_factor": &lt;OVERSAMPLE&gt;</code>: 再スコアリングを行う前に取得される候補ベクトルの数。</p></li></ul><p>Elasticsearch</p>GET &lt;INDEX_NAME&gt;/_search
{
  "query": {
    "knn": {
      "field": "&lt;DENSE_VECTOR_FIELD_NAME&gt;",
      "query_vector": [...],
      "k": &lt;NUMBER_OF_CANDIDATES&gt;,
      "num_candidates": &lt;NUMBER_OF_CANDIDATES&gt;,
      "rescore_vector": {
        "oversample": &lt;OVERSAMPLE&gt;
      },
      "filter": {
        &lt;SOME_FILTER&gt;
      }
    }
  },
  "size": &lt;RESULT_SIZE&gt;,
  "_source": {
    "excludes": [
      "&lt;DENSE_VECTOR_FIELD_NAME&gt;"
    ]
  }
}<ul><li><p><code>"size": &lt;RESULT_SIZE&gt;</code>: クライアントに返されたヒット数。このベンチマークでは、Recall@100を計算するために、結果のサイズは100です。</p></li><li><p><code>"k": &lt;NUMBER_OF_CANDIDATES&gt;</code>: 各シャードから返す最近傍の数。</p></li><li><p><code>"num_candidates": &lt;NUMBER_OF_CANDIDATES&gt;</code>: <code>knn</code>検索を実行する際にシャードごとに考慮する最近傍候補の数。</p></li><li><p><code>"oversample": &lt;OVERSAMPLE&gt;</code>: 再スコアリングを行う前に取得される候補ベクトルの数。</p></li></ul><p>例</p><p><code>Knn</code> クエリ（ <code>100_500_1</code> ）は次のようになります。</p><p>OpenSearch</p>GET search_catalog_128/_search
{
  "query": {
    "knn": {
      "search_catalog_embedding": {
        "vector": [...],
        "k": 500,
        "method_parameters": {
          "ef_search": 500
        },
        "rescore": {
          "oversample_factor": 1
        },
        "filter": {
          "term": {
            "valid": true
          }
        }
      }
    }
  },
  "size": 100,
  "_source": {
    "excludes": [
      "search_catalog_embedding"
    ]
  }
}<p>Elasticsearch</p>GET search_catalog_128/_search
{
  "query": {
    "knn": {
      "field": "search_catalog_embedding",
      "query_vector": [...],
      "k": 500,
      "num_candidates": 500,
      "rescore_vector": {
        "oversample": 1
      },
      "filter": {
        "term": {
          "valid": true
        }
      }
    }
  },
  "size": 100,
  "_source": {
    "excludes": [
      "search_catalog_embedding"
    ]
  }
}<p>Terraformスクリプト、Kubernetesマニフェスト、ベンチマークコードとともに、完全な構成はこの<a href="https://github.com/elastic/competitive-benchmarking-studies">リポジトリ</a>の<a href="https://github.com/elastic/competitive-benchmarking-studies/tree/main/es-9.3-vs-os-3.5-vector-search">es-9.3-vs-os-3.5-vector-search</a>フォルダで入手可能です。</p><h3>クラスターの設定</h3><p>私たちは、16 vCPUと64 GB RAMを備えた6台のe2-standard-16クラウドサーバーでテストを実行しました。各サーバーにおいて、検索エンジンノードを実行する各Kubernetesポッドに15個のvCPUと56GBのRAMを割り当て、そのうち28GBをJVMヒープ用に確保しました。</p><p>クラスターはElasticsearch 9.3.0とOpenSearch 3.5.0（Lucene 10.3.2）で実行しました。このベンチマークでは両方のシステムが同じLuceneバージョンを使用しているため、観測されたスループットとレイテンシの違いはLucene単独に起因するものではなく、各エンジンがフィルタリングされたk近傍法（kNN）による検索と再スコアリングをどのように統合し実行するかの違いを反映します。私たちは、3つのプライマリシャードと1つのレプリカ（合計6つのシャード、ノードごとに1つ）を持つ単一のインデックスを使用しました。</p><p>我々はまた、同じリージョン内の別のサーバーを使用してベンチマーククライアントを実行し、タイミング統計を収集しました。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7c7bdd567395d5b7/6a170bf3c1e8a56ee2f882f6/f81002c9186e4c2d3e92f49d72418fee9860fc5e-761x401.png" alt="ElasticsearchとOpenSearchのベンチマーク用のクラスター設定" /><h3>データセット</h3><p></p><p>このベンチマークでは、2,000万件のドキュメントを含む大規模なeコマーススタイルのカタログ埋め込みデータセットを使用しました。これは、実世界のフィルタリングされたベクトル検索を大規模なスケールで反映するように設計されています。</p><p></p><p>各ドキュメントはカタログ項目を表し、以下を含みます。</p><p></p><ul><li><p>近似kNN検索に使用される128次元の密なベクトル埋め込み。</p></li><li><p>構造化されたメタデータフィールドを使用してフィルタリング（例：アイテムの有効性と可用性、およびその他のカタログ制約）を行うことで、適格なサブセット内でのみ最近傍を取得するという一般的な本番パターンを可能にします。</p></li></ul><p></p><p>このデータセットを選んだ理由は、本番環境におけるエージェント型システムやRAG型システムで見られる主要なパフォーマンス上の課題を捉えているからです。つまり、ベクトル類似性だけでは不十分であり、検索はフィルタによって制約されることが多く、システムはこれらの制約の下で高い再現率を維持しながらレイテンシを低く抑える必要があるということです。より小規模なQAスタイルのデータセットと比較すると、2000万件の文書コーパスは、フィルタリングされたANNシステムが実際に直面する規模と候補数によるプレッシャーをより適切に反映しています。</p><h2>まとめ</h2><p>現代のAIアーキテクチャー、特にコンテキストエンジニアリングを中心としたアーキテクチャーにおいては、ベクトル探索の速度は些細な実装上の問題ではなく、乗数です。エージェントとワークフローが取得 → 推論 → 取得を繰り返す際、検索パフォーマンスはエンドツーエンドのレイテンシ、スループット、モデルに供給されるコンテキストの品質を直接形作ります。</p><p>当社のベンチマークでは、Elasticsearchは、OpenSearchと比べて、より低いレイテンシで一貫して高い再現率を達成しました。これは、類似ベクトルの取得だけでなく、正確性が「適切なドキュメントを取得できること」に左右されるシナリオで顕著でした。制御されたデータセットではその差は明確であり、本番環境では、大量の検索呼び出しを通じてそれらの利点が蓄積され、応答性が向上し、容量余裕が増加し、インフラストラクチャーコストが削減されます。</p><h3>参考資料</h3><ol><li><p><a href="https://www.elastic.co/search-labs/blog/context-engineering-overview">コンテキストエンジニアリングとは何ですか？</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/series/context-engineering-hybrid-search-evolution">ハイブリッド検索とコンテキストエンジニアリングの進化</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/context-engineering-relevance-ai-agents-elasticsearch">AIエージェント向けコンテキストエンジニアリングにおける関連性の影響</a></p></li></ol>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/opensearch-vs-elasticsearch-filtered-vector-search</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/opensearch-vs-elasticsearch-filtered-vector-search</guid>
    <category><![CDATA[Vector Database]]></category>
    <dc:creator><![CDATA[Sachin Frayne]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4b38e5114bbf098c/6a170bf560084b3a6c3c459d/fb7ee623925ca6696d643e437ce8efe5fe749079-1280x720.png" length="0" type="image/png"/>
    <pubDate>Wed, 25 Feb 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[ユースケースにBetter Binary Quantization (BBQ)を実装する方法]]></title>
    <description><![CDATA[ユースケースで Better Binary Quantization (BBQ) を実装する理由とその方法について説明します。]]></description>
    <content:encoded><![CDATA[<p>ベクトル検索は、テキストのセマンティック検索や、画像、ビデオ、オーディオの類似性検索を実装する際の基盤を提供します。ベクトル検索では、ベクトルはデータの数学的表現であり、そのサイズは膨大で、場合によっては遅くなることがあります。Better Binary Quantization (以下、BBQ と呼びます) は、ベクトルの圧縮方法として機能します。これにより、ベクトルを縮小して検索と処理を高速化しながら、適切な一致を見つけることができます。この記事では、BBQ と、ベクトルを自動的に再スコアリングする量子化インデックスにのみ使用可能なフィールドである rescore_vector について説明します。</p><p>この記事で説明したすべての完全なクエリと出力は<a href="https://github.com/elastic/elasticsearch-labs/tree/main/supporting-blog-content/how-and-why-bbq">、Elasticsearch Labs コード リポジトリ</a>で確認できます。</p><h2>ユースケースで Better Binary Quantization (BBQ) を実装する理由は何ですか?</h2>注: BBQ の背後にある数学の仕組みを詳しく理解するには、以下の<a href="https://www.elastic.co/jp/search-labs/blog/bbq-implementation-into-use-case#further-learning">「さらに学ぶ」セクション</a>をご覧ください。このブログでは、実装に重点を置いています。<p>数学は興味深いものですが、ベクトル検索がなぜ正確であり続けるのかを完全に理解したい場合には重要です。結局のところ、現在のベクトル検索アルゴリズムではデータの読み取り速度によって制限されることが判明しているため、これはすべて圧縮に関することです。したがって、そのデータすべてをメモリに収めることができれば、ストレージから読み取る場合と比べて速度が大幅に向上します (<a href="https://sre.google/static/pdf/rule-of-thumb-latency-numbers-letter.pdf">メモリは SSD よりも約 200 倍高速です</a>)。</p><p>いくつか留意すべき点があります:</p><ul><li><p><a href="https://arxiv.org/pdf/1603.09320">HNSW</a> (Hierarchical Navigable Small World) などのグラフベースのインデックスは、ベクター検索では最も高速です。</p><ul><li><p>HNSW: 効率的な高次元類似性検索を可能にする多層グラフ構造を構築する近似最近傍検索アルゴリズム。</p></li></ul></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt760bd95c206bfa8f/6a17e2ad505ac393f7ad8a95/590f3b3c72a76023a38a0436cd9ff90a9f80e936-1964x1262.png" alt="HNSW: 効率的な高次元類似性検索を可能にする多層グラフ構造を構築する近似最近傍検索アルゴリズム。" /><ul><li><p>HNSW の速度は、基本的にメモリ、または最悪の場合、ストレージからのデータ読み取り速度によって制限されます。</p><ul><li><p>理想的には、保存されているすべてのベクトルをメモリにロードできるようにする必要があります。</p></li></ul></li><li><p>埋め込みモデルは通常、浮動小数点数ごとに 4 バイトの float32 精度のベクトルを生成します。</p></li><li><p>そして最後に、ベクトルや次元の数によっては、すべてのベクトルを保存するためのメモリがすぐに不足する可能性があります。</p></li></ul><p>これを当然のこととして考えると、それぞれが数百、数千の次元を持つ可能性のある数百万、数十億のベクトルを取り込み始めると、すぐに問題が発生することがわかります。「<a href="https://www.elastic.co/jp/search-labs/blog/bbq-implementation-into-use-case#approximate-numbers-on-the-compression-ratios">圧縮率のおおよその数値</a>」というセクションでは、おおよその数値が示されています。</p><h2>始めるには何が必要ですか?</h2><p>始めるには、次のものが必要です。</p><ul><li><p>Elastic Cloud またはオンプレミスを使用している場合は、Elasticsearch のバージョン 8.18 以降が必要になります。BBQ は 8.16 で導入されましたが、この記事では 8.18 で導入された<code>vector_rescore</code>使用します。</p></li><li><p>さらに、クラスター内に<a href="https://www.elastic.co/jp/guide/en/elasticsearch/reference/8.18/ml-settings.html">機械学習 (ML) ノード</a>があることも確認する必要があります。(注: モデルをロードするには最低 4 GB の ML ノードが必要ですが、完全な本番環境のワークロードには、はるかに大きなノードが必要になる可能性があります。)</p></li><li><p>Serverless を使用している場合は、ベクターに最適化されたインスタンスを選択する必要があります。</p></li><li><p>また、ベクター データベースに関する基本的な知識も必要になります。Elastic のベクトル検索の概念にまだ慣れていない場合は、まず次のリソースを確認することをお勧めします。</p><ul><li><p><a href="https://www.elastic.co/jp/search-labs/blog/elastic-vector-database-practical-example">弾性ベクトルデータベースのナビゲート</a></p></li><li><p><a href="https://www.elastic.co/jp/blog/retrieval-augmented-generation-explained">検索拡張生成の背後にある大きなアイデア</a></p></li></ul></li></ul><h2>より良いバイナリ量子化（BBQ）実装</h2><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt18df00df95ff2ca7/6a17e2af414c6411989450df/4d388078495566f0527e931e0c2e38facdce83c6-1503x748.png" alt="Elasticsearch バーベキュー実装。" /><p>このブログをシンプルに保つために、組み込み関数が利用可能な場合はそれを使用します。この場合、機械学習ノード上の Elasticsearch 内で直接実行される<a href="https://www.elastic.co/jp/guide/en/machine-learning/8.17/ml-nlp-e5.html"><code>.multilingual-e5-small</code></a>ベクトル埋め込みモデルがあります。<code>text_embedding</code>モデルを、任意の埋め込みツール ( <a href="https://www.elastic.co/jp/guide/en/elasticsearch/reference/8.18/infer-service-openai.html">OpenAI</a> 、 <a href="https://www.elastic.co/jp/guide/en/elasticsearch/reference/8.18/infer-service-google-ai-studio.html">Google AI Studio</a> 、 <a href="https://www.elastic.co/jp/guide/en/elasticsearch/reference/8.18/infer-service-cohere.html">Cohere</a>など) に置き換えることができることに注意してください。希望するモデルがまだ統合されていない場合は、<a href="https://www.elastic.co/jp/guide/en/elasticsearch/reference/8.18/bring-your-own-vectors.html">独自の密なベクトル埋め込みも使用</a>できます。</p><p>まず、特定のテキストのベクトルを生成するための推論エンドポイントを作成する必要があります。これらのコマンドはすべて、Kibana <a href="https://www.elastic.co/jp/guide/en/kibana/8.18/console-kibana.html">Dev Tools コンソール</a>から実行します。このコマンドは<code>.multilingual-e5-small</code>をダウンロードします。まだ存在しない場合はエンドポイントが設定されます。実行には 1 分ほどかかる場合があります。予想される出力は、Outputs フォルダー内のファイル<a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/01-create-an-inference-endpoint-output.json">01-create-an-inference-endpoint-output.json</a>で確認できます。 </p>PUT _inference/text_embedding/my_e5_model
{
  "service": "elasticsearch",
  "service_settings": {
    "num_threads": 1,
    "model_id": ".multilingual-e5-small",
    "adaptive_allocations": {
      "enabled": true,
      "min_number_of_allocations": 1
    }
  }
}<p>これが返されると、モデルが設定され、次のコマンドを使用してモデルが期待どおりに動作するかどうかをテストできます。期待される出力は、Outputs フォルダー内のファイル<a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/02-embed-text-output.json">02-embed-text-output.json</a>で確認できます。</p>POST _inference/text_embedding/my_e5_model
{
  "input": "my awesome piece of text"
}<p>トレーニング済みのモデルがどのノードにも割り当てられないという問題が発生した場合は、モデルを手動で起動する必要がある場合があります。</p>POST _ml/trained_models/.multilingual-e5-small/deployment/_start<p>ここで、埋め込みモデルからの出力と一致するように、標準テキスト フィールド ( <code>my_field</code> ) と 384 次元の密なベクトル フィールド ( <code>my_vector</code> ) の 2 つのプロパティを持つ新しいマッピングを作成しましょう。<code>index_options.type to bbq_hnsw</code>もオーバーライドします。予想される出力は、Outputs フォルダー内のファイル<a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/03-create-byte-qauntized-index-output.json">03-create-byte-qauntized-index-output.json</a>で確認できます。</p>PUT bbq-my-byte-quantized-index
{
  "mappings": {
    "properties": {
      "my_field": {
        "type": "text"
      },
      "my_vector": {
        "type": "dense_vector",
        "dims": 384,
        "index_options": {
          "type": "bbq_hnsw"
        }
      }
    }
  }
}<p>Elasticsearch がベクトルを生成するようにするには、 <a href="https://www.elastic.co/jp/guide/en/elasticsearch/reference/8.18/ingest.html">Ingest Pipeline</a>を利用できます。このパイプラインには、エンドポイント ( <code>model_id</code> )、ベクトルを作成する<code>input_field</code> 、およびそれらのベクトルを格納する<code>output_field</code>の 3 つが必要です。以下の最初のコマンドは、内部で<a href="https://www.elastic.co/jp/guide/en/elasticsearch/reference/current/inference-apis.html">推論サービス</a>を使用する推論取り込みパイプラインを作成し、2 番目のコマンドはパイプラインが正しく動作していることをテストします。予想される出力は、Outputs フォルダー内のファイル<a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/04-create-and-simulate-ingest-pipeline-output.json">04-create-and-simulate-ingest-pipeline-output.json</a>で確認できます。</p>PUT _ingest/pipeline/my_inference_pipeline
{
  "processors": [
    {
      "inference": {
        "model_id": "my_e5_model",
        "input_output": [
          {
            "input_field": "my_field",
            "output_field": "my_vector"
          }
        ]
      }
    }
  ]
}

POST _ingest/pipeline/my_inference_pipeline/_simulate
{
  "docs": [
    {
      "_source": {
        "my_field": "my awesome text field"
      }
    }
  ]
}<p>これで、以下の最初の 2 つのコマンドを使用してドキュメントを追加し、3 番目のコマンドで検索が機能することをテストする準備が整いました。予想される出力は、Outputs フォルダー内のファイル<a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/05-bbq-index-output.json">05-bbq-index-output.json</a>で確認できます。</p>PUT bbq-my-byte-quantized-index/_doc/1?pipeline=my_inference_pipeline
{
    "my_field": "my awesome text field"
}

PUT bbq-my-byte-quantized-index/_doc/2?pipeline=my_inference_pipeline
{
    "my_field": "some other sentence"
}

GET bbq-my-byte-quantized-index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "knn": {
            "field": "my_vector",
            "query_vector_builder": {
              "text_embedding": {
                "model_id": "my_e5_model",
                "model_text": "my awesome search field"
              }
            },
            "k": 10,
            "num_candidates": 100
          }
        }
      ]
    }
  },
  "_source": [
    "my_field"
  ]
}<p><a href="https://www.elastic.co/jp/search-labs/blog/better-binary-quantization-lucene-elasticsearch#lucene-benchmarking">この投稿</a>で推奨されているように、圧縮の利点を活用しながら高い再現精度を維持するのに役立つため、大量のデータに拡張する場合は、再スコアリングとオーバーサンプリングが推奨されます。Elasticsearch バージョン 8.18 以降では、 <a href="https://www.elastic.co/jp/guide/en/elasticsearch/reference/8.18/knn-search.html#dense-vector-knn-search-rescoring">rescore_vector</a>を使用してこの方法で実行できます。予想される出力は、Outputs フォルダー内のファイル<a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/06-bbq-search-8-18-output.json">06-bbq-search-8-18-output.json</a>にあります。</p>GET bbq-my-byte-quantized-index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "knn": {
            "field": "my_vector",
            "query_vector_builder": {
              "text_embedding": {
                "model_id": "my_e5_model",
                "model_text": "my awesome search field"
              }
            },
            "rescore_vector": {
              "oversample": 3
            },
            "k": 10,
            "num_candidates": 100
          }
        }
      ]
    }
  },
  "_source": [
    "my_field"
  ]
}<p>これらのスコアは、生データで得られるスコアと比べてどうでしょうか?上記のすべてを<code>index_options.type: hnsw</code>を使ってもう一度実行すると、スコアが非常に似ていることがわかります。予想される出力は、Outputs フォルダーのファイル<a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/07-raw-vector-output.json">07-raw-vector-output.json</a>で確認できます。</p>PUT my-raw-vector-index
{
  "mappings": {
    "properties": {
      "my_field": {
        "type": "text"
      },
      "my_vector": {
        "type": "dense_vector",
        "dims": 384,
        "index_options": {
          "type": "hnsw"
        }
      }
    }
  }
}

PUT my-raw-vector-index/_doc/1?pipeline=my_inference_pipeline
{
    "my_field": "my awesome text field"
}

PUT my-raw-vector-index/_doc/2?pipeline=my_inference_pipeline
{
    "my_field": "some other sentence"
}

GET my-raw-vector-index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "knn": {
            "field": "my_vector",
            "query_vector_builder": {
              "text_embedding": {
                "model_id": "my_e5_model",
                "model_text": "my awesome search field"
              }
            },
            "k": 10,
            "num_candidates": 100
          }
        }
      ]
    }
  },
  "_source": [
    "my_field"
  ]
}<h2>圧縮比のおおよその数値</h2><p>ベクトル検索を使用する場合、ストレージとメモリの要件がすぐに大きな課題になる可能性があります。次の内訳は、さまざまな量子化手法によってベクター データのメモリ フットプリントがいかに劇的に削減されるかを示しています。</p><p>ベクトル（V）</p><p>寸法（D）</p><p>生（V x D x 4）</p><p>int8 (V x (D x 1 + 4))</p><p>int4 (V x (D x 0.5 + 4))</p><p>バーベキュー（V×（D×0.125+4））</p><p>10,000,000</p><p>384</p><p>14.31GB</p><p>3.61GB</p><p>1.83GB</p><p>0.58GB</p><p>50,000,000</p><p>384</p><p>71.53GB</p><p>18.07GB</p><p>9.13GB</p><p>2.89GB</p><p>1億</p><p>384</p><p>143.05GB</p><p>36.14GB</p><p>18.25GB</p><p>5.77GB</p><h2>まとめ</h2><p>BBQ は、精度を犠牲にすることなくベクター データを圧縮するために適用できる最適化です。これはベクトルをビットに変換することで機能し、データを効果的に検索できるようにし、AI ワークフローを拡張して検索を高速化し、データ ストレージを最適化できるようにします。</p><h2>さらなる学習</h2><p>バーベキューについてさらに詳しく知りたい場合は、次のリソースをぜひチェックしてください。</p><ul><li><p><a href="https://www.elastic.co/jp/search-labs/blog/better-binary-quantization-lucene-elasticsearch">LuceneとElasticsearchにおけるバイナリ量子化（BBQ）</a></p></li><li><p><a href="https://www.elastic.co/jp/search-labs/blog/bit-vectors-elasticsearch-bbq-vs-pq">より良いバイナリ量子化（BBQ）と積量子化</a></p></li><li><p><a href="https://www.elastic.co/jp/search-labs/blog/optimized-scalar-quantization-elasticsearch">最適化されたスカラー量子化：さらに優れたバイナリ量子化</a></p></li><li><p><a href="https://www.youtube.com/watch?v=04NzMt2Nigc">より良いバイナリ量子化（BBQ）：バイトからBBQへ、より良いベクトル検索の秘密 by Ben Trent</a></p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/bbq-implementation-into-use-case</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/bbq-implementation-into-use-case</guid>
    <category><![CDATA[Vector Database]]></category>
    <category><![CDATA[基本]]></category>
    <dc:creator><![CDATA[Sachin Frayne,Jessica Garson]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3dd0495b536b2615/6a17e2b0414c6488459450e3/66842055367cdd795532b01c167f2a4b03dc65e3-1200x628.png" length="0" type="image/png"/>
    <pubDate>Wed, 23 Apr 2025 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>