TT Lab
ブログ

한국어 English 日本語 中文

はじめる
ブログ

ブログ

TT Scoreの実タイムパスの実際の予算表 — どこに何msを費やし、何をまだ測定できていないか

ステータス:ドラフト(2026-10-16)、実測値のまとめ。 サーバー側のステップはこのシリーズでジップラボの8GB級ノートPC用GPU1枚で計測した値であり、運用ワーカー(サーバーGPU、他のタスクとカードを共有)とブラウザエンドの値はリポジトリ docs/tt/PERFORMANCE.md の実測(2026-10-11〜15)を引用しています。スマホ内の時間とインターネット区間は 未計測です。 シリーズ「ビジョンモデルの読み解き3」第8回(最終回)。モデル自体は TT Scoreモデル解剖にあります。

TT Scoreの実タイムパスの実際の予算表

目次

1. パスをたどる

TT Score 실시간 경로의 예산 ① 서버에서 한 프레임(실험용 GPU 실측, 중앙값) 추론 FP32 15.2ms 남은 몫 서버 합 18.8ms / 30fps 한 프레임 33.3ms 풀기·정규화·GPU로 옮기기 3.4ms, 후처리 0.25ms ② 브라우저까지 왕복(운영 성능 문서의 실측) 작업자만, 세션 1 p50 24–28 · p99 31–32ms 브라우저 끝에서 끝(카드 경합) p50 65 · p90 84ms 세션 3 동시(카드 경합) p50 70–95ms ③ 랠리가 끝나고 점수판이 바뀌기까지 판정 지연 중앙 0.67–0.90초 목표 1.5초 큰 몫이 「공이 사라졌다」 를 확인하는 기다림이라 — 추론 몇 ms 를 줄여도 이 숫자는 거의 그대로
図:サーバーでの1フレームのステップ別時間(推論が大部分)、ブラウザまでの往復の3つの条件、ラリー終了からスコアボード切り替わりまでの0.67〜0.90秒と目標の1.5秒

カメラ用スコアボード(/tt/play/cam)で「自動スコア」を有効にすると、次のように処理が流れます。

  1. スマホ(ブラウザ): カメラ画面を最大30fpsでキャプチャし、512×288に中央揃えで縮小し、JPEG(品質0.7)に変換して先頭に「番号+撮影時刻」の8バイトを付与し、WebSocketで送信します。応答を受信できなかったフレームが3つたまると送信を一時中断します。
  2. ウェブサーバー: ログイン状態、座席、1日あたりの制限を確認し、フレームをそのままGPUワーカーに中継します。サイズと速度の上限(秒間36フレーム)をここでもう一度チェックします。
  3. GPUワーカー: JPEGをデコードして正規化し、セッションごとに最後の3枚でウィンドウを作成します。待機中のセッションの最新ウィンドウを1つのバッチにしてボールモデルに入力し、遅延したウィンドウは新しいウィンドウで上書きします。
  4. 後処理: 最後のフレームのヒートマップからボールの塊を探し、トラッカーで繋ぎ合わせ、バウンド・ネット・ラリー終了をルールベースで検出し、学習済みの小規模なCNNでバウンドをもう一度フィルタリングします。審判のルールによってスコアが決定されます。
  5. 応答: ボール位置はフレームごとに、バウンドや判定は発生したタイミングでJSON形式で返され、スマホ側で描画されます。

2. 予算表

ステップ 場所 計測値 出典・条件 削減方法(記事)
カメラキャプチャ スマホ 未計測 — —
512×288への縮小 + JPEG スマホ 未計測(サーバーCPUでの模倣 0.27 + 0.30ms) 本シリーズ第1回 第7回(デバイス内)
アップロード(JPEG 12〜18KB) インターネット 未計測 サイズは運用設計の実測値 第5・7回(データサイズの削減)
ウェブサーバー中継 サーバー 未計測(個別計測なし) — —
JPEGデコード ワーカーCPU 0.31ms 本シリーズ第1回 —
正規化 ワーカーCPU 1.35ms 本シリーズ第1回 GPU上で実行(第1回、未計測)
ウィンドウ作成 + GPUへの転送 CPU → GPU 1.76ms 本シリーズ第1回 uint8への変換(第1回、未計測)
ボールモデル推論 GPU 15.2ms(FP32) · 10.0ms(FP16) · 4.3ms(FP16 + コンパイル) 実験用GPU、第2・3回 第2・3回
同等の推論、運用サーバーGPU GPU 1ウィンドウ 10.5ms(アイドル状態のカード) · 34ms(他のタスク2〜3個と共有時) パフォーマンス文書 2.9.8 第6回(カードの分割)
CPUでのヒートマップ作成 + 塊の検出 GPU → CPU 0.18 + 0.07ms 本シリーズ第1回 —
卓球台の追跡(オプティカルフロー・カット判定) ワーカーCPU p50 1.72 · p95 1.77ms パフォーマンス文書 2.12(負荷の低いノード) 第5回(再検出の頻度削減)
バウンドルールの先読み エンジン 3フレーム(60fpsで50ms、30fpsで100ms) エンジン設定 —
ラリー終了判定 エンジン 一定時間ボールが見えない場合に終了とみなす エンジン設定 第1回(遅い正解 vs 間違った正解)
応答の受信 + 描画 インターネット・スマホ 未計測 — —

