連続バッチングとは?LLMのスループットと応答速度を見極める
連続バッチングは、LLMの生成中にリクエストを入れ替え、共有GPUの処理容量を活用する仕組みです。静的・動的バッチングとの違い、スループットと応答遅延の関係、KVキャッシュの制約を解説。vLLM、SGLang、TensorRT-LLM、TGIの対応と設定を比較し、実際の負荷で運用上限を測る手順を紹介します。
公開日

連続バッチング(continuous batching)は、共有GPUで生成ステップの合間に新しいリクエストを受け入れる仕組みです。短い処理が終わるたびに空いた処理枠を使えるため、長い処理の完了待ちで容量を遊ばせずに済みます。このスケジューリング方式の基礎を示したのが、Yuらが2022年のOSDIで発表したOrca論文です。同時にリクエストが届く環境では、サーバー全体の毎秒トークン数を増やせます。ただし、サーバーの稼働が増えても、利用者それぞれの応答が速くなるとは限りません。
モデルを複数の利用者で共有するサーバーでは、許容する応答時間の範囲内で、どれだけ多くの処理を完了できるかが重要です。遅延の目標を伴わないスループットのグラフだけでは、何人の利用者に快適なサービスを提供できるかは判断できません。
以下で紹介するサーバーの対応状況と設定項目は、2026年10月25日に各開発元の公開ドキュメントで確認しています。途中のスケジュール例は仕組みを説明するためのもので、ハードウェアのベンチマークではありません。
連続バッチングはどのように動くのか
連続バッチングでは、生成を続けながら処理対象のグループを入れ替えます。 完了したリクエストが抜け、スケジューラーに余裕があれば待機中のリクエストが加わります。in-flight batchingやiteration-level batchingとも呼ばれます。
大規模言語モデル(LLM)は、まず**プリフィル(prefill)でプロンプトを処理し、続いてデコード(decode)**でその先の文章を生成します。一般的な自己回帰デコードでは、各生成ステップで、実行中のそれぞれのリクエストが次のトークン、つまりテキストの一片を生成します。次のステップにどのリクエストを参加させるかを決めるのがスケジューラーです。各段階については、LLM推論ガイドで詳しく解説しています。
相席の大きなテーブルを想像するとわかりやすいでしょう。全員が食べ終わってから次のグループを案内するのが、一斉入れ替え方式です。一方、席が空くたびに次の人を案内すれば、まだ食事中の人がいても新しい客が座れます。テーブルは共有していても、食事はそれぞれ別のままです。
ただし、このたとえだけでは説明しきれない点もあります。GPUのスケジューラーは、プロンプト処理やメモリの割り当ても組み込む必要があります。席が空いたからといって、待っているどのリクエストでもすぐに受け入れられるわけではありません。
Orca論文は何を変えたのか
Orcaは、スケジューリングを見直す区切りを、リクエスト全体から反復処理ごとへと変えました。 Gyeong-In YuらのOSDI 2022論文では、実行エンジンをモデルの反復処理ごとに呼び出し、その後でバッチ構成を見直す方法が説明されています。
併用される選択的バッチング(selective batching)は、モデルの一部の演算をまとめて実行しつつ、アテンションが必要とする異なる履歴に対応します。アテンションとは、トークンをそれ以前の文脈に関連づける演算です。この組み合わせにより、サービングシステムは長さの異なるリクエストの処理を織り交ぜて進められます。論文では、バッチサイズと利用可能なキー・バリューメモリもスケジューリング上の制約として扱っています。Orca論文を読む。
変わるのはモデルの周囲にあるサービングシステムです。同じ会話の中で複数の人に答えられるよう、モデルを学習し直す必要はありません。
静的・動的・連続バッチングの違い
違いを見極めるポイントは、進行中の処理に新しいリクエストがいつ加われるかです。 HTTP接続を同時に受け付けられるだけでは、モデルの実行に連続バッチングを使っているとは判断できません。
NVIDIAのTritonのバッチングに関するドキュメントでは、バッチサイズやキューの待ち時間の制御を含む、従来型の動的バッチングが説明されています。これは、LLMの生成中に処理対象を入れ替えるかどうかとは別の問題です。
vLLMの動的バッチングは、入れ替えのタイミングで判断する
LLMサービングエンジンのvLLMは、連続バッチングへの対応を明記しています。 「動的バッチング」という呼び方だけでは、動作を正確に特定できません。Hugging Faceも、連続バッチングの解説で、生成中に完了したプロンプトを入れ替える処理をdynamic schedulingやdynamic batchingと呼んでいます。名称だけで判断せず、生成ステップの合間に新しい処理を受け入れるかを確認してください。
ストリーミングも別の仕組みです。実行バッチの構成を固定したまま、クライアントにトークンを逐次送ることはできます。ここで扱う利点は、完了したリクエストが解放した処理容量を、後から届くリクエストに回せることです。
スケジュールの具体例で見る
短い処理が終わって空いた枠は、長い処理の実行中でも活用できます。 デコード用の枠が2つあるサーバーを例に考えます。リクエストAは残り2ステップ、Bは残り4ステップで完了し、2ステップ分の処理が必要なCが待機中です。この例では、プリフィル、スケジューリングのオーバーヘッド、ステップごとの所要時間の変化は考慮しません。
構成が固定されている場合、AとBが同時に始まります。Aが終わっても、CはBが完了して次のグループが始まるまで待ちます。連続バッチングなら、Aの完了後にCがその枠へ入り、Bと並行して処理を進められます。

