ベクトルの保存・読み込み(faiss.write_index, faiss.read_index)

1. 概要

faiss.write_index / faiss.read_indexFaiss インデックスをディスクに永続化し、後でメモリに復元するための基本 API です。モデル再学習なしで巨大なベクトル集合を再利用できるため、本番環境へのデプロイ、バックアップ、バッチ前計算済みインデックスの配布などで必須となります。


2. API シグネチャと I/O フラグ

言語 関数 主な引数 備考
Python faiss.write_index(index, file_path, io_flags=0) index : faiss.Index
file_path : str
ファイルハンドルや IOWriter も可 faiss.ai
Python faiss.read_index(file_path, io_flags=0) file_path : str 返り値は新しい faiss.Index インスタンス
C++ void write_index(const Index* idx, const char* fname, int io_flags=0)
C++ Index* read_index(const char* fname, int io_flags=0)

主な I/O フラグ(ビット OR で併用可)

フラグ 用途
faiss.IO_FLAG_MMAP メモリマップ読み込み。巨大インデックスを RAM に展開せず共有可能 github.com
faiss.IO_FLAG_READ_ONLY 読み取り専用でオープン。誤操作による更新防止 pypi.org
faiss.IO_FLAG_SKIP_IVF_DATA IVF のリスト本体をスキップしメタデータのみ読む(デバッグ用)

3. Python での基本的なワークフロー

python
import faiss, numpy as np # (1) インデックス構築 dim, xb = 768, np.random.rand(100_000, 768).astype('float32') index = faiss.IndexFlatL2(dim) index.add(xb) # (2) 保存 faiss.write_index(index, "demo.index") # (3) 復元 index2 = faiss.read_index("demo.index")

保存・復元後の index2 は元の index と同等の検索結果を返します github.com

GPU インデックスの場合

ディスク I/O は CPU インデックスのみ対応 なので、保存時に必ず CPU へコピーします。

python
gpu_index = faiss.index_cpu_to_gpu(res, 0, index) # 例: GPU へ移行 index_cpu = faiss.index_gpu_to_cpu(gpu_index) # 保存前に CPU 化 faiss.write_index(index_cpu, "gpu.index")

読み込み後に faiss.index_cpu_to_gpu で再度 GPU へ転送します github.comgithub.com


4. 高度な I/O テクニック

シナリオ 手法・ポイント
インデックスを RAM に載せない `faiss.read_index(“large.index”, faiss.IO_FLAG_MMAP
バイナリ形式のインデックス faiss.write_index_binary / read_index_binary を使用。HNSW-Binary などで利用
シリアライズして DB・クラウドへ格納 chunk = faiss.serialize_index(index) → バイト列を任意ストレージへ保存 → faiss.deserialize_index(chunk) で復元 github.com
部分ロード/デバッグ IO_FLAG_SKIP_IVF_DATA を指定すると IVF データ本体をスキップしメタデータのみ読める faiss.ai

5. バージョン互換性と注意事項

  • Faiss の major バージョン差 が大きい場合(例: 1.7 → 1.9)には、古いバージョンで書いたファイルが読めないことがある。Read 失敗時は faiss::FaissException が投げられるので、faiss.Version() を確認し同系統のバージョンで再ビルドを推奨。

  • 量子化パラメータや IVF 訓練データ はインデックスファイルに含まれるため、index.is_trainedTrue なら再訓練不要。

  • オンディスク IVF(OnDiskInvertedLists) を使う場合、IO_FLAG_MMAP でロード後に .make_direct_map() を呼ぶと再構成が高速化。ただし direct map は RAM を占有する点に注意 pypi.org

  • マルチスレッド/マルチプロセス で同一ファイルを共有する場合は、書き込みを単一プロセスに限定し、その後 read-only でオープンする。


6. まとめ

  • faiss.write_index / faiss.read_indexモデル再学習不要の高速永続化手段

  • GPU インデックスは CPU→GPU コピーを挟む

  • IO_FLAG_MMAP により 巨大インデックスのメモリマップ読み込み が可能。

  • バイナリ・シリアライズ API で 柔軟なストレージ戦略 に対応。

これらの機能を組み合わせることで、開発環境・本番環境・複数ノード間でのインデックス共有や迅速なスケーリングが実現できます。

ChatGPT4o 生成日:2025/06/18