小さなモデルの過大な性能主張を見抜く
一言でいうと
モデルのファイルサイズと実行性能を分けて測り、デプロイの根拠の範囲を明示します。
なぜ必要なのか
小さくなったモデルを見て「メモリも減って、どこでも速くなりました」と報告すると、何が抜けているでしょうか。ファイルはディスク上のバイト数であり、実行中のプロセスにはPython・推論エンジン・作業バッファも含まれます。デプロイの判断には、精度だけでなく、何をどんな環境で測定したのかが必要です。このラボは、量子化の勝利を保証する大会ではなく、根拠を持ってデプロイの可否を決める練習です。
どう動くのか
提供されるbench.pyは、モデルの読み込みと入力の準備を時間測定の外に置き、engine.runの呼び出しを測ります。したがって、報告されるレイテンシはウェブリクエストの全体の応答時間ではありません。CPU推論のスレッドは1つに固定し、独立した3ラウンドで、バッチサイズごとにウォームアップ10回のあと100回ずつ測定します。バッチサイズは1と32です。モデルの実行順序もラウンドごとに交互にします。測定値の単位はマイクロ秒/バッチで、各バッチには合計300個の生の時間が残ります。
latency_stats(samples_us, batch_size)を実装するとき、p50は並べ替えたサンプルの中央値、p95はnearest-rank方式のceil(0.95×n)番目の値です。Pythonのインデックスでは、ここから1を引きます。サンプルが偶数個のときの中央値は、真ん中の2つの平均です。ラウンドごとのp95を平均せず、生のサンプルを合わせてから計算し直します。スループットは、batch_size×n×1,000,000/sum(samples_us)です。バッチ32の時間をそのまま1秒あたりのリクエスト数に反転すると、画像の数が32倍ずれます。
メモリは、Linuxの/proc/self/statusのVmHWMをバイトに換算して記録します。これは測定プロセス全体の最大常駐メモリであり、モデルだけのメモリでも、GPUメモリでもありません。今回の開発コンテナでの測定の1つでは、モデルファイルが約70KBから24KBに減っても、プロセスのHWMは約62MBで同程度でした。時間は、共有CPUの負荷・命令セット・ランタイムなどによって変わるため、その数字を採点の正解として固定しません。
benchmark.jsonは、モデルとデータのSHA-256を一緒に記録します。モデルを再変換したなら、測定もやり直す必要があります。ハッシュの連結と統計の検査は、古いレポートや計算の誤りを見つけますが、学生が時間を自分で作って書いていないことを証明する仕組みではありません。生のサンプルはレビュー可能な実験の記録であって、改ざん防止の証明書ではありません。
実務のレビュー会議で聞かれる質問
「どれだけ速くなりましたか」と聞く前に、「どこからどこまで測りましたか」と聞いてみてください。ファイルの読み込みやモデルのロードまで測ったcold startと、すでに準備されたセッションのrun呼び出しは、ユーザーが体験する別の状況です。アプリを1日に1回開く人と、同じセッションで映像を処理し続ける装置では、重要な指標が違います。今回のラボは後者の一部である、準備済みのCPU推論を測定するもので、ネットワーク・画像の前処理・結果の受け渡しの遅延は含みません。
3ラウンドのp95がそれぞれ10、20、100なら、平均の43.3を全体のp95と書いてもよいでしょうか。パーセンタイルは、データの個数と順序によって決まります。ラウンドの要約3つだけでは、どちらに遅いサンプルが何個あったのかを復元できません。そのため、ヘルパーは生の時間をすべて残し、学生の関数は合わせた300個を並べ替え直します。逆に、生の時間をすべて捨てて要約だけを保存すると、外れ値を見直す根拠もなくなります。
単位を付けた手計算もやってみてください。バッチサイズ32で300回繰り返すと、画像は合計9,600個です。時間の合計が3,000,000マイクロ秒なら3秒なので、スループットは3,200個/秒です。バッチ呼び出しの数を分子に使うと100回/秒になりますが、その値自体が間違っているわけではありません。間違いは、それを画像のスループットと名付けることにあります。レポートのキーと単位が、計算式の意味を固定しなければなりません。
平均的には速くても、まれに長い遅延が現れるモデルは、締め切りのある作業には合わないことがあります。しかし、このラボのp95が、ハードリアルタイムの上限を保証するわけではありません。まだ観察していない負荷や装置の条件があります。電力・熱・長時間の安定性も、別のテストが必要です。target_benchmark_requiredをtrueのまま残すのは、仕事を終えていないことを隠すための文言ではなく、今回の証拠では主張できない部分を正確に引き継ぐための申し送りです。
最後に、モデルを再変換したときに何をやり直す必要があるかを書き出してみてください。ハッシュだけを新しく書くのではなく、推論の回帰と測定をもう一度実行する必要があります。新しいファイルのハッシュを古い時間サンプルに付けると、連結の形式は合っていても、実験の記録は偽りです。自動採点が、すべての行動を監視できるわけではありません。再現スクリプト・生の結果・実行条件を一緒に残し、同僚が同じ方法でもう一度確認できるようにすることが、実務の基本です。
次のラボですること
ステップ7で統計関数を実装し、提供された測定ヘルパーを実行してください。ステップ8のrelease.jsonには、モデルファイルが32KiB以下、精度の低下が1%p以下という、この実験のデプロイ条件を記録します。これは、プロセス全体が32KiBの中で動くという意味ではありません。target_benchmark_requiredはtrue、universally_fasterはfalseです。実機のレイテンシ・メモリ・電力の検証は、別に残ります。ラボを終了する前に、ソースとレポートを保管してください。セッション終了後、作業ファイルは残りません。