この例が示すのは、より早く処理に参加できるという点であり、実測した高速化率ではありません。短い回答と長い要約が混在するサポート用チャットボットにも、同じスケジューリング上の余地があります。実際にどれだけ改善するかは、リクエスト、ハードウェア、サービング設定によって変わります。
スループットが伸びる理由とKVキャッシュの制約
バッチングは、同じモデル重みの転送から、より多くの有効な処理を引き出します。 モデル重みとは、回答の計算に使う学習済みの数値パラメーターです。同じモデルを使う複数のリクエストは、GPUメモリから重みを読み出す処理を共有できるため、利用可能な計算資源をより有効に使えます。連続的にスケジューリングを見直すことで、個々のリクエストが完了しても、効率よく処理できるバッチを維持しやすくなります。バッチング、メモリ転送、GPU利用率の関係は、NVIDIAが解説しています。
効率の悪いバッチでも、GPUが忙しく動き続けることはあります。重要なのは利用率のグラフが埋まっているかではなく、その稼働から有効なリクエスト処理がどれだけ生まれているかです。
一方、実行中のリクエストはそれぞれ作業用のメモリも必要とします。KVキャッシュはキー・バリューキャッシュの略で、処理済みトークンのアテンションの状態を保存します。同時実行するリクエストが増えたり、履歴が長くなったりすると、このメモリへの負荷が高まります。この状態と、再利用可能なプロンプトキャッシュの違いは、KVキャッシュの解説を参照してください。
PagedAttentionでメモリを無駄なく使う
連続バッチングが決めるのは実行する処理であり、PagedAttentionが変えるのはアテンションの状態の保存方法です。 Woosuk Kwonらの2023年のvLLM論文では、KVの状態を固定サイズのブロックに分け、物理メモリ上で連続していなくても配置できる方法が説明されています。ブロックマップによって、シーケンス内の論理的な順序を保ちます。
これにより、断片化や不要な重複によるメモリの浪費を減らせます。メモリをより隙間なく使えれば、より多くのリクエストの作業領域が収まり、スケジューラーが選べる有効な処理も増えます。論文でも、このメモリ管理手法はOrcaのスケジューリング手法を補完するものと明記されています。

