コンテンツにスキップ

8.2.3 高性能推理サービス

  • スループット、レイテンシ、バッチ処理、キューといった推理サービスのキーワードを理解する
  • 「動く」ことと「サービスとして提供できる」ことは違うと理解する
  • 最小構成のバッチ処理推理サービスの考え方を読み取れるようになる
  • 推理サービス最適化の考え方の第一歩を身につける

推理サービスは、「リクエストがどう入ってきて、どう並び、どうまとめられ、どう返るか」で理解すると分かりやすいです。

flowchart LR
A["リクエストが入る"] --> B["キューに並ぶ"]
B --> C["バッチにまとめる"]
C --> D["モデルを実行する"]
D --> E["結果を返す"]

この節で本当に解決したいのは、次の2つです。

  • なぜモデルを1回動かせることと、サービスとして運用できることはまったく別なのか
  • なぜ推理サービスは本質的に、キュー、バッチ、リソース配分の問題なのか

一、なぜローカル推論と推理サービスは別物なのか?

Section titled “一、なぜローカル推論と推理サービスは別物なのか?”

ローカル推論で気にするのは「結果が出るか」

Section titled “ローカル推論で気にするのは「結果が出るか」”

たとえば:

  • 1つの prompt に答えられるか
  • 1枚の画像を生成できるか

推理サービスで気にするのは「同時にどれだけのリクエストをさばけるか」

Section titled “推理サービスで気にするのは「同時にどれだけのリクエストをさばけるか」”

一度本番に出すと、相手はこうなります。

  • 複数のリクエストが同時に来る
  • 流量が急に増える
  • 使えるリソースに限りがある
  • タイムアウトがある

だから推理サービスの核心はこうなります。

限られたリソースの中で、速度とスループットをどう両立するか。

初学者向けの分かりやすい比喩

Section titled “初学者向けの分かりやすい比喩”

推理サービスは、こんなものだと考えるとイメージしやすいです。

  • 飲食店の厨房で料理を出すこと

ローカル推論は、もっとこうです。

  • 自分で家で1食作って、ちゃんと作れるかを見ること

推理サービスは、もっとこうです。

  • 昼のピークに注文が一気に入る
  • 厨房がどう順番を決めるか
  • どうまとめて作るか
  • どうすればお客さんを長く待たせないか

この比喩は初心者にとても役立ちます。なぜなら、推理サービスの本質が

  • 流量をどうさばくか

という問題だとつかみやすくなるからです。


二、まず最重要の2つの用語を分けよう

Section titled “二、まず最重要の2つの用語を分けよう”

1回のリクエストにどれくらい待つか。

スループット(スループット)

Section titled “スループット(スループット)”

単位時間あたりにどれくらいのリクエストを処理できるか。

この2つは、たいてい引き合います。

たとえば:

  • batch を大きくすると、スループットは上がりやすい
  • でも、1件あたりの待ち時間は長くなることがある

つまり推理サービスは、「どれか1つだけ高ければよい」のではなく、バランスの問題です。


三、なぜバッチ処理(batching)がとても重要なのか?

Section titled “三、なぜバッチ処理(batching)がとても重要なのか?”

8件のリクエストがほぼ同時に来たら、次の2通りがあります。

  • 1件ずつ別々に実行する
  • まとめて1つの batch として実行する

後者のほうが、ハードウェアをより効率よく使えることが多いです。

requests = [12, 8, 15]
batch_size = 8
for r in requests:
num_batches = (r + batch_size - 1) // batch_size
print("必要な batch 数:", num_batches)

期待される出力:

Terminal window
必要な batch 数: 2
必要な batch 数: 1
必要な batch 数: 2

ここでの requests は、分かりやすくした作業量のリストです。大事なのは切り上げ計算で、作業量が batch size を超えると、サービス層は複数回のモデル実行に分ける必要があります。

このコードは何を教えているのか?

Section titled “このコードは何を教えているのか?”

このコードが教えているのは、

推理サービスは「1つのリクエスト」だけで考えるのではなく、「キューと batch」で考える

ということです。

初学者がまず覚えておくとよい見分け表

