Flat(全件検索)

1. 位置づけと基本概念

Flat インデックス(“Flat” または "Flat")は すべてのベクトルをそのままメモリ上に保持し,クエリごとに全件を線形走査して距離/類似度を計算する 最も単純かつ正確な方式です。前処理・クラスタリング・量子化を一切行わないため 訓練フェーズが不要 で,常に真の最近傍(exact NN)を返しますbge-model.comgithub.com

2. データ構造とメモリ使用量

格納形式は float32 が基本で,1 ベクトルあたり 4 × d byte(d は次元数)をそのまま確保します。したがって 100 万件・768 次元なら約 2.9 GB が必要ですgithub.com。ID を個別に持たないため add_with_ids は不可ですが,IndexIDMap でラップすれば任意 ID を付与できますgithub.com

3. 計算量とスケーラビリティ

検索は 時間計算量 O(N × d) の純粋なブルートフォースで,データセットが大きいほど線形に遅くなります。100 万件ならクエリ当たり 100 万回の距離計算が発生し,大量クエリではボトルネックになり得ますauto.gluon.ai

4. バリエーションと距離指標

クラス 距離/類似度 備考
IndexFlatL2 L2(ユークリッド距離) デフォルトの exact NN
IndexFlatIP 内積(ドット積)/コサイン※ ベクトル正規化でコサインに対応
GpuIndexFlat{L2,IP} CUDA GPU 版 CPU 版と同一 APIfaiss.ai

※コサイン類似度は事前にベクトルを L2 正規化して IndexFlatIP で検索しますgithub.com

5. 基本 API 例(Python)

python
import faiss, numpy as np d = 768 # 次元数 index = faiss.IndexFlatL2(d) # Flat インデックス生成 xb = np.random.rand(100000, d).astype('float32') index.add(xb) # ベクトル追加 xq = np.random.rand(1, d).astype('float32') D, I = index.search(xq, k=5) # 上位5件を取得

IndexFlat*is_trained == True で,追加前の訓練は不要ですpinecone.io。GPU を使う場合は faiss.index_cpu_to_gpu() で転送すれば同じコードで高速化できますgithub.com

6. サポートされる操作

  • 再構築: reconstruct(idx) で元のベクトルをそのまま取得可。

  • 削除: remove(ids) で該当行を物理削除(インデックスサイズが変動)。

  • ID 付与: faiss.IndexIDMap でラップ。
    これらはすべて Flat 系共通の軽量操作として実装されていますgithub.com

7. 典型的な用途

  • 小~中規模データセット(数十万件程度)で,正確性を最優先する場合

  • 他インデックスのベースライン: 近似法の精度検証やユニットテスト

  • IVF/OPQ などの coarse quantizer: IndexIVFFlat の量子化器として使用pinecone.iogithub.com

  • GPU バッチ検索: 高スループットが必要だが RAM より GPU メモリに余裕がある場合

8. 長所と短所まとめ

観点 長所 短所
精度 100 %(exact NN)
実装 訓練不要・コードが簡潔 ID 付き追加は要ラッパー
メモリ 圧縮しないため再構築不要 大規模データで RAM/GPU メモリ圧迫
速度 小規模なら十分高速,GPU でさらに加速 O(N) に比例し大規模データでは遅い

9. いつ Flat を選ぶべきか

  • 検索回数が少ない(≤ 1 万クエリ程度)かつ データセットが RAM に収まる 場合

  • 結果の完全性が絶対条件 の評価・医療・法務ドメイン

  • IVF / HNSW などを採用する前にベースラインを確認 したいフェーズ
    上記以外では,IVF 系や PQ 系,HNSW 系の近似インデックスと併用・置換を検討してくださいgithub.com

ChatGPT4o 生成日:2025/06/18