LLM推論の高速化は、モデルやカーネルの改善だけで決まるわけではありません。高価なGPUを使っていても、CPUとの受け渡しで待ち時間が残れば、その分だけ処理能力は眠ったままになります。
Hugging FaceのUnlocking asynchronicity in continuous batchingは、continuous batchingをさらに非同期化する実装を解説しています。同期的な処理では、CPUが次のバッチを準備している間GPUが待ち、GPUが計算している間CPUが待ちます。記事の実験では、この待ち時間が全体の約24%を占め、非同期化によってGPU稼働率は76.0%から99.4%へ、生成時間は300.6秒から234.5秒へ短縮されています。
ここで重要なのは、性能改善の中心が「もっと速い計算」ではなく「待たせない設計」にある点です。
continuous batchingは、リクエストを詰めてGPUの空きを減らします。ただし、それだけではCPUとGPUの処理順序が直列に残ります。Hugging Faceの記事が示す非同期化は、この直列性をほどきます。CPUはバッチNをGPUに投げたあと、GPUの計算完了を待つのではなく、次のバッチN+1の準備に入ります。その裏で、GPUはバッチNを処理し続けます。
もちろん、単に並べればよいわけではありません。入力転送、GPU計算、出力転送を別々のCUDA streamに分け、CUDA eventで依存関係を明示する必要があります。さらに、次のバッチ用のバッファを同じ場所に書き込むと、GPUが読んでいるデータをCPU側が壊してしまうため、スロットを分ける設計も必要になります。高速化は、魔法の最適化ではなく、データの所有権とタイミングを細かく設計した結果です。
これはLLM基盤を運用する側にとって、かなり実務的な示唆を持ちます。推論コストを下げたいとき、最初の選択肢はGPUを増やすことでも、より小さいモデルへ逃がすことでもないかもしれません。既存のGPUがどれだけ待っているかを測り、CPU処理、転送、スケジューリング、同期点を分解して見ることが先になります。
特に長い生成や高並列の推論では、1ステップあたりの小さな待ち時間が積み上がります。逆に言えば、その待ち時間を隠せる設計にできれば、モデルを変えずにスループットを引き上げられます。これは、LLMインフラの競争力がモデル選定だけでなく、実行ループの設計品質に移っていることを示しています。
GPUを使い切るとは、計算を速くすることだけではありません。CPU、メモリ転送、同期、スケジューラを含めて、GPUが待たない流れを作ることです。LLM推論の次の改善余地は、モデルの中だけでなく、モデルを動かす時間割の中にも残っています。
関連記事
- Unlocking asynchronicity in continuous batching
- Granite Embedding Multilingual R2: Open Apache 2.0 Multilingual Embeddings with 32K Context — Best Sub-100M Retrieval Quality
- Granite Embedding Multilingual R2: Open Apache 2.0 Multilingual Embeddings with 32K Context — Best Sub-100M Retrieval Quality
参考文献
コメント