状態:ドラフト(2026-10-16)、一部実測。 段階別の時間は、ジップラボの8GB級ノートPC用GPU1基が搭載されたサーバーにおいて、使い捨てのポッド(CPU4コア制限)で測定しました(ウォームアップ30回後の300回の中央値)。スマホでのキャプチャ・エンコード時間とインターネット区間は 未計測です。キューの模倣はノートPC用CPUのサンプル(
code/01_latency_queue.py、1秒前後)です。 シリーズ「ビジョンモデルを読む3:リアルタイムで動かす」第1編。このシリーズでは ビジョンモデルを読む1·2で見たモデルを 定められた時間内 に動かす方法を扱います。
目次
- 1. 「リアルタイム」の2つの数値
- 2. 段階を重ね合わせる場合:スループットは増加し、遅延はそのまま
- 3. 処理が追いつかない場合:キューに並べるか、破棄するか
- 4. 遅い正解は不正解:Streaming Perception
- 5. 私たちの実測:ボール検出の1フレームの生涯
- 6. 数値を読み取る習慣
- 7. 限界
- 8. 私たちのプロジェクトとのつながり
- 参考文献
1. 「リアルタイム」の2つの数値
卓球のスコアボードアプリが「リアルタイム」であるためには、2つの条件が同時に満たされなければなりません。
- スループット(throughput):1秒間に何フレームを処理するか。カメラが30fpsで提供する場合、30以上でなければ処理が追いつきません。
- エンド端の遅延(end-to-end latency):1フレームが撮影された瞬間からその結果が画面に表示されるまで。ボールが跳ね返った後、スコアボードがいつ変わるかを決定します。
両者は混同されがちですが異なる数値です。スループットは「最も遅い単一の段階」によって決まり、遅延は「すべての段階の合計 + キューで待機した時間」です。30fpsのフレーム間隔である1000 ÷ 30 = 33.3ms はスループットの予算であり、遅延の上限ではありません。段階を重ね合わせれば遅延が33msを超えても30fpsを出すことができ、逆に遅延が10msであってもキューが蓄積すれば1秒後の結果を見ることになります。
2. 段階を重ね合わせる場合:スループットは増加し、遅延はそのまま
前処理8ms、推論25msを順番に行うと1フレームに33ms、1秒間に30.3枚になります。前処理を別のスレッドであらかじめ行っておくと(パイプライン)、GPUは休むことなく推論だけを行うため1秒間に40枚まで向上します。しかし、1フレームが経験する時間は依然として8 + 25 = 33msです。
처리량 = 1 ÷ (가장 느린 단계의 시간)
지연 = 단계 시간의 합 + 줄에서 기다린 시간
리틀의 법칙: 처리 중인 프레임 수 = 처리량 × 지연 (40장/초 × 0.033초 = 1.32장)
リトルの法則(待ち行列理論の基本公式)は逆向きにも適用されます。スループットが決まっているにもかかわらず「現在処理中または待機中のフレーム」が増えた場合、その分だけ遅延が増加したことを意味します。
3. 処理が追いつかない場合:キューに並べるか、破棄するか
推論時間は毎回わずかに異なります。平均25msであれば通常は予算内ですが、平均が36msとなって予算を超過した場合はどうなるでしょうか。30fpsのカメラによる60秒間を模倣しました(code/01_latency_queue.out.txt、推論時間は対数正規分布、数値は説明用の仮定)。
| 推論平均 | ルール | 処理fps | 破棄されたフレーム | 遅延中央値・p99 | 60秒後の最後のフレーム遅延 |
|---|---|---|---|---|---|
| 25ms | キューイング | 30.0 | 0% | 24.6・44.1ms | 21.3ms |
| 25ms | 最新のみ | 30.0 | 0% | 24.6・44.1ms | 21.3ms |
| 36ms | キューイング | 27.9 | 0% | 2,068.7・4,465.7ms | 4,500.7ms |
| 36ms | 最新のみ | 27.4 | 8.6% | 48.0・82.3ms | 75.9ms |
予算内では両方のルールは同じです。予算を超過すると、 キューイングはスループットをほぼ維持したまま遅延が際限なく蓄積します(1分後には4.5秒遅れた画面になります)。「最新のみ」は、プロセッサが空いた瞬間に最も新しいフレームだけを取得し、遅延したものを破棄します。8.6%を破棄する代わりに遅延が抑えられます。リアルタイム映像において数秒前のフレームの結果は役に立たないため、破棄する方が正解です。TT Scoreのリアルタイムワーカーとブラウザもこのように動作します(第8編)。
4. 遅い正解は不正解:Streaming Perception
Li・Wang・Ramananによる「Towards Streaming Perception」(ECCV 2020)はこの考え方を評価方法に昇華させました。通常の検出精度(AP)は、世界がモデルを待ってくれると仮定します。この論文の streaming AP は、時刻tの正解を「t以前に計算が 終了した 最も最近の出力」と比較します。遅れて出力されたものはすでに移動してしまった世界と比較されるため、スコアが当然低下します。
| 検出器(自動運転映像30fps、1920×1200) | 1フレーム | AP |
|---|---|---|
| HTC(正確だが遅い)、通常評価 | 700.5ms | 38.0 |
| 同モデル、streaming評価 | 700.5ms | 6.2 |
| RetinaNet(最速)、0.2倍入力 | 31–36ms | 5.5–6.0 |
| Mask R-CNN、0.5倍入力、前処理GPU | 56.7ms | 12.0 |
| + スケジュール調整(時々休止) | 56.7ms | 13.0 |
| + カルマン予測、0.75倍入力で再選択 | 92.7ms | 17.8 |
(論文の表1・2、2017年のコンシューマー向け上位GPU 1枚)3つのことがわかります。
- 正確だが遅いモデルはリアルタイム処理では破綻します(38.0 → 6.2)。
- だからといって、最も速いモデルが勝つわけでもありません。その中間あたりが最適です。
- 予測(遅延の間に物体が移動した分だけ未来に押し出す)を組み合わせると、より遅くても正確なモデルが再び勝利します。遅延を「減らす」ことができなければ、「埋める」ことができます。
「スケジューリング」が興味深い点です。次のフレームが間もなく届きそうな場合は、現在のフレームの処理を開始せずに待ちます。古いフレームを処理し続けて新しいフレームを逃すよりもマシだからです。第3節の「最新のみ」と同じ考え方です。
5. 実測:ボール追跡1フレームのライフサイクル
TT Scoreのリアルタイムパイプラインをサーバー側で段階別に計測しました。実際の試合映像1フレーム(1920×1080をカメラサイズの1280×720に縮小したもの)を300回実行しました。スマートフォンが行う処理(縮小・エンコーディング)も同じサーバーCPUで模擬的に再現しました。
| 段階 | 場所 | 中央値 | p90 |
|---|---|---|---|
| 1280×720 → 512×288へ縮小 | スマートフォン(サーバーCPUで模擬) | 0.27ms | 0.30ms |
| JPEGエンコーディング(品質70) | スマートフォン(サーバーCPUで模擬) | 0.30ms | 0.31ms |
| (転送:JPEG中央値 12,252バイト) | インターネット | 未計測 | 未計測 |
| JPEGデコーディング | サーバーCPU | 0.31ms | 0.32ms |
| BGR → RGB変換、0〜1正規化、平均・標準偏差の減算 | サーバーCPU | 1.35ms | 1.38ms |
| 3フレーム分のスタック構築 + GPUへの転送 | CPU → GPU | 1.76ms | 1.86ms |
| ボールモデル推論(FP32、通常運用時) | GPU | 15.17ms | 15.19ms |
| (同じ推論をFP16で実行した場合) | GPU | 9.98ms | 10.03ms |
| シグモイド関数 + ヒートマップのCPUへの転送 | GPU → CPU | 0.18ms | 0.20ms |
| ボールの塊(ブロブ)の検出 | サーバーCPU | 0.07ms | 0.07ms |
サーバー側での1フレームあたりの処理時間は約19ms(FP32)であり、そのうち推論が80%を占めています。残りの部分で大きな割合を占めていたのはデコーディングではなく、 正規化(1.35ms)とGPUへの転送(1.76ms) でした。512×288×3をfloat32に変換すると1枚あたり1.77MBになり、3フレーム分のスタックでは5.3MBを毎回生成して転送することになります。uint8のままGPUに送信し、GPU側で正規化を行えば転送量が4分の1になり、正規化の処理もGPUが担当することになります。これについてはまだ変更しておらず、効果は未計測です。
この表には、スマートフォンのカメラによる撮影・実際のエンコーディング、インターネットの往復、Webサーバーの中継、画面描画の時間が含まれていません。それらの部分については、第8編にて実際のブラウザテストで計測したエンドツーエンドの値とともに整理します。
6. 数値を読み解く習慣
- 中央値とテール(末尾の数値)の両方を見る。 ユーザーが「カクつく」と感じるのはp99側の値です。第3節において、予算内であってもp99は44msとなり予算を超過していました。
- 条件をセットで捉える。 「推論10ms」という数値は、どのGPUで、どのようなバッチサイズで、他の処理と同時に実行されているかによって最大3倍まで変動します(第6編)。
- ウォームアップ後に計測する。 GPUの初回実行時は、カーネルの選択やメモリの確保により数秒かかることがあります。本シリーズの計測値はすべて、ウォームアップ後の繰り返し実行における中央値です。
7. 制限事項
- 第3節のシミュレーションは単一の推論段階を前提としたものであり、時間分布は仮定に基づいています。実際のシステムは複数の段階からなり、各段階にキューが存在します。
- 第5節はサーバー側のみを計測しています。スマートフォンのCPUで同様の縮小・エンコーディング処理にどれだけの時間がかかるかは未計測です。
- 人間がどの程度の遅延から「遅い」と感じるかに関する一次資料については、今回は原文を確認できなかったため言及していません。
8. 我々のプロジェクトとのつながり
- 卓球における「遅すぎる正解」とは、次のラリーが始まった後にスコアボードが更新されるような状況です。TT Scoreは、判定をラリー終了後1.5秒以内に出すことを目標として計測を行っています(第8編)。
- ブラウザは応答を受け取っていないフレームが3枚に達すると送信を一時停止し、オペレーターは溜まったウィンドウを新しいものに置き換えます。これは第3節の「最新のみ」の原則を両端で実践しているようなものです。
- 本シリーズの今後の記事では、表の中で最も大きな割合を占めるセル(推論)を削減する方法について解説します。精度(第2編)、コンパイラ(第3編)、小型モデル(第4編)、実行頻度の削減(第5編)、リソースの共有(第6編)、スマートフォン上での実行(第7編)。
TTの一言。 ボールがバウンドしてから4秒後に「バウンド!」と叫ばれても、どれほど正確であっても私はすでに次のボールを打っています。遅い正解は不正解と同じです!
参考文献
- Li, M., Wang, Y.-X., Ramanan, D. (2020). Towards Streaming Perception. ECCV 2020. https://arxiv.org/abs/2005.10420
- 我々の計測:本シリーズの実測値(生データはリポジトリ外の調査記録)、リポジトリの
docs/tt/PERFORMANCE.md第4節 - サンプルコードと出力:このフォルダーの
code/01_latency_queue.py,code/01_latency_queue.out.txt