CPU自己対局ループの無駄なパディングを削り、実行時間を16.6%短縮した

自己対局(self-play)、学習(training)、モデル評価(arena)をすべてCPU環境で回す1世代(generation)の実行サイクルでは、処理時間の大半をONNX Runtimeによる推論が占めていた。そこで探索アルゴリズムや学習レシピには手を加えず、ニューラルネットワークに渡すデータ行数とパディングの無駄を徹底的に削る方針で最適化を進めた。

個別のステージを対象としたマイクロベンチマークでは25.2%の短縮が確認されたものの、一連のパイプライン全体を通しで測定したところ、最終的な短縮幅は16.6%にとどまった。本稿では実態に即した指標として、後者の数値を採用値としている。

何を変えたか

変更内容測定結果
論理CPUではなく物理コアごとにworkerを配置16 workers 約5,400 rows/s → 8 workers 約7,600 rows/s
同一の公開局面(public state)に対する推論結果をメモ化evaluator rows: self-play -8.1%、arena -2.8%
合法手の候補数に応じてバッチを適切に分割padded/actual比: self-play 1.68→1.08、arena 2.22→1.11
opset 20のGELUを使用0.937 ms/row → 0.899 ms/row
存在するentity/candidateの行のみを計算約8,100 rows/s → 約11,800 rows/s

特に大きな効果を上げたのは、やみくもにワーカー数を増やすことではなく、不要な行(row)や余計なパディングの削減だった。

実ループでは16.6%短縮

同一のGCE c3d-standard-16 Spot VM環境において、自己対局256局、学習512 updates、arena評価800 pairsからなる1世代をエンドツーエンドで比較した。

stagebaselinetreatmentchange
self-play196.0 s164.4 s-16.1%
training375.7 s325.1 s-13.5%
arena1,285.5 s1,053.7 s-18.0%
generation total1,866.3 s1,555.6 s-16.6%

baselineではarenaが世代全体の処理時間の約69%を占めていたため、自己対局や学習だけを高速化してもエンドツーエンドでの改善幅には限界があった。

高速化したが採用を見送った手法

試したもの結果採用しなかった理由
dynamic INT88,139 → 13,286 rows/spolicy top-1一致率が94.8%に低下し、評価器の挙動自体が変わる
bf16 CPU training1 updateで約19%高速化学習レシピの前提が変わってしまう
arena concurrency 32→128約19%低下ワーキングセットの増大によるキャッシュ効率悪化

単体のマイクロベンチマークだけでなく、実際に運用するワークフロー全体で検証し直したことで、確実に享受できる実行時間短縮の効果を16.6%と見極めることができた。同じCPU予算のなかで実験のイテレーション回数を増やせることが、今回の最適化の最大の成果である。


この記事は、実装・実験記録をもとに、本文の大部分をLLMが執筆し、筆者が内容を確認・編集しています。