← 戻る

FLAT vsIVF: インバーテッド・ファイル・インデックスの仕組み

同じデータ、同じクエリ――しかし、異なる検索戦略。クエリポイントをドラッグして調整し nprobe、「検索を実行」を押すと、IVF がデータの大部分をスキップする様子を確認できます。

nprobe2
8 クラスタの2 を検索
速度20ms
値が小さいほどアニメーションが速くなります

FLAT — 全探索

すべての点をスキャンする
比較
200 / 200
ステータス
✓ 完了
リコール
100%

IVF — 転置ファイル索引

検索nprobe クラスター
比較
33 / 33
ステータス
✓ 完了
リコール@5
100%

何が起きているのか?

  1. 構築フェーズ(完了済み):K-meansにより、200 個の点が8 個のクラスターに分割された。各クラスターには中心点(×印)がある。
  2. ステップ1 — 中心点の評価: IVF は、まずクエリから各中心点までの距離を計算します。これは、データセットのサイズにかかわらず、8 回の比較のみです。
  3. ステップ2 — 最も近いnprobe クラスターを選択します。これらはハイライト表示されます。その他のクラスターはすべて完全にスキップされます。
  4. ステップ3 — 選択されたクラスター内のポイントをスキャンする: 200 ポイントのうち、約50 のみを対象とする。

トレードオフ:nprobe → スキャンされるクラスター数が増える → リコール率は高くなるが、処理速度は低下する。小さい nprobe → 処理は速くなるが、スキャンされていないクラスターにある真の近傍を見逃す可能性がある。クエリを nprobe = 1 し、クエリをクラスタの境界付近にドラッグして、リコールが低下する様子を確認してみてください。

IVF インデックスとは何ですか?

IVF (Inverted File)は、クラスタリングに基づく近似最近傍インデックスである。構築時、k-means アルゴリズムによってすべてのベクトルが nlist クラスターに分割し、各クラスターはその中心点によって表されます。クエリ実行時には、検索はまずクエリを各中心点とのみ比較し、最も近い nprobe クラスターを選び出し、それらに含まれるベクトルのみをスキャンし、それ以外のものはすべてスキップします。

Milvus メモリ使用量と精度のバランスを調整した、いくつかのIVF のバリエーションを提供しています: IVF_FLAT 生ベクトルを格納する(最も精度が高い)、 IVF_SQ8 各次元を1バイトに圧縮する(メモリ使用量が約4分の1に削減、リコールのコストがわずかに増加)、および IVF_PQ 積量子化を適用し、リコールのコストは大きくなるものの、はるかに高い圧縮率を実現します。

nlist のチューニングおよびnprobe

  • nlist (構築時間):k-meansクラスターの数。一般的な初期値は、N個のベクトルに対して4 × sqrt(N) である。クラスター数が多いほど、各クラスターは小さくなる。これによりスキャンは高速化されるが、重心探索のコストは増大し、境界効果が強まる。
  • nprobe (クエリ時間):1回のクエリにつきスキャンするクラスタの数。これがリコールとレイテンシを調整する主なパラメータであり、まさに上記のスライダーが制御しているものです。 nlist / 16 から始め、リコールが目標値に達するまで増やしてください。
  • バリエーションの選択: IVF_FLAT から開始する。メモリが不足している場合はIVF_SQ8 に移行し、データセットがSQ8 では処理できないほど大きい場合にのみIVF_PQ に移行する。各ステップダウン後に、自身のデータでリコール率を検証すること。

IVF vsHNSW vsDiskANN

IVF 構築が高速で、ベクトルに加えてメモリオーバーヘッドが小さく、理解しやすいが、同じリコール目標の場合、HNSW は通常、メモリ内でのクエリ処理がより高速である。インデックスの再構築を頻繁に行う場合(構築速度が重要)、メモリに制約がある場合(IVF_SQ8/IVF_PQ )、または予測可能で調整可能なスキャン挙動を望む場合は、IVF を選択する。 メモリ内クエリのレイテンシを最小限に抑えるにはHNSW を選択し、ベクトルがRAM に全く収まらなくなった場合はDiskANN を選択してください。

よくある質問

IVF_FLAT 、IVF_SQ8 、IVF_PQ の違いは何ですか?

これら3つはすべて同じ方法でベクトルをクラスタ化しますが、クラスタ内のベクトルの保存方法に違いがあります。「IVF_FLAT 」は生の浮動小数点ベクトルを保持します(リコールが最高)。「IVF_SQ8 」は各次元を8ビットに量子化し、リコールをわずかに犠牲にすることでメモリ使用量を約4分の1に削減します。「IVF_PQ 」はベクトルを短い積量子化コードに置き換え、最高の圧縮率を実現しますが、リコールの損失も最大となります。

nlist とnprobe はどのように選択すればよいですか?

一般的な経験則として、N個のベクトルに対してnlist = 4 × sqrt(N) とし、クエリ実行時にnprobe を調整します。nprobe が大きくなると、より多くのクラスターがスキャンされ、リコール率は向上しますが、レイテンシも高くなります。nlist/16 程度から始め、保留されたクエリセットでのリコール率が目標値に達するまで値を増やしていきます。

なぜIVF は、真の最近傍の一部を見逃してしまうのでしょうか?

これはクラスタの境界によるものです。クエリがクラスタの端付近に位置する場合、その真の近傍の一部は、スキャンされたnprobe のクラスタに含まれていない隣接するクラスタにある可能性があります。これは、nprobe = 1の境界付近にクエリポイントをドラッグすることで、可視化上で確認できます。

IVF とHNSW のどちらを使うべきですか?

同じリコール率の場合、HNSW は通常、インメモリ検索では高速ですが、より多くのメモリを使用し、構築に時間がかかります。IVF は構築が迅速で、メモリが限られている場合には量子化(SQ8/PQ )との相性が良いです。RAM を完全に超えるデータセットについては、代わりにDiskANN を検討してください。

さらに詳しく知りたい場合は、インデックスパラメータについては『IVF_FLAT 』のドキュメントを参照するか、完全な決定ガイドについては『Index Explained』をご覧ください。

探索を続けてください