-
Notifications
You must be signed in to change notification settings - Fork 0
embedding生成のバッチサイズ拡大による高速化 #135
Copy link
Copy link
Closed
Description
概要
Ollama embedding APIのバッチサイズを10→50に拡大し、embedding生成を3-5倍高速化する。
背景
現在のembedding生成は58692セクションで約630秒かかる。ボトルネック分析の結果:
| ステップ | 推定時間 | 割合 | 原因 |
|---|---|---|---|
| Ollama API呼び出し | ~590秒 | 94% | バッチサイズ10 → 5870回のHTTPリクエスト |
| SQLite書き込み | ~20-40秒 | 3-6% | autocommit |
| テキスト取得 | 数秒 | 1% | - |
対応内容
T1: バッチサイズ拡大
- ファイル:
src/embedding/ollama.rs行12 - 変更:
const BATCH_SIZE: usize = 10;→const BATCH_SIZE: usize = 50; - 期待効果: 5870回 → 1174回のリクエストに削減。630秒 → 120-200秒(3-5倍高速化)
- タイムアウト調整:
REQUEST_TIMEOUT_SECS(現在30秒、行18)を60秒に引き上げる。バッチサイズ拡大でリクエスト処理時間が増加するためマージンを確保。
T2: SQLiteトランザクションバッチ化
- ファイル:
src/embedding/store.rs,src/cli/embed.rs(sections.iter().zip(embeddings.iter())のループ内upsert_embedding呼び出し),src/cli/index.rs(generate_embeddings_for_manifest()内の同様のupsertループ。incremental更新経路も含む) - 変更内容:
EmbeddingStoreにexecute_in_transaction<F, T>(&self, f: F) -> Result<T>メソッドを新設。内部でself.conn.execute_batch("BEGIN")/self.conn.execute_batch("COMMIT")を使用(rusqliteの&self制約に適合する raw SQL 方式)。embed.rsのファイル単位ループ(行150for entry in &manifest.files)内でトランザクションを適用。index.rsのgenerate_embeddings_for_manifest()内の同様のupsertループにも同じトランザクションを適用(incremental更新経路含む)。
- トランザクションスコープ: ファイル単位(= そのファイルの全セクション)。
- API契約:
execute_in_transactionはクロージャがOkを返した場合のみCOMMIT、Errを返した場合はROLLBACKを実行。これによりhas_current_embedding()のキャッシュ判定(パス+ハッシュでファイル全体の処理済み判定)と整合する。一部sectionが失敗した場合はファイル全体をROLLBACKし、再実行時に自動回復可能にする。 - エラー時振る舞いの変更: 現行コードではsection単位でエラースキップ・次セクション続行だが、T2導入後はファイル単位でROLLBACK・次ファイル続行に変わる。失敗したファイルは再実行時に自動回復される。
- 期待効果: 58692回の個別fsync → ファイル数(2909)回に削減。20-40秒の削減
- 備考: T2はプロバイダー非依存の改善であり、OpenAI利用時にも同様の効果がある。
影響範囲
変更対象ファイル
| ファイル | 変更内容 | 影響度 |
|---|---|---|
src/embedding/ollama.rs |
BATCH_SIZE, REQUEST_TIMEOUT_SECS 定数変更 | 低(内部定数のみ) |
src/embedding/store.rs |
execute_in_transaction() メソッド追加 |
中(新API追加) |
src/cli/embed.rs |
upsertループをトランザクションで囲む | 中 |
src/cli/index.rs |
generate_embeddings_for_manifest() のupsertループをトランザクションで囲む(incremental更新含む) |
中 |
影響を受けないファイル
src/search/- 読み取り専用のため影響なし(※埋め込み再生成後の回帰確認推奨)src/cli/suggest.rs- 読み取り専用のため影響なしsrc/cli/status/- 読み取り専用のため影響なしsrc/embedding/openai.rs- BATCH_SIZE=100は変更なし
パフォーマンス影響
- 正常系: API呼び出し回数5分の1削減、SQLite fsync回数大幅削減。3-5倍の高速化期待。
- 異常系: REQUEST_TIMEOUT_SECS=60により、Ollama停止時の1リクエストあたり待機時間が30秒→60秒に。ファイル単位ROLLBACKにより失敗時は同ファイルの全セクションを再処理。
外部コンポーネントへの影響
- Ollama: 1リクエストあたりの入力テキスト量が5倍に増加。VRAM使用量増加。
- SQLite: トランザクション時間が長くなる代わりにfsync回数が大幅削減。Rust crateの追加・更新は不要。
リスク
- バッチサイズ拡大によりOllamaのVRAM使用量が増加。50で問題がある場合は30に下げる
- OpenAIプロバイダーは既にBATCH_SIZE=100で問題なし
受け入れ基準
-
BATCH_SIZE=50に変更後、cargo test --allが全パスすること -
cargo clippy --all-targets -- -D warningsで警告0件 -
cargo fmt --all -- --checkで差分なし -
EmbeddingStoreにexecute_in_transactionメソッドが追加され、embed.rsとindex.rsの両方から利用されていること -
execute_in_transactionのcommit/rollback動作の単体テストが追加されていること -
REQUEST_TIMEOUT_SECSがバッチサイズ拡大に合わせて調整されていること - 手動テスト:
embedコマンド実行時にエラーなく完了すること - 手動テスト:
index --with-embeddingコマンド実行時にエラーなく完了すること
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels