milvus-logo
LFAI
フロントページへ
  • コンセプト

Knowhere

Milvusのコアとなるベクトル実行エンジンKnowhereについて紹介します。

概要

KnowhereはMilvusの中核となるベクトル実行エンジンで、FaissHnswlibAnnoyを含む複数のベクトル類似性検索ライブラリを内蔵しています。また、Knowhereはヘテロジニアスコンピューティングをサポートするように設計されています。インデックス構築と検索要求をどのハードウェア(CPUまたはGPU)で実行するかを制御する。これがKnowhereの名前の由来である。将来のリリースでは、DPUやTPUを含む、より多くの種類のハードウェアがサポートされる予定です。

MilvusアーキテクチャにおけるKnowhere

下図は、MilvusアーキテクチャにおけるKnowhereの位置を示しています。

Knowhere Knowhere

一番下の層はシステム・ハードウェアです。その上にサードパーティのインデックス・ライブラリが配置されています。一番上のレイヤでは、KnowhereはCGOを介してインデックスノードやクエリノードとやり取りします。

Knowhereの利点

以下はKnowhereがFaissより優れている点です。

BitsetViewのサポート

Milvusは "ソフト削除 "を実現するためにビットセット機構を導入しています。ソフト削除されたベクトルはデータベースに存在しますが、ベクトルの類似性検索やクエリの際に計算されることはありません。

ビットセットの各ビットはインデックス付きベクトルに対応する。あるベクトルがビットセットで "1 "とマークされた場合、そのベクトルはソフト削除され、ベクトル検索には関与しないことを意味する。bitset パラメータは、CPU および GPU インデックスを含む、Knowhere で公開されているすべての Faiss インデックス照会 API に適用されます。

bitset メカニズムの詳細については、bitset を参照してください。

バイナリ・ベクトルのインデックス作成における複数の類似性メトリクスのサポート

KnowhereはハミングJaccardTanimotoSuperstructureSubstructureをサポートしています。Jaccard と Tanimoto は 2 つのサンプル・セット間の類似性を測定するために使用でき、Superstructure と Substructure は化学構造の類似性を測定するために使用できます。

AVX512命令セットのサポート

FaissがすでにサポートしているAArch64SSE4.2AVX2以外に、KnowhereはAVX512もサポートしています。AVX512はAVX2と比較してインデックス構築とクエリの性能を20~30%向上させることができます。

SIMD命令の自動選択

Knowhereは、あらゆるCPUプロセッサ(オンプレミスとクラウドの両方のプラットフォーム)で適切なSIMD命令(SIMD SSE、AVX、AVX2、AVX512など)を自動的に呼び出すことをサポートしているため、ユーザーはコンパイル時にSIMDフラグ("-msse4 "など)を手動で指定する必要がありません。

KnowhereはFaissのコードベースをリファクタリングして構築されています。SIMDアクセラレーションに依存する一般的な関数(類似度計算など)はファクタアウトされます。次に、各関数について4つのバージョン(すなわち、SSE、AVX、AVX2、AVX512)が実装され、それぞれが別々のソースファイルに入れられます。その後、ソースファイルは対応する SIMD フラグで個別にコンパイルされます。したがって、Knowhere は実行時に現在の CPU フラグに基づいて最適な SIMD 命令を自動的に選択し、フッキングを使用して適切な関数ポインタをリンクします。

その他の性能最適化

Knowhereのパフォーマンス最適化については、Milvus: A Purpose-Built Vector Data Management Systemを参照してください。

Knowhereのコード構造

Milvusの計算には主にベクトル演算とスカラー演算が含まれます。Knowhereはベクトル・インデックスの操作のみを処理します。

インデックスは元のベクトルデータから独立したデータ構造です。一般的に、インデックスの作成には、インデックスの作成、データの学習、データの挿入、インデックスの構築という4つのステップが必要です。AIアプリケーションの中には、データセットの学習とベクトル探索が分離されているものもある。データセットのデータはまず学習され、類似検索のためにmilvusのようなベクトルデータベースに挿入される。例えば、オープンデータセットsift1Mとsift1Bは、学習用データとテスト用データを区別している。

しかし、Knowhereでは学習用データと検索用データは同じです。Knowhereはセグメント内のすべてのデータを学習し、学習済みデータを挿入してインデックスを作成します。