Section titled “初学者がまず覚えておくとよい見分け表”
現象先に見る層
1件の処理は速いのに、全体ではさばききれないスループットとバッチ処理
応答が遅いのに、GPU が遊んでいるキューと batch の組み方
リクエストが増えると急にタイムアウトするキュー長と並行処理の制御
単体ベンチマークは良いのに、本番では悪いモデル本体よりサービス層のスケジューリング

この表は初心者にとても役立ちます。なぜなら、「推理サービスが遅い」という曖昧な話を、具体的な切り分けポイントに分解してくれるからです。

推理サービスのキューとバッチ処理の図


四、なぜキューが高性能サービスの基本部品なのか?

Section titled “四、なぜキューが高性能サービスの基本部品なのか?”

なぜなら、リクエストはきれいには来ないから

Section titled “なぜなら、リクエストはきれいには来ないから”

実際の流量は、たいてい次のようになります。

  • 山がある
  • 谷がある
  • 突発的に増える

キューがないと、システムは簡単に:

  • 突然落ちる
  • リクエストをそのまま取りこぼす

ことになります。

from collections import deque
queue = deque(["req1", "req2", "req3", "req4", "req5"])
batch_size = 2
while queue:
batch = []
for _ in range(min(batch_size, len(queue))):
batch.append(queue.popleft())
print("batch を実行:", batch)

期待される出力:

Terminal window
batch を実行: ['req1', 'req2']
batch を実行: ['req3', 'req4']
batch を実行: ['req5']

この例はとてもシンプルですが、すでに次のことを示しています。

  • リクエストはまずキューに入る
  • そのあと batch ごとに実行される

これが、多くの推理サービスの基本的な動きです。


五、並行処理とバッチ処理は同じではない

Section titled “五、並行処理とバッチ処理は同じではない”

これは、初学者がいちばん混同しやすいところです。

複数のリクエストが、システムの中で同時に進むこと。

複数のリクエストを、モデル側で1つの batch にまとめて計算すること。

つまり、こう覚えるとよいです。

  • 並行処理はスケジューリングの問題
  • バッチ処理はモデル実行の問題

この2つはしばしば一緒に現れますが、同じ意味ではありません。


六、最小の推理サービスのメインループ

Section titled “六、最小の推理サービスのメインループ”
from collections import deque
queue = deque(["q1", "q2", "q3", "q4"])
batch_size = 2
def run_model(batch):
return [f"{item}_の回答" for item in batch]
while queue:
batch = []
for _ in range(min(batch_size, len(queue))):
batch.append(queue.popleft())
results = run_model(batch)
for item, result in zip(batch, results):
print(item, "->", result)

期待される出力:

Terminal window
q1 -> q1_の回答
q2 -> q2_の回答
q3 -> q3_の回答
q4 -> q4_の回答

このコードには、高性能推理サービスの最も重要な骨組みがすでに入っています。

  • 入隊
  • バッチ化
  • 推論
  • 結果の返却

この流れこそが、「サービス」の本体です。

初めて推理サービスを作るときの、いちばん安定した順番

Section titled “初めて推理サービスを作るときの、いちばん安定した順番”

一般に、次の順番のほうが安定して進めやすいです。

  1. まず 1件のリクエストを安定して返せるようにする
  2. 次にキューを入れる
  3. そのあと batch 化する
  4. 最後に batch サイズとリソース利用率を調整する

最初から最大スループットを狙うより、この順番のほうがシステムを安定させやすいです。


七、なぜ高性能推理サービスは常にバランス調整なのか?

Section titled “七、なぜ高性能推理サービスは常にバランス調整なのか?”

実際には、次のようなトレードオフがあります。

  • batch を大きくすると、スループットは上がりやすい
  • batch を小さくすると、応答は速くなりやすい
  • モデルを常駐させると速いが、リソースを多く使う
  • インスタンス数を増やすと安定しやすいが、コストが上がる

つまり、

推理サービスの最適化は、絶対値を上げることではなく、業務上の制約の中でバランスを取ること。


八、本番サービスで特に見るべき指標

Section titled “八、本番サービスで特に見るべき指標”

