はじめに
まずはじめに、本大会の運営に携わった皆様、対局いただいた皆様、本当にお疲れさまでした。 そして素晴らしい大会を開催していただき、ありがとうございました。
おかげさまで、「氷彗」は第36回世界コンピュータ将棋選手権で優勝することができました。
正直なところ、今回はそこまで「優勝を狙うぞ」という感じで出場したわけではありませんでした。 自分はこれまで選手権で二次予選を突破したことがなく、コンピュータ将棋を長くやってきた中で、それだけがずっと心残りになっていました。 決勝は会場に行かなくてはならず、そのハードルが高かったため、二次予選突破したら辞退しようかと思っていました。
そのため、電竜戦が終わってからは、選手権向けに短期的な調整をするというより、中長期的にソフトを強くする方向を優先していました。 実際、電竜戦以降そこまで大きく強くなったわけではありません。それでも今回優勝することができ、かなりうれしく思っています。
有効だったこと
コーディングエージェントの活用
今回かなり大きかったのが、コーディングエージェントの活用でした。
大会前の修正の多くは、コーディングエージェントを使って短時間で実装しています。 単純な実装補助だけではなく、将棋プログラム自体の改善案や実装もいくつか行ってもらいました。
特に大きかったのは、「Stockfishとの差分を極力減らす」という考え方をやめられたことかなと思っています。
これまでは、
- upstream に追従しやすくする
- 差分管理を楽にする
- 大規模変更時のマージを簡単にする
といった理由から、かなり Stockfish 互換を意識していました。差分が大きくなればなるほど追従コストもかなり大きくなります。 ですが最近は、コーディングエージェントによってそのあたりのコストをかなり下げられるようになってきました。
その結果、 「Stockfish と違うからやめておこう」 という判断をしなくてよくなったのは大きかったと思っています。
今後は、Stockfish互換性をそれほど意識しない方向になるかもしれません。
nnue-pytorch の高速化
最近は bullet-shogi を使って学習するチームもかなり増えてきているようです。 github.com
一方で自分は引き続き nnue-pytorch を使っているのですが、以前から不満だったのが GPU 使用率でした。
学習中、GPU 使用率が30%程度しか出ておらず、かなり効率が悪い状態になっていました。 そこで学習部分を見直し、GPU をほぼフルに使えるように修正しました。 これによって学習速度がかなり改善し、実験サイクルを高速に回せるようになりました。
体感では、学習時間は以前の1/3程度になっていると思います。 現状では bullet-shogi と比較してもかなり近い速度が出ています。
この高速化によって、今まで重くて試せていなかった実験にも手を出せるようになりました。 実際、選手権後に試した実験だけでも、すでにレートが70程度向上しています。 こんなに伸びそうならば、もっと早く取り組んでおけばよかったかなと思っています。
自動対局システム
大会期間中、常にPCの前に張り付くことが難しかったため、USIエンジンをCSAサーバーへ接続する自動対局システムを構築しました。 前回の電竜戦で不戦敗となった対局があったので、ネットワーク監視やエンジンプロセス監視を強化したいと思っていました。 実装はGolangで行い、主に以下の機能を持っています。
- ネットワーク切断時の自動再接続
- エンジン異常終了時の自動復旧
- 連続対局
将棋AIそのものとは直接関係ありませんが、大会運用面ではかなり重要だったと思っています。 特に長時間大会では、「安定して動き続けること」の価値はかなり大きいです。
時間制御の修正
電竜戦は比較的短時間なので、これまでは時間制御をそれほど重視していませんでした。 一方で選手権は持ち時間が長めなので、時間の使い方によるレーティング差はかなり大きいと感じています。 そのため今回、時間制御周りにもある程度手を入れました。
本当は SPSA でしっかり最適化したかったのですが、そこまでは間に合いませんでした。 それでも以前よりはかなり改善できたかなと思っています。
長時間対局では、
- どこで時間を使うか
- どこで節約するか
- 評価値が揺れている局面でどう粘るか
といった部分の積み重ねがかなり効いてくる印象があります。 このあたりはまだ改善余地が大きそうです。
有効ではなかったこと
dlshogi 60ブロックモデルでの revalue
電竜戦後、dlshogi の60ブロックモデルを使った revalue を試していました。 ただ結果としては、あまりうまくいきませんでした。
おそらく値が正常についていない局面があり、かなり不自然な挙動をしていました。 まだ原因を追い切れていないため、今後もう少し調査したいと思っています。
利き特徴量を考慮した新特徴量
Stockfish では full_threats 特徴量など、新しい特徴量が少しずつ導入されています。 NNUE系はかなり成熟してきていますが、長期的には特徴量を更新していかないと頭打ちになると思っています。
将棋では実績のある利き情報を考慮した新特徴量を試していましたが、現状ではあまり良い結果にはなりませんでした。 ただ、nnue-pytorch の高速化によって実験速度はかなり改善したので、今後も継続して試していきたいところです。
HalfKAv2_hm 特徴量
HalfKAv2_hm も試していました。 結果としては、ほんの少し弱くなる程度でした。
ただ、L1層を伸ばせそうな感触自体はあるので、完全に諦めたわけではありません。 こちらももう少し別方向から試してみたいと思っています。
今後
LayerStack
今回、いくつかのチームが進行度ベースで LayerStack を切り替えていました。 自分も「現状の構成が最適ではないだろうな」と思いつつ、長らく放置していた部分になります。
ただ、選手権後の実験で、進行度とは別の切り分けによって、20〜30程度レートが伸びそうなものが見つかっています。 進行度ベースも含め、どの切り方が良いのか今後探していきたいと思っています。
学習方法
nnue-pytorch を高速化できたので、学習周りについては今後さらに進めていきたいと思っています。 なお、現時点では bullet-shogi に乗り換える予定はありません。
理由としては、
- PyTorch ecosystem の自由度が高い
- 実験しやすい
- 小回りが利く という点が大きいです。
また、Stockfish側も現状 nnue-pytorch を捨てていないため、しばらくはこちらを使っていく予定です。
ネットワーク構成
これまでは「Stockfish互換」をかなり意識していたため、効果が薄くても残している構成がいくつかありました。 ただ、コーディングエージェントによって実装コストがかなり下がったので、この辺りも今後はもっと自由に変えていきたいと思っています。 そろそろ、「互換性のためだけに残しているもの」は見直していく時期なのかなと思っています。
特徴量
長期的にさらに壁を突破するには、やはり特徴量の進化は必要だと思っています。 最近のNNUEはかなり成熟しているとはいえ、まだ改善余地はあるはずです。 今回うまくいかなかった実験も含め、今後も継続して試していきたいと思っています。
