NNUE評価関数、新しい時代の夜明け

いま、将棋AIの世界はdlshogiに代表されるDeep Learning型の将棋ソフトと、αβ探索を用いる従来型の将棋ソフトとに大きく二分される。後者の上位ソフトは、評価関数にNNUE評価関数を採用しており、後者のタイプのソフトはNNUE型と呼ばれるほどの一大勢力を築き上げている。

このNNUE評価関数を設計したのは、tanuki-チーム(当時)の那須さんである。NNUEは浅い層からなるニューラルネットワークだが、那須さんの実装は、C++ templateで書かれていて、層を増やしたり特徴量の数を変更したりできるようになっていた。

そのソースコードを初めて目にしたtanuki-さんは当時次のようにツイートしている。

ところが、那須さんが公開時に決めた層の数や入力特徴量の数を変更しようという人はなかなか現れなかった。当時、このことを那須さんは嘆き、コンピュータ将棋開発者に大変失望されていたように思う。

那須さんが公開時に決めたアーキテクチャは、その後、「標準NNUE型」と呼ばれるようになり、実質的にこれが標準化していき、現在に至る。

何故、他の開発者がアーキテクチャを変更しなかったのかと言うと、アーキテクチャを変更しても強くならなかったからである。それどころか、標準NNUE型の評価関数も、tanuki-さんがWCSC28(第28回世界コンピュータ将棋選手権)の大会後に公開された評価関数ファイル(評価関数パラメーター)からの追加学習でしか他の開発者は強くできなかった。実は、1から学習させて、WCSC28 tanuki-から追加学習させる場合と同じだけ強くした人はいなかったのである。水匠とて、その例外ではなかった。

// ちなみにtanuki-さんのWCSC28の出場ソフト名は「the end of genesis T.N.K.evolution turbo type D」これは、「the end of genesis TMRevolution turbo type D」のオマージュであろう。ソフト名を読み上げるのが年配の方には難しいようで、CSA(コンピュータ将棋協会)の瀧澤武信会長には大会中に「ソフト名は読みやすいものを」とやんわり注意された。

何故、1から学習すると強くできなかったのか。

まず、1から学習させる場合、学習までに時間がかかるので、たくさんの実験をすることができない。このため、条件を色々変えつつ、実験をするだけ計算リソースを持っている人がいなかったのである。

もう少し正確に言うと、ニューラルネットワークの学習は、BP(= Backpropagation : 逆伝播法)を用いるのだけど、NNUEは1つの層の入出力特徴量が少ないのでこの部分の並列化効果に乏しく、128スレッドで学習を走らせても16スレッドあたりで学習速度が頭打ちになるのである。

なので、複数の学習を並列で走らせれば良いのだが、手探りで学習させている場合、学習結果を見てから条件を調整しなおしてまた1から学習させたいわけで、並列で走らせれてもあまり嬉しくなかったのである。

1から学習すると強くできなかったもう一つの理由は、学習にはqsearch(静止探索)を用いるのだが、やねうら王のqsearchの仕様がちょくちょく変わるからである。これは、Stockfishのソースコードに、やねうら王が追随するからでもある。

tanuki-さんの大規模な実験により、やねうら王のどのバージョンで学習部がリグレッション(後退)したのかが判明しつつある。

なんと、学習に用いるやねうら王のバージョンにより、(最大で)R70ぐらいの差がある。おまけにここ近年のやねうら王だと悪いほうに変移しつつある。

そう言えば、水匠の開発者のたややんさん(やねうら王チーム)は「最近のやねうら王だと学習がうまくいかないので、古いやねうら王を学習に使っています」みたいなことをずっと言ってて、私は「そうはならんやろ」と思っていたのだが、「なっとるやろがい」であったのだ。ほんま、ごめん。

それで、まだ具体的な原因はよくわかっていないというのが実状なのだが、これが判明するのは時間の問題であろう。ともかく、これくらい大規模な実験をしないと原因の究明は難しく、私が一人で開発してたら永久に気づくことはなかったであろう。(やねうら王のバージョンによって学習がサチった時の強さが異なるだなんて私は微塵も考えていなかったわけで…。)

そうこうしているうちに、tanuki-さんが標準NNUE以外のNNUE評価関数で成果を出しつつある。tanuki-さんは、WCSC32(第32回世界コンピュータ将棋選手権)で halfkp_1024x2-8-32 という新しいアーキテクチャを採用された。(プログラム名「マメット・ブンブク」)

さらに、NNUEの学習部をPyTorchで書き換えるという作業をされている。長らくバグっていてうまく学習が出来ていなかったのだが、このバグが最近取れたらしく、学習が回るところまでは作業が進んだそうである。最終的に学習されたものは、水匠に比べるとまだ最終的に学習される評価関数パラメーターだと少し弱いようなのだが、上に書いたやねうら王のバージョンとも関係する問題かも知れない。

また、PyTorchを用いる場合、学習にGPUが活用できる。これがCPUで学習させる場合に比べてどれだけ速いのか?tanuki-さんに尋ねてみた。

とのことであった。

