このページでは、 MongoDB ベクトル検索の主要なパフォーマンス最適化戦略と、それを使用してベンチマークを作成した方法について説明します。このガイドを解釈する方法については、このベンチマークの使用方法を参照してください。
ベンチマークには、 33の製品カテゴリにわたり571.54M件のレビューを含む巨大なeコマースデータセット、Amazonレビュー2023 データセットを使用しました。これには1996年5月~2023年9月のやりとりが含まれています。約4820000個の固有なアイテムがこれらのレビューの対象となっており、ユーザーレビュー(評価、テキスト、有益性投票)、アイテムメタデータ(説明、価格、画像)、ユーザーアイテムインタラクショングラフなどの豊富なマルチモーダルデータを提供します。タイトルと説明が含まれているアイテムデータセット(5.5Mおよび15.3M)のサブセットを調査し、Voyage AIの voyage-3-largeモデルを使用し、以下のロジックを使用してそれらを組み込みました。
source = "Item: Title: " + record["title"] + " Description: " + record["description"] source_embedding = vo.embed(source, model="voyage-3-large", input_type="document", output_dimension=2048) 
フィルター結果の品質は、近似最近傍探索クエリの結果と、同じテキストインプットとリクエストされたベクトル数に対応する浮動厳密最近傍探索の正確な結果を使用し、Jaccard類似度(intersection / expected number of results)を計算することで決定されます。リコールは、eコマースデータセットに要求される可能性のある50件のサンプルクエリの平均交差点を見つけて計算されます。
注意
ベンチマークに使用されるソースコードと、ソース データセットを埋め込むために使用されるコードを確認するには、「 パフォーマンス テスト リポジトリ 」を参照してください。
パフォーマンスに影響を与える要因
このセクションでは、 MongoDB ベクトル検索 のパフォーマンスに影響いくつかの要因と、それらをテストするためにベンチマークをどのように構成したかについて説明します。
量子化
量子化はベクトル埋め込みの精度を低下させてメモリ使用量を削減し、検索速度を向上させますが、検索精度が低下します。
スカラー量化
スカラー量子化は32ビットの浮動小数点ベクトルを8ビットの整数に変換し、メモリ使用量を4倍削減します。整数ベクトル比較は、浮動小数点ベクトルと比べて計算時間が短く、必要なリソースも少なくなりますが、検索精度のパフォーマンスが低下する可能性があります。
バイナリ量子化
バイナリ量子化はベクトルを1ビット表現に変換し、メモリ使用量を32倍削減します。バイナリベクトル比較はハミング距離の計算を含み、intベクトルと比べて計算時間がさらに短く、リソースも少なくて済みます。しかし、浮動小数点ベクトルからバイナリベクトルに移行すると、検索精度が非常に低下するため、これを考慮して、レイテンシを増加させる再スコアリングステップを追加します。クエリ時に、検索中に蓄積された上位のnumCandidatesは、上位のlimit結果を得る前に、ディスク上の完全な忠実度ベクトルによって順序付けられます。
ベクトル次元
Voyage AIのvoyage-3-largeモデルを使用して中規模(5.5M)と大規模(15.3M)のベクトルデータセットを埋め込みました。この埋め込みモデルを選んだのは、多くのIRベンチマークでの優れた性能と、マトリョーシカ表現学習および量子化を考慮してトレーニングされているためです。したがって、量子化を有効にすると、ベクトルの量が多い場合でも低次元で良好なパフォーマンスを発揮します。
ビューのインデックスの作成を活用し、ソース2048次元ベクトルの最初のN次元をスライスする追加のフィールドを生成して、1024、512、256次元ベクトルを生成しソースフィールドと同様にインデックスを作成しました。
注意
ビューにベクトル検索インデックスを作成するには、MongoDB バージョン 8.1 以降を使用しなければなりません。
db.createView(   "all_dims_amazon_dataset",   "2048d_amazon_dataset",   [     {       $addFields: {         "1024_embedding": { $slice: ["$embedding", 1024] },         "512_embedding": { $slice: ["$embedding", 512] },         "256_embedding": { $slice: ["$embedding", 256] }       }     }   ] ) 
db.all_dims_amazon_dataset.createSearchIndex(   "all_dims_vector_index",   "vectorSearch",   {     "fields": [       {         "numDimensions": 2048,         "path": "embedding", // original 2048d embedding produced by voyage-3-large         "quantization": "scalar", // adjust to binary when needed         "similarity": "dotProduct",         "type": "vector"       },       {         "numDimensions": 1024,         "path": "1024_embedding",         "quantization": "scalar",         "similarity": "cosine", // sliced embeddings aren't normalized, so must use cosine         "type": "vector"       },       {         "numDimensions": 512,         "path": "512_embedding",         "quantization": "scalar",         "similarity": "cosine",         "type": "vector"       },       {         "numDimensions": 256,         "path": "256_embedding",         "quantization": "scalar",         "similarity": "cosine",         "type": "vector"       }     ]   } ) 
各位置で異なる表現と同様に、異なる次元は各ベクトルの表現能力(キャパシティー)に影響を与えます。その結果、特に2048d浮動小数点厳密最近傍探索ベースラインと比較して測定する場合、256dベクトルよりも2048dベクトルでより高い精密度を達成できます。
より多くのストレージとメモリを必要とするだけでなく、高次元ベクトルは低次元ベクトルに比べてクエリが若干遅くなりますが、 MongoDB ベクトル検索 がベクトル比較を実行するときに SIMD を活用するため、これは大幅に軽減されます。
フィルタリング
また、すべての15.3Mアイテムを含むコレクションに対して、個別のインデックス定義を作成しました。これにはこのデータセットに対して事前にフィルタリングされたクエリを有効にするために2つのフィールドのフィルターが含まれています。
db.large_amazon_dataset.createSearchIndex(   "vectorSearch",   "large_vector_index",   {     "fields": [       {         "numDimensions": 2048,         "path": "embedding",         "quantization": "scalar", // adjust to binary when needed         "similarity": "dotProduct",         "type": "vector"       },       {         "path": "category",         "type": "filter"       },       {         "path": "price",         "type": "filter"       }     ]   } ) 
大規模のインデックス化されたデータセットに対して、フィルターなしおよびフィルター済みの検索クエリを実行しました。
# unfiltered query query = [   {     "$vectorSearch": {       "index": "large_vector_index",       "path": "embedding",       "queryVector": embedding.tolist(),       "limit": k,       "numCandidates": candidates,     }   },   {     "$project": {"embedding": 0}   } ] 
# filtered query query = [   {     "$vectorSearch": {       "index": "large_vector_index",       "path": "embedding",       "queryVector": embedding.tolist(),       "limit": k,       "numCandidates": candidates,       "filter": {"$and": [{'price': {'$lte': 1000}}, {'category': {'$eq': "Pet Supplies"}}]}     }   },   {     "$project": {"embedding": 0}   } ] 
注意
両方のクエリパターンは、$projectステージを使用して、出力から埋め込みフィールドを除外します。結果に埋め込みが必要でない限り、レイテンシを短縮するために常にこれをお勧めします。
検索ノード構成
MongoDB ベクトル検索 のパフォーマンスは 専用の検索ノードでスケーリングされます。このノードはプライマリデータベースのワークロードとは別にベクトル計算を処理し、専用のハードウェアインスタンスを効率的に使用します。すべてのテストは M20 ベースクラスターを使用して実行されましたが、テストのタイプに応じて、テストケースよりも優れた検索ノードを再構成しました。すべてのテストはAmazon Web Servicesの検索ノード us-east-1 を使用して実行され、us-east-1 でも EC2インスタンスがリクエストを行っています。Amazon Web Servicesでプロビジョニングできる検索ノードは 3 種類あり、使用可能なディスク、 RAM、 vCPU の量が異なります。
| ノード タイプ | リソースプロファイル | 推奨使用量 | 
|---|---|---|
| 低 CPU | メモリ比率 (~6:1)、低vCPUに対して低ディスク | 量子化を活用しない多くのベクトルワークロードに適した開始点 | 
| 高 CPU | メモリ比率(~25:1)、高vCPUに対して高ディスク | 高QPSワークロードまたは量子化を活用するワークロード向けのパフォーマンス選択 | 
| ストレージ最適化 | メモリ比率(~25:1)、低vCPUに対して高ディスク | 量子化を活用するワークロードに対するコスト効率の良い選択 | 
Amazonデータセットのサイズ設定
768 次元の浮動小数ベクトルは、ディスク上の ~3KB の領域を占有し、このリソース要件は、ベクトルの数と各ベクトルの次元数に応じて直線的にスケーリングします。1M 768d ベクトルは ~3 GBを占有し、 1M 1536d は ~6 GBを占有します。
量子化を使用して、ディスクに保存されている完全忠実度ベクトルからメモリに保持される表現ベクトルを生成します。これにより、スカラー量子化では必要なメモリ量が3.75倍、バイナリ量子化では24倍に減少しますが、量子化されていないベクトルと量子化されたベクトルを保存するために必要なディスク容量は増加します。
1スカラー量子化768d次元ベクトルには、0.8kbのメモリ(3/3.75)と~3.8kbのディスク(3 + 3/3.75)が必要です。これらのハードウェアオプションと量子化のリソース要件を考慮し、さまざまなテストケースに対して次の検索ノード階層を選定しました。
| テストケース | 必要なリソース(RAM、ストレージ) | Search Node Tier RAM, disk, vCPUs | 2xノードの料金 | 
|---|---|---|---|
| 中規模データセット(5.5Mベクトル、すべての次元)、スカラー量子化 | 22, 104.5 GB | S50-ストレージ-最適化 32GB、843GB、4 vCPU | $1.04/hr | 
| 中規模データセット(5.5Mベクトル、すべての次元)、バイナリ量子化 | 3.43, 104.5 GB | S30-高CPU 8GB 213GB 4vCPU | $0.24/hr | 
| 大規模なデータセット(15.3Mベクトル、2048d)、スカラー量子化 | 32.64, 155.04 GB | S50-ストレージ-最適化 32GB、843GB、4 vCPU | $1.04/hr | 
| 大規模なデータセット(15.3Mベクトル、2048次元)、バイナリ量子化 | 5.1, 155.04 GB | S30-高CPU 8GB 213GB 4vCPU | $0.24/hr | 
binData ベクトル圧縮
大規模なデータセットには、ソースコレクションの各ベクトルのフットプリントを約60%削減するベクトル圧縮という追加機能を活用しました。これにより、ソースコレクションでIDがハイドレートされると、クエリ内のステップが加速されます。これはすべての大規模なワークロードに推奨されるステップです。
同時実行性
シリアルクエリレイテンシだけでなく、10と100のリクエストが同時に発行された場合の合計スループット/QPSも評価しました。
注意
より高度のスループットを処理するための推奨メカニズムは、検索ノードの数を水平に拡大することですが、これらのテストでは測定しませんでした。
シャーディング
システムのスループットの_idフィールドのクラスターおよびコレクションに対するシャーディングの影響を評価し、大規模なバイナリ量子化インデックスの10と100の同時リクエスト数に焦点を置きました。