DataObj基底クラス

DataObj Size() は の唯一の仮想メソッドです。Indexクラスは 、"size_"というフィールドを継承しています。また、Index クラスには と の 2 つの仮想メソッドがあります。 から派生した クラスは、すべてのベクトル・インデックスの仮想基底クラスです。 は、 、 、 、 などのメソッドを提供します。DataObj DataObj Serialize() Load() Index VecIndex VecIndex Train() Query() GetStatistics() ClearStatistics()

base class 基底クラス

その他のインデックス・タイプを上図の右側にいくつか示します。

  • Faissインデックスには2つの基底クラスがあります:浮動小数点ベクトル上のすべてのインデックス用のFaissBaseIndex 、バイナリ・ベクトル上のすべてのインデックス用のFaissBaseBinaryIndex

  • GPUIndex はすべてのFaiss GPUインデックスの基底クラスです。

  • OffsetBaseIndex はすべての自己開発インデックスの基本クラスです。ベクトルIDのみがインデックス・ファイルに格納されることを考えると、128次元ベクトルのファイル・サイズは2桁小さくなります。

IDMAP IDMAP

厳密に言えば、IDMAP はインデックスではなく、ブルートフォース検索に使用されます。ベクトルがデータベースに挿入される際、データ学習もインデックス構築も必要ない。検索は挿入されたベクトル・データに対して直接行われる。

しかし、コードの一貫性を保つために、IDMAPVecIndex クラスを継承し、その仮想インターフェースもすべて継承している。IDMAP の使い方は他のインデックスと同じである。

IVFインデックス

IVF IVF

IVF(転置ファイル)インデックスは最も頻繁に使用される。IVF クラスはVecIndexFaissBaseIndex から派生し、さらにIVFSQIVFPQ へと拡張される。GPUIVFGPUIndexIVF から派生する。そしてGPUIVF はさらにGPUIVFSQGPUIVFPQ に拡張される。

IVFSQHybrid は、独自に開発したハイブリッド・インデックスである。粗い量子化器はGPUで実行され、バケット内の検索はCPUで実行される。このタイプのインデックスは、GPUの計算能力を活用することで、CPUとGPU間のメモリコピーの発生を減らすことができる。 は、 と同じ想起率を持つが、より優れた性能を持つ。IVFSQHybrid GPUIVFSQ

BinaryIDMAPBinaryIVFFaissBaseBinaryIndexVecIndex から派生したものである。

サードパーティ・インデックス

third-party indices サード・パーティ・インデックス

現在、Faiss以外のサードパーティ・インデックスとしてサポートされているのは、ツリーベース・インデックスAnnoy とグラフベース・インデックスHNSW の2種類のみである。これら 2 つの一般的で頻繁に使用されるサードパーティ・インデックスは、いずれもVecIndex から派生したものである。

Knowhere へのインデックスの追加

Knowhere に新しいインデックスを追加する場合、まず既存のインデックスを参照します:

  • 量子化ベースのインデックスを追加するには、IVF_FLAT を参照。

  • グラフベースのインデックスを追加するには、HNSW を参照。

  • ツリーベースのインデックスを追加するには、Annoy を参照してください。

既存のインデックスを参照した後、以下の手順に従って新しいインデックスを Knowhere に追加できます。

  1. IndexEnum に新しいインデックスの名前を追加します。デー タ 型は文字列です。

  2. フ ァ イ ルConfAdapter.cpp に、 新 し い イ ンデ ッ ク ス にデー タ 検証チ ェ ッ ク を追加 し ます。検証チェックは、主にデータ学習とクエリのパラメータを検証するためのものです。

  3. 新しいインデックス用に新しいファイルを作成します。新しいインデックスの基底クラスには、VecIndexVecIndex の必要な仮想インタフェースを含める。

  4. 新しいインデックスのインデックス構築ロジックをVecIndexFactory::CreateVecIndex() に追加する。

  5. unittest ディレクトリの下にユニットテストを追加する。

次のステップ

MilvusでKnowhereがどのように動作するのかを学んだ後は、次のことを行ってください:

翻訳DeepLogo

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started
フィードバック

このページは役に立ちましたか ?