さきほども書いたように、CPU側は16スレッドぐらいでサチってしまうので、それ以上スレッド数を増やしても速くはならない。GPUを使う場合、RTX 2070のような少し古いGPUですら8.8倍もの速度が出るのである。

RTX 3090Tiだとおそらくその3倍近くは出るだろうし、この夏に発売になる4090であれば、さらに倍近く出るだろう。

凄まじい学習速度である。これだけの速度が出れば、NNUEの様々なアーキテクチャで1から学習させて比較実験を行うことが容易になる。

そんなわけで、NNUE評価関数はいままさに新しい時代の夜明けを迎えようとしている。ここ近年、NNUE評価関数に進歩がなかったがtanuki-さんのお陰で視界が一気に開けてきた。

NNUE評価関数、新しい時代の夜明け」への15件のフィードバック

    • WCSC29のやねうら王は0からの学習です。ただ、それはWCSC28のtanuki-とほぼ同等のところまでしかいけてないです。

      のちの研究により、そこから追加学習をした場合、WCSC28のtanuki-から追加学習するよりRが伸びないことが判明しました。その原因に対する仮説は色々あるんですが、ここに書くには余白が狭すぎて。(←と言って逃げる)

    • elmo(WCSC29)が「ゼロベクトルから」と書いてあるのは、他の教師からの追加学習ではなく、1からの意味です。(実際はNNUEはNNなのでパラメーターはゼロベクトルで初期化されるのではなく、乱数で初期化されますが。)

      ただ、elmo(WCSC29)も水匠は越えてなくて、その水匠がtanuki-(WCSC28)からの追加学習だったので、結局、tanuki-(WCSC28)からの追加学習が最高、みたいな結論に長らくなっています。

      • あ、なるほど!
        最強評価関数(e.g.水匠)=tanuki-(wcsc28)+追加学習分で、右辺の左側の元となる評価関数がtanuki-より適したものがいないってことでしたか。少し読み違えており、ややこしいコメントとなってしまい申し訳ありませんでした。にしても、奥が深いですね~

        • 追加学習について質問なのですが、やねうら王NNUE評価関数では、まだ学習の余地あり/過学習などは何をもって判断なされてるのでしょうか?
          また、評価関数の構造を理解しきれていないのですが、水匠を見て
          「これはタヌキから派生しているものだね」などわかるものですか?

          • > まだ学習の余地あり/過学習などは何をもって判断なされてるのでしょうか?

            損失関数(Loss function)の出力する値(←機械学習ではこれが減ることを目的としている)を見た上で、実際に対局させて強くなっているかどうかも確認しています。

            > 「これはタヌキから派生しているものだね」などわかるものですか?

            NNの場合、追加学習ではあまり値が動かないのでわかりますね。

  1. >>16スレッドあたりで学習速度が頭打ちになるのである。
    むちゃむちゃ興味深いですね、ここを見ただけでAWSとAzureの無駄な費用削れそうですw
    やねさん水匠の評価関数を相当評価してるみたいですが、やねうら王評価関数もいま手を加えたらいまのトップ帯に並べるのでは??怪しい部分もあった当時の100TBookで優勝したので評価関数自体も強いと思うんですよね‥もしどこかで機会あるなら野良でいじってみたいですなw

    • 私は水匠5が最強だと思っていて、たややんさんが水匠8とかをリリースしてもしつこく水匠5を使い続けてこれで大会優勝してやるつもりだす。← 嫌がらせの域

      • ナンバリングのどれがどのくらい強いかよくわかってない人⇐

        そういえば評価関数の学習で1個知りたいことがありました。
        振り飛車評価関数の追加学習をしたくfgでdlshogiが振った棋譜やShogiGUIで条件もたせて対局した棋譜を使いたい。評価値のスケールが異なるので、振り飛車を評価する既存の評価関数を使ってShogiGUIで棋譜解析させてその評価値を学習の際に使いたいのですが、そんなことって可能だったりしますか?

        • > 評価値のスケールが異なるので

          それはスケールを変換すれば良いだけでは…。
          シグモイド関数で勝率に変換できるので(この時、スケールを調整)、そのあと逆変換(この時、スケールを調整)すれば良いだけで…。

          • ありがとうございます。スケールに加え振り飛車過小評価もなおしたいところもあり…
            解析機能の評価値を転用できないかな〜というところを聞きたかったです。

          • 解析機能を転用するのは、プログラムを少し書けばできるとしても、解析作業が自動化できないので、やめたほうがいいような…。

            やねうら王の”makebook think”という定跡を与えてそこに評価値をつけるコマンドがあるので、その処理部分のソースコードを見れば、並列的に任意の局面を調べて評価値を出力する方法がわかるかと思います。プログラムが少しでも書けるならそっちがお勧めですね…。

          • (返信タグがなかったのでここから)
            夜分遅くにありがとうございました!

  2. 初歩的な質問なのですが、浅い層からなるニューラルネットワークでNNUE評価関数が作られていると思われるのですが、Deep Learning型の将棋ソフトとの違いは何でしょうか?

    • DeepLearning系は探索部にMCTSが使われていること、かなり深い(ResNet 10b~40b)ネットワークアーキテクチャであることが大きな違いっすかね。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です