Skip to content

kurono-soshiki/image-index-serch

Repository files navigation

画像検索システム (Image Index Search)

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 sync

AMD GPU (ROCm) の場合

AMD GPU で ROCm PyTorch を使用する場合:

前提条件

  • Ubuntu 22.04/24.04 または対応Linux
  • AMD GPU (RX 7000/9000シリーズ等)
  • ROCm 6.x がインストール済み
  • Python 3.12以上

ネイティブ Linux でのインストール(推奨)

# 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 doctor

確認ポイント

  • torch.version.hip に ROCm バージョンが表示される
  • device(auto)cuda (ROCm) と表示される

注意事項

  • ROCm PyTorch は torch.cuda.is_available()True を返します(CUDA API互換のため)
  • uv sync を実行するとCUDA版に戻る可能性があります
  • ROCm版は手動でインストールする必要があります

WSL2 での制限事項

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` コマンドから実行してください。

1. 画像をインデックス化

# 基本的な使い方
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

2. テキストで検索

# 基本的な検索
uv run image-search search "赤い車"

# 詳細オプション
uv run image-search search "猫と犬" --top-k 20 --threshold 0.25

3. 類似画像を検索

# 類似画像検索
uv run image-search similar /path/to/image.jpg

# オプション指定
uv run image-search similar /path/to/image.jpg --top-k 10 --threshold 0.3

4. 検索結果をエクスポート

# 類似画像をコピーして出力
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` が生成されます。

5. インデックス情報を表示

uv run image-search info

6. インデックスのクリーンアップ

# 存在しない画像をインデックスから削除
uv run image-search clean

# インデックスを完全削除
uv run image-search clean --purge

7. 環境診断

# 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)

8. Web GUI で操作

# 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` コマンドで環境を確認できます。

既知の課題と制約

一時ファイルパスの問題(P1)

アップロードされた画像のメタデータに保存されるパスが .data/temp 配下になります。インデックス完了後に一時ファイルが削除されるため、パスが無効になる可能性があります。

対策: 将来的にはアップロード画像を永続化する機能の実装を検討しています。

ページネーションのパフォーマンス(P2)

画像一覧APIは全画像を読み込んでからスライスしているため、大量の画像がある場合のパフォーマンス懸念があります。

対策: データベースレイヤーでのページネーション実装を検討しています。

サムネイル最適化(P2)

元の画像をそのまま配信しているため、大きな画像の読み込み速度に課題があります。

対策: サムネイル生成機能の実装を検討しています(P2機能候補)。

今後の拡張計画

P2: 推奨機能(次のフェーズ)

  • サムネイル最適化(自動生成・キャッシュ)
  • ドラッグ&ドロップUI
  • 画像削除機能
  • アップロードされた画像の永続化

P3: オプション機能(将来拡張)

  • 画像編集機能(回転・トリミング)
  • 画像の一括エクスポート
  • タグ付け機能
  • フォルダ管理

開発

テスト実行

# 全テスト実行(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 ライセンスの下で公開されています。

参考資料

About

複数の画像から特定のものを検索するシステム

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages