機械学習周りのプログラミング中心。 イベント情報
ポケモンバトルAI本電子書籍通販中

iPadのNeural Engineで将棋AI part13 細かい話

他の記事で書きそびれた細かいテクニック等をまとめておきます。

CSAプロトコルでの対局テスト

  • shogi-server shogi-server をサーバとして使います。
  • ruby 2.7.5をインストールする必要がありますが、それ以外は最新のMacで問題ありませんでした。
  • 対戦相手は将棋所でサーバ通信対局機能を用いて、lesserkaiなどを投入しました。
  • ponder機能の確認は少々面倒です。lesserkaiはすぐ指すので確かめられず、やねうら王などの著名なソフトは強すぎます。負けるのを承知でやねうら王などでponderが動作することをローカルで確認しつつ、floodgateで動作を確認した形です。
    • 自分のソフトが決定的な挙動をする場合に、lesserkaiを相手にすると全く同じ進行になる場合がよくありますが、たまに違う進行になる場合もあり動作確認の相手としては不便に感じました。決定的に動くモードとあえてランダム要素を入れて様々な状況を試せるモード、ponder確認のためにランダムな時間待ってくれる機能等がついた対戦相手を作ってもいいかもしれません。

DNNモデル

  • 最初は、「強い将棋ソフトの創りかた」のサンプルコードのデフォルトパラメータで学習できる、10ブロック(20層)192チャンネルを試していました。バッチサイズ16で1000samples/sec程度でした。
  • 処理時間でDNN評価に90%程度、それ以外の合法手生成や探索木の処理が10%程度でした。
  • 合法手生成等の高速化に時間を割けないので、DNN側を重くしたほうが強いのではないかと思い、dlshogi本家で使われているといわれる15ブロック(30層)224チャンネルのモデルを学習しなおしました。バッチサイズ16で600samples/sec程度でした。
  • 探索ノード数が少ない状況でバッチサイズを大きくすると変な探索結果になる場合があったため、最終的にバッチサイズ1で動作させることにしました。探索部含めて、およそ330NPS(1秒当たり330局面についてDNNを評価)となりました。

思考時間

10秒に固定して試作し、そのまま変更していません。時間が足りない場合はそれに応じて思考時間が短くなります。10秒経過したら探索を止めて、その後最善手の計算と送信が入るのでサーバには11秒と計測される場合がほとんどでした。

定跡

ソフトウェア実装はSwiftで新規に書きましたが、評価関数・探索アルゴリズムはdlshogiと類似しており、棋風としてはdlshogiやそのライブラリを用いたソフトの探索が浅い状態のものとなることが予想されました。棋譜としてありきたりだとつまらないと思い、初手だけランダムにすることにしました。初手では2六歩、7六歩および悪手を除外した20通りの手からランダムに指すこととしました。悪手を除いた初手のリストは、ponanzaで使われた初手のリストに準拠しています。 「第2期電王戦バージョンのponanzaが指さない初手は ▲8六歩、▲9八香、▲6八金、▲5八金左、▲4八飛、▲3八飛、▲1八飛、▲1八香の8通り。 それ以外の22通りの初手を指す。」 参考: https://twitter.com/floodgate_fan/status/851019316522762240

後手番になった場合も定番の3四歩、8四歩以外にしようと思いましたが、先手の初手によっては悪手となる手があると考えられます。そのため、1手目それぞれに対して、2手目の全候補手を指した場合の評価値を計算しました。

1手目、2手目の組み合わせによる評価値(先手から見たもの)

角頭の歩を突く△2四歩はよくないですが、初手が▲2六歩の場合は特に悪い評価値になるということがわかります。この表に従い、各初手ごとに、3四歩、8四歩以外で評価値上位3手を等確率に選びました。結論は以下の表のようになります。

2手目としてランダムに選ぶ手の候補

3手目以降は定跡なしです。

棋力と今後

floodgateで対局した結果、レート基準となるgikou2_1cとほぼ同等の3300でした。 iPadでDNNを使った場合の棋力を単純に推測するなら、モデルの実行速度だけ検証し、PC上でdlshogiの探索ノード数をそれに合わせて動作させれば十分なのですが、iPadで実際に動くものが作れるかという検証を最後まで行うことができました。有線LANの接続や冷却などの課題はスムーズに解消でき、慣れないSwiftと格闘するのが主に苦労する点でした。

レート3700の"Kristallweizen-Core2Duo-P7450"が文字通りの内容、つまり2019年のNNUE型評価関数Kristallweizenと2009年発売のノートパソコン向けの2コアのCPU、Core2Duo-P7450の組み合わせだとすると2021年発売のiPadのCPUがこれに劣るとは考えにくいです。つまり、CPUで深く探索するタイプのソフトを実装したほうが強いと思われます。dlshogiでは即詰みについては探索が入っていますが、見落としによって形勢が悪化するような状況まではケアできず、300NPS程度では評価関数の精度が少々向上しても見落としを避けられないと考えています。 ハードウェアをiPadに固定した場合で最強を目指すなら、CPUでの探索をメインとして、GPU/Neural Engineを補助的に使うような仕組みが良いと考えられます。合議や、WCSC27のPonanza Chainerのように探索の順序のヒントとして使うということが考えられます。

今回はUI、通信部、探索部それぞれ1スレッドで動作させるという形でしたが、探索内部で複数スレッドを密に連携させるとなるとSwiftはつらいかもしれません。C言語にあるvolatileなどの機能がない C volatile equivalent | Apple Developer Forums ことや、インラインアセンブラが使えないなどの制約があります。デバッグ中にも、複数スレッドから局面データを操作しようとするとSwift言語からは明示的に使っていないmalloc関連のエラーで止まってしまうという事象がありました。現実的にはコア部分はC++で実装し、UI等はSwiftで実装するというのが妥当と思われます。技術的に面白そうな課題としては、AMD64SIMD命令で書かれた探索部をARMの命令に置き換える部分でしょうか。最近のApple端末のマルチコアCPUは、high-performance coreとhigh-efficiency coreという非対称なコアが搭載されているため、うまく連携できるかどうかも検証する必要があります。 Appleの開発環境にはまだまだ慣れないのですが、やねうら王を単純に移植してどの程度強くなるかをいずれ検証してみたいです。

まずは明日の選手権本番を楽しみたいと思います。