Inference Latency
推論レイテンシは、モデルが1つの入力を予測に変換するのにかかる時間です。レイテンシの要因、測定方法、スループットとのトレードオフについて解説します。
推論レイテンシとは、学習済みの機械学習モデルが、カメラのフレームやテキストプロンプトなどの入力1件を予測に変換するのにかかる時間です。通常はミリ秒(ms)で表され、システムの応答速度を左右します。30フレーム/秒で動作するカメラは33.3 msごとに新しいフレームを出力するため、それ以上の時間がかかる検出器はストリームに遅れ、リアルタイム推論に対応できなくなります。レイテンシはフォワードパスのみ、または生の入力から利用可能な出力までのエンドツーエンドで示されます。また、本番システムでは、遅い応答が少数でも平均値と同じくらい重要になる場合があるため、中央値(p50)や99パーセンタイル(p99)などのパーセンタイルを追跡します。
推論レイテンシを増加させる要因#
1回の予測はいくつかの段階を経ます。前処理では入力をデコード、リサイズ、正規化します。フォワードパスではネットワークを実行します。そのコストはモデルのFLOPs、入力解像度、数値精度に応じて増加し、処理速度はCPU、GPU、ニューラルプロセッシングユニット(NPU)のいずれを使うかなど、プロセッサに左右されます。後処理では生の出力を結果に変換します。検出器の場合、ボックスをデコードして非最大値抑制(NMS)を実行します。クラウドAPIでは、ネットワークの往復時間と、リクエストがキューで待機する時間が加わります。そのため、エッジAIでは、データを取得するデバイス上でモデルを実行します。また、初回呼び出しではフレームワークがメモリを確保し、重みをキャッシュに読み込み、初回実行時にカーネルを選択するため、以降の呼び出しより時間がかかります。
ハードウェアとランタイムによって、フォワードパスの速度は桁違いに変わることがあります。Ultralytics YOLO26 nanoは、CPU上でONNXを使用するとCOCOの640ピクセル画像1枚あたり平均38.9 ms、NVIDIA T4 GPU上でTensorRTを使用すると1.7 msです。Ultralytics YOLOは、結果のspeed属性に各予測のステージごとの時間を記録します。ベンチマークモードでは、各エクスポート形式について測定を繰り返します。
from ultralytics import YOLO
# Load the smallest YOLO26 detection model
model = YOLO("yolo26n.pt")
# Predict on one image
results = model("https://ultralytics.com/images/bus.jpg")
result = results[0]
# Per-image time in milliseconds for each stage of the pipeline
for stage, ms in result.speed.items():
print(f"{stage}: {ms:.1f} ms")このループは前処理、推論、後処理の時間を出力し、その合計が現在のデバイスで画像1枚を処理するモデルのレイテンシになります。
レイテンシを正確に測定する#
レイテンシの数値を比較できるのは、同じ方法で測定した場合に限られます。信頼できる測定では、数回のウォームアップ実行を除外し、多数の実行を計測して、単一実行の値ではなく中央値と裾野のパーセンタイルを報告します。GPUでは、カーネルの起動が非同期であり、早すぎる時点で時計を読み取ると処理完了前に計測が止まるため、たとえばtorch.cuda.synchronize()を使ってデバイスの処理完了を待つ必要があります。入力サイズ、バッチサイズ、精度、デバイスはすべてデプロイ時と一致させる必要があります。データセンターのGPUでのモデルのレイテンシは、スマートフォンでのレイテンシの参考にならないためです。FLOPsはハードウェアに依存せずコストを推定しますが、FLOPsが同じモデルでも、同じデバイス上で明らかに異なる速度で動作することがあります。
推論レイテンシとスループットの比較#
スループットは、画像/秒やトークン/秒のように、システムが単位時間あたりに処理する入力数です。レイテンシとは反比例することがよくあります。バッチを大きくするとハードウェアの稼働率が上がり、スループットは向上しますが、バッチ内の各入力はバッチ全体の処理完了を待つため、個々のリクエストへの応答時間も長くなります。
import time
import torch
import torchvision
# A ResNet-18 image classifier in inference mode on the CPU
model = torchvision.models.resnet18().eval()
for batch in [1, 2, 4, 8]:
x = torch.randn(batch, 3, 224, 224)
with torch.inference_mode():
model(x) # warmup run, not timed
times = []
for _ in range(20):
start = time.perf_counter()
model(x)
times.append(time.perf_counter() - start)
latency = sorted(times)[len(times) // 2] # median seconds per batch
print(f"batch {batch}: {latency * 1e3:5.1f} ms per batch, {batch / latency:4.0f} images/s")ノートPCのCPUでは、バッチサイズを1から8に増やすとスループットは毎秒168枚から220枚に向上しましたが、バッチの応答時間は6 msから36 msに延びました。そのため、運転支援や音声アシスタントなどのインタラクティブシステムはバッチサイズ1で動作し、動画アーカイブのインデックス作成などのオフラインジョブは積極的にバッチ処理を行います。LLMサーバーでは連続バッチ処理を使い、実行中のバッチにリクエストを追加・削除することで、各ユーザーにバッチ全体の完了を待たせずに高いスループットを維持します。
推論レイテンシの削減#
通常、最大の改善効果は計算量を減らすことで得られます。たとえば、より小さなモデルバリアント、低い入力解像度、またはモデルプルーニングによる重みの削減です。モデル量子化でFP16やINT8を使うと、低精度演算に対応したハードウェアでは、残った各演算のコストを下げられます。TensorRT、OpenVINO、ONNX Runtimeなどの最適化された推論エンジンにエクスポートすると、レイヤーが融合され、デバイスに最適なカーネルが選択されます。モバイル接続では数十ミリ秒かかることが多いネットワークの往復時間は、モデルをデバイス上で実行すればなくなります。
レイテンシが重要となる場面#
- 大規模言語モデル(LLM): チャットサービスでは、ユーザーが応答性として感じる初回トークンまでの時間と、ストリーミング速度を左右する出力トークンあたりの時間を計測します。投機的デコーディングでは、複数のドラフトトークンを1回のフォワードパスで検証することで、後者を短縮します。
- 産業検査: コンベヤー上方のカメラは、部品が排除ゲートに到達する前に各部品を分類する必要があるため、レイテンシがライン速度の上限を決めます。
- 自動運転車: 認識、計画、制御で限られた処理時間を共有します。時速100 kmで走行する車は、100 msの遅延ごとに2.8メートル進みます。