少なくとも、次の指標はよく見ます。

  • 平均レイテンシ
  • P95 / P99 レイテンシ
  • キュー長
  • batch 利用率
  • エラー率
  • GPU / CPU 利用率

これらの指標を見ると、今のボトルネックが

  • リクエスト側にあるのか
  • batch の組み方にあるのか
  • モデル実行側にあるのか

が分かりやすくなります。

初学者がまず覚えるとよい監視表

Section titled “初学者がまず覚えるとよい監視表”
指標先に知ること
平均 / P95 レイテンシユーザーが実際にどれくらい待ったか
キュー長リクエストがたまっているか
batch 利用率ハードウェアをしっかり使えているか
GPU / CPU 利用率ボトルネックがモデル実行にあるか、それ以外か

この表も初心者に向いています。なぜなら、「監視項目が多い」という状態を、もっと直感的な問いに変えてくれるからです。


単発の推論ベンチマークだけを見る

Section titled “単発の推論ベンチマークだけを見る”

本番で本当に大事なのは、全体の流量の中でどう動くかです。

最初から batch を大きくしすぎる

Section titled “最初から batch を大きくしすぎる”

スループットは上がるかもしれませんが、レイテンシが悪化することがあります。

モデルを動かせるだけで満足する

Section titled “モデルを動かせるだけで満足する”

キューやリソース利用率を見られないと、どこが本当のボトルネックか分かりにくくなります。


このページを終えたら、この証拠カードを残します。

ランタイム選択
ローカルモデル、推論サーバー、または統合 API
リクエスト契約
エンドポイント、payload、出力形式、エラー形状
レイテンシまたはコスト
1つの測定値または推定値
失敗確認
タイムアウト、メモリ圧迫、モデル不一致、またはバージョンずれ
ロールバック計画
フォールバックモデル、リトライ方針、またはトラフィック切り替え

この節でいちばん大事なのは、ある推理サービス用語を1つ覚えることではなく、次の理解です。

高性能推理サービスの核心は、モデル呼び出しを「単発の実行」から「実際の流量の中で、スループット・レイテンシ・リソース使用をバランスさせるシステム」に変えること。

これが、「ローカルでモデルを動かす」ことと本質的にまったく違う点です。

これをプロジェクトやシステム設計として見せるなら、何を見せるべきか

Section titled “これをプロジェクトやシステム設計として見せるなら、何を見せるべきか”

特に見せる価値が高いのは、次のような点です。

  • リクエストをどうキューイングし、どう batch 化するか
  • スループットとレイテンシをどう両立させているか
  • 本番で重要な監視指標は何か
  • どのときにボトルネックがキューにあり、どのときにモデル実行にあるか

こうすると、相手には次のことが伝わりやすくなります。

  • ただモデルを呼べるだけではない
  • サービスとしての推論を理解している

  1. 自分の言葉で説明してみましょう:なぜ batching と concurrency は同じではないのか?
  2. 考えてみましょう:あなたのプロダクトが非常に低いレイテンシを求めるなら、大きい batch と小さい batch のどちらを選びやすいですか?
  3. 最小構成の推理サービス監視項目リストを設計してみましょう。
  4. なぜ推理サービスの本当の難しさは「どれか1つを極めること」ではなく、「バランスを取ること」だと言えるのでしょうか?
解法と解説
  1. concurrency は同時に処理中のリクエスト数です。batching は複数の処理をまとめ、アクセラレータに効率よく流すことです。高い concurrency が大きな batch を意味するとは限らず、大きな batch はレイテンシを増やすことがあります。
  2. 低レイテンシのプロダクトでは、小さい batch または短い待ち時間の dynamic batching を選ぶことが多いです。
  3. 最小監視項目は、p50/p95/p99 レイテンシ、スループット、キュー時間、batch サイズ、GPU/CPU/メモリ、KV cache 圧力、エラー/タイムアウト率、token rate、品質/コスト信号です。
  4. 1つの指標を極端に伸ばすと別の指標が悪化します。大きな batch はスループットを上げますが遅延も増えます。長いコンテキストは recall を上げますがメモリを使います。高すぎる concurrency はタイムアウトを招きます。