蒸留ランナー

重くて遅い教師(全通り先読みプランナー。LLMの代役)のプレイを記録し、勾配ブースティング木(LightGBMと同じ方式をJSで実装)に蒸留しました。教師は1判断に数ms〜数十msかかりますが、生徒は数µsで判断します。応答に260msかかる条件では、教師は間に合わずに落ちますが、生徒はリアルタイムのまま、学習に使っていない開始条件の4分の3をクリアします。

プレイヤー
判断が反映されるまでの遅延
フレーム(0〜179)
いまの判断
―
判断1回の計算時間
―
生徒の推論(1万回平均)
―
到達距離
―

入力される特徴量

ハーネスが毎判断つくる21次元ベクトル(右は重要度)

画面の画像は使いません。記事のハーネスと同じく、ゲーム内部の状態を数値に直して渡します。

terrain_0〜9 は前方10タイルの地面の高さです(足元との差、穴は−9)。e1 / e2 は前方の敵2体の相対位置と速度です。

操作は記事と同じく2択です。right_run(右へ走る)と right_run_jump(走りながらジャンプ)のどちらかを4フレームごとに選びます。

蒸留の手順

1

教師がプレイして記録

開始待機0, 3, 6 … 177の60通りで教師がプレイし、クリアした回の「状態 → 選んだ操作」を記録します。

2

勾配ブースティング木で学習

完全一致の重複を除き、少数派の「ジャンプ」に重みを付けて二値分類を学習します。葉31枚 × 300本、学習率0.1です。

3

未知の開始条件でテスト

学習に使っていない開始待機120通りで、生徒をリアルタイムにプレイさせます。

結果

プレイヤー方式判断1回クリア

作ってみて分かったこと

そのまま真似させると、見たことのない状況で崩れる。最初の版では、学習データの正解率が98%でも、未知の開始条件でのクリアは5%でした。教師が「ぶつかる直前の最後の瞬間」に跳ぶので、生徒の判断が4フレームずれるだけで詰むためです。

教師を「真似しやすい教師」にする。「最善の続きが生き残るか」ではなく「続きの手順のうち何割が生き残るか」で判断する教師に変えると、余裕を持って跳ぶようになり、生徒の成績が大きく上がりました。

学習範囲の外には弱い。開始待機0〜59で学習して60以降でテストすると、ほぼ全滅しました。敵の配置が見たことのない形になるためです。そこで学習とテストは同じ0〜179の範囲から、重ならないように取っています。生徒が自分で訪れた状態に教師がラベルを付け足すDAggerも試しましたが、この設定では伸びませんでした(91→87〜91/120)。

ハーネスを単純にする。ボタンを押す長さでジャンプの高さが変わる仕様では、空中での押し方までラベルに影響して学習が崩れました。ジャンプの高さを固定し、判断を接地中に集中させています。

参考:Jevにゲームをやらせるな!LLMを蒸留してみよう!(Zenn)