それでも、物理的な容量の上限は残ります。配置を効率化しても、長い会話を無制限に収めることはできません。vLLMでは、KV領域が不足するとプリエンプションが発生し、リクエストを一時停止した後で状態を再計算する場合があります。その結果、処理完了までの遅延が悪化することがあります。この動作は、最適化に関するドキュメントで説明されています。
応答の遅延はどう変わるのか
連続バッチングはキューでの待ち時間を短くできる一方、バッチが大きくなったり混み合ったりすると、処理開始後の体感速度が落ちる場合があります。 段階ごとに分けて確認してください。
- 最初のトークンまでの時間(TTFT): 出力が始まるまで利用者が待つ時間です。
- トークン間レイテンシ: ストリーミング開始後、トークンが届く間隔です。
- エンドツーエンドのレイテンシ: リクエスト全体が完了するまでの時間です。
新しく届いたリクエストは、固定バッチ全体が終わるまで待たずに済む場合があります。ただし、大きな新規プロンプトの処理が、デコード中のリクエストとリソースを取り合うこともあります。**チャンク化プリフィル(chunked prefill)**はプロンプト処理を小さく分割し、進行中の生成処理と織り交ぜてスケジューリングできるようにします。
たとえばvLLMは、反復処理あたりのトークン予算にトレードオフがあると説明しています。値を小さくするとトークン間レイテンシを抑えやすく、値を大きくするとより多くのプリフィルを処理でき、TTFTを改善しやすくなります。したがって、この予算は無条件に最大化する設定ではなく、ワークロードに合わせて決めるものです。vLLMのチューニングガイドを参照してください。
低負荷・高負荷で連続バッチングの効果はどう違うのか
低負荷ではまとめる処理がほとんどなく、過負荷が続けば連続バッチングでもキューは残ります。 リクエストを順番に送る開発者が、同時にリクエストの重なる顧客向けサービスと同じ効果を期待するべきではありません。逆に、GPUが継続的に処理できる量を超えて受け入れれば、いずれ待ち時間が悪化します。
対話型アプリケーションでは、中央値とあわせて、95パーセンタイルを表すp95も確認してください。平均値が良好でも、一部のセッションで遅さが目立つことがあります。プロダクトの利用体験から許容できるTTFTとストリーミング間隔を決め、その範囲内で処理容量を測定します。
連続バッチングに対応するLLMサーバーと制約
以下の4つのサーバーは、いずれも連続バッチングまたはin-flight batchingへの対応を明記しています。 ただし、同じ機能に対応していても、スケジューラー、メモリ予算、対応モデルを同一視することはできません。
vLLMの連続バッチング
vLLMは、リクエストを連続的にスケジューリングする仕組みと、KVキャッシュのページ管理を組み合わせています。 ドキュメントにも両方が明記されています。運用時に見るべき設定は、単に希望するAPIの同時接続数ではなく、最大シーケンス数と反復処理あたりに割り当てるトークン数です。
制約になるのはメモリの逼迫です。同時実行数を増やしても、使える処理容量が増える代わりに、プリエンプションや再計算が発生することがあります。実際のトラフィックの構成と遅延目標に合わせて調整し、設定を比較するときはモデルとハードウェアを固定してください。
SGLang
SGLangは連続バッチングに対応し、リクエストの受け入れを制御する設定を公開しています。 サーバー引数のドキュメントでは、--max-running-requests、--chunked-prefill-size、そして--mem-fraction-staticで制御するモデル重みとKVプールのメモリ予算が定義されています。
これらはそれぞれ別の要素を制御します。同時に実行できるリクエスト数、チャンクに含めるプロンプト処理量、メモリの割り当てです。リクエスト数の上限を上げても、ほかの制限はなくなりません。エンジン選び全体についてはvLLMとSGLangの比較を参考にし、そのうえで実際に提供するモデルとリクエストの組み合わせを評価してください。
NVIDIA TensorRT-LLM
NVIDIA TensorRT-LLMは、in-flight batchingがcontinuous batchingおよびiteration-level batchingと同じ意味であることを明記しています。 機能ドキュメントでは、コンテキスト処理段階と生成段階のシーケンスを一緒に処理し、記載された実装ではパックされた入力テンソルを使うと説明されています。
リクエスト数の上限とトークン予算は、別々の制約です。PyTorchスケジューラーのドキュメントも、KV容量などのリソースを確保する処理と、その範囲に収まるリクエストから実行対象を選ぶ処理を分けています。in-flightスケジューラーでも、これらの容量チェックを通らない処理は受け入れられません。
Hugging Face Text Generation Inference
Hugging Face Text Generation Inferenceは連続バッチングに対応していますが、新規導入の判断ではメンテナンス状況を考慮する必要があります。 ドキュメントによると、現在受け付けているのは小規模な修正、ドキュメントの改善、軽微な保守で、今後の利用にはvLLMやSGLangなどのエンジンを推奨しています。
この状況によって、既存のTGI環境でバッチングが使えなくなるわけではありません。私なら、新しいサービング基盤の候補は、開発が活発な代替エンジンから評価します。すでに目標を満たしている運用環境では、サポートや機能について具体的な必要性が生じた時点に合わせて移行を計画します。
連続バッチングに期待しすぎてはいけないこと
連続バッチングに、どの環境でも当てはまる高速化の倍率はありません。 OrcaとPagedAttentionの論文が評価しているのは、特定のシステムとワークロードです。その結果から、任意のモデル、GPU、プロバイダーのエンドポイントにそのまま適用できる普遍的な改善幅を取り出すことはできません。
待ち時間がなくなるわけでもありません。キュー内のリクエストには依然としてプロンプト処理とメモリが必要で、スケジューラーの方針に従って順番を待ちます。長いプロンプト、高い同時実行負荷、キャッシュの逼迫は引き続き制約になります。
また、サーバー全体のトークン生成量が増えても、チャット製品が改善した証拠にはなりません。最初のトークンが届くまでの待ち時間が延びたり、ストリーミングが途中で途切れたりするなら、増えたスループットは、そのプロダクトが許容できる運用範囲を外れている可能性があります。
導入・運用で次に取り組むこと
開発者はリクエストが重なる場合に共有サービングを検討し、運用担当者は遅延の上限内で調整し、プロバイダーの選定担当者はリソースが競合する状況での測定結果を確認してください。 たまにしかリクエストを送らない個人用ツールなら、対応を急ぐ必要はありません。利用者がキューで待ち、応答の長さもばらつくサービスには、取り組む具体的な理由があります。ローカル利用から共有サービングへの移行については、OllamaとvLLMの比較で扱っています。
同時実行数を増やす前に、求める利用体験を定める
実際のワークフローで許容できる、最初のトークンまでの時間、ストリーミングの間隔、完了までの時間を書き出します。バックグラウンドで動く要約処理と、利用者にその場で対応するサポートアシスタントでは、許容できる範囲が異なります。
実運用を代表するリクエスト構成を再現する
モデル、ハードウェア、プロンプト長、出力上限、キャッシュ条件を比較できる状態にそろえます。短い回答、長いプロンプト、長い生成を含めてください。リクエストの到着パターンも実態に合わせ、閑散とした単独利用時の結果を、混雑したサービスの代わりにしないことが大切です。
スループットとともにキューと遅延を記録する
サーバー全体の毎秒出力トークン数、完了したリクエスト、待機中のリクエスト、失敗、TTFT、トークン間隔を測定します。vLLMは、
vllm:num_requests_waiting、vllm:time_to_first_token_seconds、vllm:inter_token_latency_secondsなどの対応する指標を本番環境向けメトリクスのドキュメントで公開しています。目標を満たせる最大の負荷を見極める
スケジューリングやメモリの設定は、項目ごとに変更します。遅延が上限を超えたり、メモリの逼迫で再計算が繰り返されたりしたら、同時実行数を増やすのをやめます。プロバイダーにも、想定する同時実行数におけるスループットと遅延を同じように示してもらい、処理容量が共有なのか予約されているのかも確認してください。
最終的に得るべきものは、実測に基づく運用上限です。意図した利用体験を維持しながら、エンドポイントが継続して処理できるワークロードを明らかにします。それがあって初めて、バッチングという機能を導入の判断につなげられます。
AIインフラの実践的な解説や、使っている技術構成の見直し方は、ニュースレターに登録してお読みください。
- 公開日
- カテゴリー
- Build
- 言語











