【要約】LangGraph ノード内の LLM 並列実行を asyncio.Semaphore で制御する [Zenn_Python] | Summary by TechDistill
> Source: Zenn_Python
Execute Primary Source
// Problem
LangGraphを利用する開発者が、大量のデータを並列に処理しようとした際に、以下の技術的課題に直面する。
* API制限への抵触:
* リソースの枯渇:同時実行数が制御不能になり、プロセス内のメモリや接続数が急増する。
* 予測不能な負荷:タスク数に比例してリクエストが飛ぶため、下流サービスへの負荷が制御できない。
* API制限への抵触:
asyncio.gatherで大量のタスクを一度に投げると、LLMプロバイダーのレートリミットに達する。* リソースの枯渇:同時実行数が制御不能になり、プロセス内のメモリや接続数が急増する。
* 予測不能な負荷:タスク数に比例してリクエストが飛ぶため、下流サービスへの負荷が制御できない。
// Approach
開発者は、
* Semaphoreの活用:
* 実行範囲の限定:LLM呼び出し部分のみを
* 例外処理の最適化:
asyncio.Semaphoreを導入することで、1プロセス内での同時実行数を明示的に制限するアプローチをとる。* Semaphoreの活用:
asyncio.Semaphoreを用いて、同時に実行可能なタスク数を定義する。* 実行範囲の限定:LLM呼び出し部分のみを
async with sem:で囲み、前処理等の並列性は維持する。* 例外処理の最適化:
return_exceptions=Trueを使用しつつ、CancelledErrorを上位へ再送出する実装を行う。// Result
この手法を導入することで、開発者はプロセス内のリソース消費とAPI負荷を予測可能な範囲に抑えられる。
* API負荷の抑制:同時実行数を制限し、レートリミットによるエラーを回避できる。
* 実装の簡潔性:既存の非同期コードに最小限の変更で組み込める。
* 段階的な拡張:プロセス内制御を確立した上で、分散レートリミッターへの移行が可能となる。
* API負荷の抑制:同時実行数を制限し、レートリミットによるエラーを回避できる。
* 実装の簡潔性:既存の非同期コードに最小限の変更で組み込める。
* 段階的な拡張:プロセス内制御を確立した上で、分散レートリミッターへの移行が可能となる。
Senior Engineer Insight
> プロセス内での同時実行数制御は、安定稼働のための最低限の防波堤である。しかし、本手法は単一プロセス内の制御に留まる。分散環境では、ワーカー数に比例してAPIへの総負荷が増大する。そのため、RPMやTPMを考慮した分散レートリミッターの導入が不可欠だ。本記事の手法を「第一段階」と位置づけ、次のステップとして分散制御を設計すべきである。