GPUワーカー側を合計すると約19msとなり、30fpsの1フレーム(33.3ms)の範囲内に収まります。実働ワーカーの1セッションが30fpsを処理しきれることと一致します。

3. エンドツーエンドの計測値

各ステップの合算値と、実際に計測されたエンドツーエンドの値は異なります。キューでの待ち時間、スレッド間の引き渡し、同一カード上の他のタスクによる影響が加わるためです。

項目 計測値 条件(運用パフォーマンス文書)
ワーカーの往復、セッション1 p50 24〜28ms · p99 31〜32ms、29.4fps 同一ノードのクライアント、TTSとカードを共有(4.2)
ワーカーの往復、3セッション同時 セッションあたり16〜20fps、p50 70〜95ms、p99 約127ms 同上、送信されたフレームの21〜30%が上書きによりドロップ(4.2)
ブラウザのエンドツーエンド p50 65 · p90 84 · p99 146ms、24.6fps ヘッドレスブラウザのダミーカメラ → 実装された中継 → ワーカー、カード競合中(4.1)
ラリー終了 → ブラウザに判定が到着 中央値 0.67〜0.90秒 運用エンジンコードを時間単位で実行するシミュレータ、公開映像の複数条件、キャプチャのブレ・往復60ms・ワーカー15msを運用環境に近づけた値(2.14)。目標は1.5秒

最後の行は、ユーザーが実際に感じる遅延です。1フレームの往復(数十ms)よりも10倍以上長いです。判定は「ボールが床に落ちた、または外に出た」ことを確認してから下す必要がありますが、ボールが一時的に隠れたこととラリーが終了したことを区別するには、一定時間ボールが見えない状態を待つ必要があるためです。研究記録によると、この待ち時間を短縮すると判定遅延のp90は大幅に短縮されますが、勝者の正確性がわずかに低下するため、まだ変更していません(進行中の研究)。

これは第1回のStreaming Perceptionと同じ構造です。 遅い正解と早い不正解のトレードオフであり、モデルを数ms高速化してもこの数値はほとんど変化しません。

4. では何を最初に削減すべきか

やりたいこと 最大のレバー 根拠
判定の高速化 ラリー終了判定(待機時間 vs 正確性) 第3節
1つのカードでセッションを増やす 推論:FP16 + コンパイル(15.2 → 4.3ms、実験用GPU) 第2・3回。有効化する前のボール位置の一致確認が必要
遅延のテイルを減らす カードを他のタスクと共有しない 第6回(10.5 → 34ms)
低速な回線でも 512×288・JPEG品質を維持、アップロード帯域約3Mbit/s 第7回
サーバーなしで 卓球台の検出からスマホで行う 第4・7回

第2回では、FP16でのボール位置はFP32と判定結果のいずれも同じでしたが、その測定は実験用GPUにおける1試合の388フレームでした。本番環境で有効化するには、本番GPUおよび複数の試合・劣化条件で再確認する必要があります。

5. まだ測定できていない項目

6. シリーズを終えて

このシリーズで最も頻繁に登場したフレーズは「測ってみたら予想と違った」でした。乗算を8分の1に減らしたのに1.6倍しか速くならず(第4回)、まとめれば速くなると考えていたバッチ処理はこのGPUではむしろ遅くなり(第6回)、精度を半分に落としたことよりもJPEG圧縮の方がボール位置を大きく揺るがしました(第2回)。そして、ユーザーが体感する遅延を決めていたのはモデルではなく判定ルールの待ち時間でした(本記事)。論文やドキュメントは方向性を示してくれますが、実際の数値は自分のモデル・自分のデバイス・自分の使用方法で測定して初めて明らかになります。

ティティの一言。 私がボールを見つけるには15msあれば十分ですが、スコアボードが切り替わるまでには0.8秒ほどかかります。ボールが本当に落ちたのかしばらく見守るからです。焦って間違えるよりはマシですよね!

参考文献

ログインするといいねできます

コメント

まだコメントはありません。

ログインするとコメントできます