たった1ファイルの変更で31.8倍の高速化
RAGインジェクション・パイプラインをテストした際、ボトルネックに直面しました。1つのドキュメントの処理に50秒もかかっていたのです。
CPUはアイドル状態のままでした。アプリは計算やロジックを実行しているのではなく、次のリクエストを開始する前に、単にHTTPリクエストの完了を待っているだけでした。
埋め込み(embedding)モジュールを非同期で動作するように書き直しました。インフラ構成は一切変えずに、実行時間は49.61秒から1.56秒へと短縮されました。
テスト詳細
- モデル: Amazon Titan Text Embeddings V2 (AWS Bedrock)
- データセット: 33個のテキストチャンク
- リージョン: us-east-1
結果
- シーケンシャル(逐次処理): 49.61秒
- コンカレント(並行処理): 1.56秒
- 高速化率: 31.8倍
なぜ効果があるのか シーケンシャルなコードは、リクエストを送信するとレスポンスが返ってくるまで処理をブロックし、それを各チャンクに対して繰り返します。1チャンクあたり1.5秒かかる場合、33チャンクでは約50秒を浪費することになります。
非同期コードはすべてのリクエストを同時に発行するため、全体の処理時間は最も遅い単一のリクエストの時間と同じになります。
スケーリングによる影響
- 31チャンク: 49.61秒 → 1.56秒
- 100チャンク: 約160秒 → 約3秒
- 500チャンク: 約800秒 → 約5秒
- 1,000チャンク: 約1,600秒 → 約10秒
パイプラインへのヒント
- アイドル時間(待機時間)を探しましょう。コードが単にネットワークの応答を待っているだけなら、ハードウェアを追加しても意味がありません。
- AWS Bedrockのレート制限を遵守してください。
asyncio.Semaphoreを使用して、同時リクエスト数を制限しましょう。 - ノンブロッキングなライブラリを優先してください。
boto3からaioboto3に切り替えるか、呼び出しをasyncio.to_thread()でラップします。
1つのファイルを変更するだけで、ボトルネックが解消されました。低コストで、高いインパクト。
出典: https://dev.to/edwardyun/318x-speedup-by-changing-one-file-async-embedding-calls-on-aws-bedrock-4l61
オプションの学習コミュニティ: https://t.me/GyaanSetuAi
