SigLIP2/CLIP と FAISS を使った高精度画像検索エンジン
このシステムは、ローカルの画像ディレクトリに対してベクトル検索を実行し、自然言語クエリや画像に基づいて類似画像を検索できます。
- 画像インデックス化: ディレクトリ内の画像をスキャンしてベクトル化
- テキスト検索: 自然言語で画像を検索
- 類似画像検索: 画像から類似画像を検索
- 差分更新: 新規画像のみを効率的にインデックス化
- Web GUI: ブラウザで操作できる直感的なインターフェース(FastAPI + HTMX)
- 検索結果のエクスポート: copy/symlink/hardlink/zip で一括出力
- 環境診断: doctor コマンドでGPU/ROCmサポートを確認
- SigLIP2/CLIP: Google/OpenAI のマルチモーダルモデル(画像/テキストエンコーディング)
- FAISS: Meta 社の高速類似検索ライブラリ
- FastAPI + HTMX: 軽量でインタラクティブな Web GUI
- Python 3.12+: 最新の Python 機能を活用
- Ubuntu, WSL, macOS など
- GPU(NVIDIA CUDA, AMD ROCm, Apple Silicon MPS) または CPU
- mise
- uv
- ruff
# miseで環境構築
mise install
# 依存関係をインストール
uv syncAMD GPU で ROCm PyTorch を使用する場合:
- Ubuntu 22.04/24.04 または対応Linux
- AMD GPU (RX 7000/9000シリーズ等)
- ROCm 6.x がインストール済み
- Python 3.12以上
# 1. ROCmの確認
rocminfo | head -20
# 2. 既存のPyTorchをアンインストール
uv pip uninstall torch torchvision
# 3. ROCm版PyTorchをインストール(ROCm 6.2の場合)
uv pip install torch torchvision --index-url https://download.pytorch.org/whl/rocm6.2
# 4. 環境診断で確認
uv run image-search doctortorch.version.hipに ROCm バージョンが表示されるdevice(auto)がcuda (ROCm)と表示される
- ROCm PyTorch は
torch.cuda.is_available()がTrueを返します(CUDA API互換のため) uv syncを実行するとCUDA版に戻る可能性があります- ROCm版は手動でインストールする必要があります
WSL2環境でのROCmには以下の制限があります(2025年12月時点):
対応GPU(ディスクリートGPUのみ):
- Radeon RX 9000シリーズ (RDNA 4)
- Radeon RX 7000シリーズ (RDNA 3) - RX 7900 XTX/XT など
- Ryzen AI Max 300シリーズAPU(プレビュー)
非対応:
- 内蔵GPU(iGPU)
- Radeon RX 6000シリーズ以前
制限事項:
/dev/kfdが存在しない(WSL2は/dev/dxgを使用)rocm-smi/amd-smiは動作しない- ROCmインストールには
--usecase=wsl,rocm --no-dkmsオプションが必要
ROCmのフル機能を使用するには、ネイティブLinux(Ubuntu 22.04/24.04)での使用を推奨します。
参考:
重要な変更: `main.py` は削除されました。すべての操作は `image-search` コマンドから実行してください。
# 基本的な使い方
uv run image-search index /path/to/images
# オプション指定
uv run image-search index /path/to/images --model siglip2-so400m --device auto --batch-size 32
# 強制再インデックス化
uv run image-search index /path/to/images --force# 基本的な検索
uv run image-search search "赤い車"
# 詳細オプション
uv run image-search search "猫と犬" --top-k 20 --threshold 0.25# 類似画像検索
uv run image-search similar /path/to/image.jpg
# オプション指定
uv run image-search similar /path/to/image.jpg --top-k 10 --threshold 0.3# 類似画像をコピーして出力
uv run image-search export-similar ./query.jpg --output-dir ./output --mode copy
# シンボリックリンクで出力(ディスク容量節約)
uv run image-search export-similar ./query.jpg -o ./output --mode symlink
# ZIP アーカイブで出力
uv run image-search export-similar ./query.jpg -o ./output --mode zip出力モード:
- `copy`: ファイルをコピー(デフォルト)
- `symlink`: シンボリックリンクを作成
- `hardlink`: ハードリンクを作成
- `zip`: ZIP アーカイブに圧縮
manifest.json: 各出力には検索結果のメタデータ(スコア、パス等)を含む `manifest.json` が生成されます。
uv run image-search info# 存在しない画像をインデックスから削除
uv run image-search clean
# インデックスを完全削除
uv run image-search clean --purge# GPU/ROCm サポート状況を確認
uv run image-search doctor出力例:
Torch Diagnostics
Key Value
cuda_available True
mps_available False
torch.version.cuda None
torch.version.hip 6.2.41133
device(auto) cuda (ROCm)
# Web GUIを起動
uv run image-search web
# カスタムポートで起動
uv run image-search web --port 8080
# 開発モード(自動リロード)
uv run image-search web --reloadブラウザで `http://127.0.0.1:8000\` にアクセスして、以下の操作が可能です:
Index(インデックス化)
- Directory: ディレクトリのインデックス化(バックグラウンドジョブ)
- Upload images: ブラウザから直接画像をアップロードしてインデックス化(複数ファイル対応)
Search(検索)
- Text search: 自然言語でテキスト検索
- Similar search: 類似画像検索
- Image path: ローカルパスを指定
- Upload image: ブラウザから画像をアップロードして検索
Images(画像一覧)
- インデックス済み画像の一覧表示(ページネーション対応)
- 各画像のサムネイル表示と類似検索ボタン
- 画像数が多い場合でも快適に閲覧可能
Export(エクスポート)
- 検索結果の一括エクスポート
- copy/symlink/hardlink/zip の4モードに対応
- ファイルアップロード時の厳格なバリデーション(ファイルタイプ、サイズ、ファイル名)
- パストラバーサル攻撃対策
- 一時ファイルの自動クリーンアップ
- 最大ファイルサイズ: 10MB
siglip2-so400m (SigLIP2 SO400M 384px) がデフォルトです。高精度・多言語対応・商用利用可能です。
| プリセット名 | 特徴 |
|---|---|
| siglip2-so400m | デフォルト・高精度(85.0%)・多言語 |
| siglip-so400m | 安定版(83.1%) |
| openclip-vit-b-32 | 軽量・高速 |
| openclip-vit-l-14 | バランス型 |
| openclip-vit-h-14 | 高精度 |
| xlm-roberta-h14 | 多言語対応 |
| japanese-clip | 日本語特化 |
詳細は仕様書を参照してください。
- JPEG (.jpg, .jpeg)
- PNG (.png)
- WebP (.webp)
- BMP (.bmp)
- GIF (.gif)
- TIFF (.tif, .tiff)
- CUDA: NVIDIA GPU(推奨)
- ROCm: AMD GPU(PyTorch HIP 経由、Linux のみ)
- MPS: Apple Silicon (M1/M2/M3/M4)
- CPU: フォールバック(全環境対応)
`device auto` で自動選択されます。`doctor` コマンドで環境を確認できます。
アップロードされた画像のメタデータに保存されるパスが .data/temp 配下になります。インデックス完了後に一時ファイルが削除されるため、パスが無効になる可能性があります。
対策: 将来的にはアップロード画像を永続化する機能の実装を検討しています。
画像一覧APIは全画像を読み込んでからスライスしているため、大量の画像がある場合のパフォーマンス懸念があります。
対策: データベースレイヤーでのページネーション実装を検討しています。
元の画像をそのまま配信しているため、大きな画像の読み込み速度に課題があります。
対策: サムネイル生成機能の実装を検討しています(P2機能候補)。
- サムネイル最適化(自動生成・キャッシュ)
- ドラッグ&ドロップUI
- 画像削除機能
- アップロードされた画像の永続化
- 画像編集機能(回転・トリミング)
- 画像の一括エクスポート
- タグ付け機能
- フォルダ管理
# 全テスト実行(165件以上 pass)
uv run pytest
# カバレッジ付き
uv run pytest --cov=src/image_index_search --cov-report=html# Lintチェック
uv run ruff check .
# フォーマット
uv run ruff format .image-index-serch/
├── src/image_index_search/ # メインパッケージ
│ ├── core/ # コアロジック
│ │ ├── encoder.py # 画像/テキストエンコーダー
│ │ ├── indexer.py # インデックス管理
│ │ ├── searcher.py # 検索エンジン
│ │ ├── scanner.py # ディレクトリスキャナー
│ │ ├── exporter.py # エクスポート機能
│ │ └── services/
│ │ └── workflow.py # ワークフロー管理
│ ├── storage/ # ストレージ層
│ │ ├── vector_store.py # FAISSベクトルDB
│ │ └── metadata_store.py # メタデータストア
│ ├── models/ # データモデル
│ │ ├── config.py # 設定
│ │ ├── image_metadata.py # 画像メタデータ
│ │ └── search_result.py # 検索結果
│ ├── utils/ # ユーティリティ
│ │ ├── device.py # デバイス検出
│ │ ├── image_loader.py # 画像読み込み
│ │ └── security.py # セキュリティ
│ ├── web/ # Web GUI
│ │ ├── app.py # FastAPIアプリ
│ │ ├── job_store.py # バックグラウンドジョブ
│ │ └── templates/ # HTMLテンプレート
│ └── cli.py # CLIエントリーポイント
├── tests/ # テストコード(120件)
│ ├── unit/ # ユニットテスト
│ ├── integration/ # 統合テスト
│ └── e2e/ # E2Eテスト
├── .data/ # データディレクトリ(gitignore)
├── docs/ # ドキュメント
└── agent.md/ # エージェント用指示
本プロジェクトは MIT ライセンスの下で公開されています。