Lightweightのモデル公開(WCSC33ver)

第33回世界コンピュータ将棋選手権で使用していたLightweightのモデルファイルを公開します。
モデルファイルのみの公開のため、USIエンジンについてはdlshogiのビルド済みエンジン等をそのまま利用ください。

特徴

・EfficientNetを主体とした軽量モデル※ではありますが、WCSC32や第3回電竜戦時とは異なり、大幅にモデルサイズを増大しています。
 そのため、以前公開したモデルよりもNPSがかなり落ちています(手元の環境では平均して21,000nps程度)
・50層のResNetで事前学習・生成したモデルを用いた知識蒸留を行っています。
・その他の特徴については、アピール文書をご確認ください。
 
(※公表されているEfficientNetの構成をそのまま使っているわけではなく、数個のResidual blockをその前段に置いています)
また、探索パラメータ設定はLightweight独自のものを推奨するため、以下で案内するZIPファイルに同梱されているparams.txtを参照ください。


モデルファイルのダウンロードについて

以下の3ファイルを同梱しています。
Lightweight_2153_WCSC33ver.onnxがモデルファイル、params.txtが推奨のパラメータ設定になります。
また、モデル公開にあたっては利用用途の制限を設けておりますので、readme.txtを必ずご確認ください。
(使用された時点で、readme.txtに記載する利用用途の制限に同意されたものとします)
 ・Lightweight_2153_WCSC33ver.onnx
 ・readme.txt
 ・params.txt



以下のリンクからダウンロード可能です。
drive.google.com

Lightweightのモデル公開

第3回世界将棋AI電竜戦 (本戦/ハード統一戦)で使用していたLightweightのモデルファイルを公開します。(1/15時点ではまだ準決勝以降を残していますが、Lightweightは進出していないため先に公開します)
モデルファイルのみの公開のため、USIエンジンについてはdlshogiのビルド済みエンジン等をそのまま利用ください。

特徴

同じDL系のdlshogiやGCT、二番絞り等と大きく異なる点は、モデルアーキテクチャやそれによる探索速度(NPS)となります。
EfficientNetを主体とした軽量モデル※であり、WCSC32時と異なり、50層のResNetで事前学習・生成したモデルを用いた知識蒸留を行っています。軽量モデルである故の評価・Policy精度のハンデは、探索量でカバーする前提となります。
(※公表されているEfficientNetの構成をそのまま使っているわけではなく、数個のResidual blockをその前段に置いています)
また、探索パラメータ設定はLightweight独自のものを推奨するため、以下で案内するZIPファイルに同梱されているparams.txtを参照ください。


参考までにですが、ハード統一戦に出場していたDL系ソフトでNPSを比較すると以下のようになるそうです。
(AobaZeroの山下さんが大会期間中に調査されていたものになります)

ソフト NPS
HoneyWaffle 59,000
Lightweight 55,500
Etude No.1 40,900
Rish 40,200
二番絞り 10,700
AobaZero 6,160



モデルファイルのダウンロードについて

以下の3ファイルを同梱しています。
Lightweight_6141_DR3ver.onnxがモデルファイル、params.txtが推奨のパラメータ設定になります。
また、モデル公開にあたっては利用用途の制限を設けておりますので、readme.txtを必ずご確認ください。
(使用された時点で、readme.txtに記載する利用用途の制限に同意されたものとします)
 ・Lightweight_6141_DR3ver.onnx
 ・readme.txt
 ・params.txt



以下のリンクからダウンロード可能です。
drive.google.com

探索木の可視化

第3回世界将棋AI電竜戦も終わってひと段落がついたので、掲題の通り、前から気になっていた探索木の可視化をやってみました。

将棋ソフト界隈ではαβ法などの説明でよく登場する探索木ですが、将棋ソフト開発者側も基本的にいつも見えているのはGUIが表示している読み筋の冒頭だけで、対局中の探索でどのように探索木が伸びていっているのかまでは見えていません。
そこで好奇心半分、探索部の復習半分として探索木の可視化を試してみました。






■対象ソフトの選定
山岡さんの書籍「強い将棋ソフトの創りかた」でも使われているpython-dlshogi2を用いました。
最初からDL系ソフトで可視化することを考えていたのと、
探索部がpythonで書かれているので扱いやすく、実行時に逐一ビルドが必要ないことから採用しました。
※モデルや探索部はpython-dlshogi2をそのまま利用しています。


■グラフの可視化手段
graphvizを用いました。
タプルを列挙するだけで簡単に有向グラフが描ける手軽さから採用しました。


■可視化方法について
mcts_player.pyの中身を書き換える形で実装しました。
先述の本でも解説されている通り、MCTSを用いるDL系将棋ソフトは以下①~③を繰り返すことで探索木を成長させます。
①選択
②展開・評価
③バックアップ

このとき、③にてバックアップを行う際にcurrent_nodeとそこに紐づくchild_nodeの情報を保持しているため、
current_nodeをキーに順次リストへ追加していくようにしました。(既に存在する場合はchild_nodeを更新する)





上記のようにして探索木を可視化したのがこちら。(※探索木が巨大(非常に横長)になるため、goコマンド実行直後の7六歩の手を探索したところで止めています)


ちなみに、もう少しだけ探索木を伸ばすと以下のようになります。横が長すぎて直接はてなブログに画像を上げれなかったのでgoogleドライブから見てください。(pcからの方が見やすいです)
drive.google.com
4手先でさえこれだけ広がってくるので、将棋がどれだけ候補手が多いゲームかが少し体感できた気がします。





今回はお試しということでpngファイルとして可視化しましたが、graphvizはさらに巨大な探索木を出力しようとするとpngファイルではつぶれてしまうのでsvg形式やPDFにする必要があるかもしれないです。


では、今度は「DL系とNNUE系で探索木の伸び方がどう変わってくるのか?」、「DL系はNNUE系と比べて本当に狭く深く読んでいるのか?」という話が気になってくるのですが、NNUE系ソフトはソースコード全然読んだことがなく不慣れ(やねうら王コマンド叩いたことくらいしかない)なので、もし誰か既にやっている方orやってくれる方がいたら教えていただけると嬉しいです。

【dlshogi】Google Colabのノートブック上でdlshogiのビルドができないときに

最近Google Colabでdlshogiをビルドしようとしたら躓いたのでメモを残しておきます。

GCTの加納さんが公開されている以下ノートブックですが、
2022/11/7現在に実行しようとすると、usiのビルド部分でエラーを吐かれます。
colab.research.google.com


色々調べたところ、Google Colabに初期設定されているcudaのバージョンが問題だったようなので、
以下のコードを一番最初に行うことで以降のビルドでも躓かないようになります。
(※2022/11/7現在では、最新版のmasterでビルドも可能です)

!sudo apt install --no-install-recommends cuda-11-0


上記コードを最初に実行してから、下記コードを実行するとcuda11.0になっていることが確認できると思います。

nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2020 NVIDIA Corporation
Built on Wed_Jul_22_19:09:09_PDT_2020
Cuda compilation tools, release 11.0, V11.0.221
Build cuda_11.0_bu.TC445_37.28845127_0

■補足
山岡さんが公開されている以下ノートブックもこれでビルドできるようになるかと思います。
colab.research.google.com

探索部の実験メモ

Lightweightの探索部は基本的にdlshogiに倣っており、下記式が最大となるノードを選んでいます。

Q(s _ t, a) + U(s _ t, a)


特に、U(s _ t, a)の部分については、以下のように求めています。(これもdlshogi通りです)

\displaystyle{U(s, a) = c _ {puct} P(s, a) \frac{\sqrt{\sum_ b N(s, b)}}{1 + N(s, a)}
}


ここで、\displaystyle{\frac{\sqrt{\sum_ b N(s, b)}}{1 + N(s, a)}}の部分に注目してみると、
{\sqrt{\sum_ b N(s, b)}}は局面sにおいて選択した全ての手の合計回数を示しており、またN(s, a)は局面sにおいて選択した手aの合計回数を示しています。
つまりこの部分は「選択回数の少ない手を優先する」という役割を担っていますが、「どのような場合に選択回数の少ない手をどれだけ優先させるか」という部分については改良の余地があるのではと考えます。


そこで現在、KLDを利用したPUCTアルゴリズムの改良案を試しており、floodgateや手元で自己対局を行って計測等を行っています。
KLDは直接的には「ある2つの確率分布の差異」を表す尺度ですが、これをコンピュータ将棋、特にdlshogi系のソフトに置き換えた場合は「局面の難しさ」を表す尺度になりうると考えています。
簡単な局面(≒探索があまり必要ではなく、Policyのみで最善手を判断できる場面を指す)であれば最善手が早々に定まりますが、
難しい局面となると、探索を進めるにしたがって最善手が変わることがよく起こります。これに従ってKLDも大きくなります。
(※もちろんモデルの精度が良いほど、この「難しい局面」のレベルが上がってくるわけですが....)

ここで1つ仮説を立てますが、
KLDが大きい、つまり探索がより重要な局面である場合は、
「選択回数が少ない手の優先度を引き上げてやることで、Policyが見落としている最善手をより発見しやすくする」
ことができるのではないかと考えました。


そこで2022/7/9に行われたTSEC3では、実験的にLightweightの探索部について、
U(s _ t, a) の部分を以下のように変更していました。

\displaystyle{U(s, a) = c _ {puct} P(s, a) \frac{KLD _ {adjustment} \sqrt{(\sum_ b N(s, b))}}{1 + N(s, a)}}

\displaystyle{KLD _ {adjustment} =  \sqrt{kld(P _ s, Q _ s)+kld _ {base}}}

(ただし、\displaystyle{1 ≤ KLD _ {adjustment} ≤ 3}


上記式の通りですが、\displaystyle{kld(P _ s, Q _ s)}\displaystyle{kld _ {base}}を足してルートを取ったものを\sqrt{(\sum_ b N(s, b))}にかけることで、選択回数が少ない手の優先度をKLDに応じて動的に引き上げることが狙いです。
また、過度にKLDの値に引きずられて探索バランスが崩れないようにするため、\displaystyle{KLD _ {adjustment}}は1から3までの間に収まるように下限、上限を設けて調整しています。\displaystyle{kld _ {base}}はハイパーパラメータです。



このハイパーパラメータを決めるあたっては、以下の条件で連続対局を行い暫定的な値を決めています。
■計測条件
持ち時間:5秒(秒読み)
対局相手:S.Lightweight-EF(WCSC32出場時もの)
対局数 :1800対局(50games×36trials)
開始局面:互角局面集を使用
※差異は上記探索アルゴリズムの変更有無のみ
※その他のパラメータはWCSC32のもので統一

■計測結果

非線形で近似してみると、2.25付近が最大となっているように見えます。(※グラフ上は50〜350で表現されていますが、実際に内部で取り扱う際は他パラメータと同様に100で割っているので、225→2.25となります)
上記の計測結果をもとにして、TSEC3に出場したLIghtweight 2.0は\displaystyle{kld _ {base}}=2.25で設定していました。
※ただし、そもそも1trialsあたりのgamesの回数が少なかったり、
\displaystyle{kld _ {base}}が3.00以上の場合の計測回数が少ない、
また複数ソフトとの対戦を行っていないといった計測自体における不足点はあるので、
あくまで参考値としたほうがよさそうです。

第32回世界コンピュータ将棋選手権に出場してきました

GWの2022年5月3から5日にかけて、「第32回世界コンピュータ選手権」が開催されました。
将棋ソフト関連大会の中では一番歴史が古い大会で、1990年から毎年開催されています。
今回、自分が開発する「S.Lightweight-EF」も本大会に参加してきましたので、忘れないうちにその振り返りを記載します。

■結果
まずは最初に結果から。
1次予選 :33チーム中7位(予選通過)
2次予選 :28チーム中6位(予選通過)
決勝リーグ:6位


■準備したこと
昨年冬に開催された第2回電竜戦では、B級9位(全46チーム中19位)という結果でした。
この結果を受け、電竜戦に出した「Lightweight-EF」の改良を行い、その改良版を「S.Lightweight-EF」としました。
詳細はこちら



※以下、個人的に印象に残った箇所に絞って記載します。
■1次予選
世界コンピュータ将棋選手権については初出場のため、1次予選からの出場でした。

・Argo 戦
初戦のArgo戦では、先手番だったものの勝ちきれずに引き分け。
残り数手で詰みであることは見えていましたが、Argoに粘られたことで320手を迎えてしまいました。
ここで引き分けたことで勝ち点が0.5となり、結果的に1次予選通過の雲行きが怪しくなりました。

・prelude 戦
谷合先生が開発されたソフトとの一戦。
水匠以外には全勝されていたため、相当に強いことは認識していましたがやはり強かったです。同じDL系として勝ちたかった...。
ただ、対局数が限られている中で注目のソフトと戦えたこと自体はとても嬉しかったです。

・十六式いろは煌 戦
7回戦が終わった時点でボーダーギリギリの10位でした。
確実に2次予選に進むためにはこの対局で勝つ必要があったため、特に緊張して見ていた対局でした。
30手目までは互角の局面が続いていたものの、そこから少しずつ有利に転じていきなんとか最終戦を勝つことができました。
この時点で5勝2敗1分となったため予選突破が確定しました。


■2次予選
・やねうら王 戦
s-book_blackをベースにした定跡が刺さり、80手目付近で+600弱程度有利な状況となりました。
やねうら王側の棋力を考えるとそれでも320手まで粘られるor頓死等でひっくり返される可能性がありましたが、なんとか勝ちきるところまで持っていくことができました。
※当日の対局室にて一部の方にはお話しした記憶がありますが、S.Lightweight-EFは形勢有利(体感的には+400以上)になってから詰みまで持っていくところにやや不安があります。

・二番絞り 戦
予想外の4連勝で次に迎えた相手は二番絞りでした。
同じdlshogiベースではありますが、開発コンセプトは対極的で
こちらは軽量志向であるのに対して、二番絞りは「巨大な深層学習モデルで最高精度の局面評価を誇る」とされています。(アピール文から引用)
後手番での対局となりましたが、一度も後手側に評価値は触れることなくじわじわと持っていかれた形で敗局しました。
こちら側では50手目を過ぎたあたりで、すでに評価値が-400程度となっていました。

・水匠 戦
一度は入玉局面までは持っていったものの、130手目を過ぎたあたりから評価値が一気に水匠有利に転じました。
その後、玉を追い立てられあと少しで投了という場面で異常終了してしまい負けとなりました。
あの局面からはどちらにしろ負けていたものの、この異常終了の原因が分からず、残り2局を残していたためかなり焦りました。

・Novice 戦
2次予選最終局。
ともに5勝という成績であったため、勝った方が決勝リーグに進む状況でした。
Noviceチームの定跡が強いということは既に聞こえてきており、また130手目を超えた時点で+400ほど先手良しとなっていました。
ただ、143手目の3六金打を指した局面にて詰みが見つかったことで、なんとか勝利することができ2次予選突破が決まりました。
※S.Lightweight-EF側でも検討すると、10秒探索した時点で最善手として挙がってくるものの直後に詰みを見つけて避けるようです。


■決勝リーグ
・マメット・ブンブク 戦
前日の2次予選にて既に一度後手番にて負けていたtanukiさんが初戦の相手でした。
記憶している限り、これまで一度も勝てたことがない相手でしたが、70手目前くらいで後手有利に傾き始めました。
そのまま相入玉となり優勢だったものの、勝ち切れずに320手を迎えて引き分けとなりました。

・dlshogi with HEROZ 戦
今回優勝されたdlshogi with HEROZとの対局は、S.Lightweght-EF側としては100手を超えるまでほぼ互角の評価値を示していました。
そこから110手目付近で少しずつ後手良し側に振れていき、181手での投了となりました。
※kanouさんの棋譜中継サイトでは水匠が一瞬150手目前後で先手+500くらいを示しましたが、S.Lightweight-EFから見ると110手目からはずっと後手有利と評価しています。


■終わりに
自分がコンピュータ将棋に興味を持ったのは、前回大会の優勝者であるelmo(開発者:瀧澤さん)がきっかけでした。
それまでは「過去に電王戦という大会があった」くらいの認識しかありませんでしたが、
会社での各部署の紹介にて瀧澤さんやelmoが紹介されていたのを見て、「自分でもやってみたい」とコンピュータ将棋に興味を持ちました。
そこから色々な開発者のブログやソースコード、解説本から勉強させていただいたり、時にはSNS等でアドバイスをいただいたりして
今回このような結果を残すことができました。

マッチングなど運に恵まれた部分も大きかったとは思いますが、良い結果が残せたことは嬉しい限りです。
また今大会にて色々な開発者の方々と実際にお話しさせていただいたり、開発についてアドバイス等をいただけたりしたこと、とても感謝しております。

プロ棋士の先生方や、司会進行・聞き手等を務めて下さった皆様、ご多忙のなかご参加いただきありがとうございました。またCSAの皆様におかれましても、リモート参加を含めたハイブリット開催という難しいオペレーションを3日間に渡って行っていただきありがとうございました。

今後ともどうぞよろしくお願いいたします。

S.Lightweight-EFについて

第32回世界コンピュータ将棋選手権が終わりましたが、そちらに出場していた「S.Lightweight-EF」について記載します。
どちらにしろ後からアピール文書としても出し直しますが、主にそちらには書かない部分について言及しようと思います。


■概要
dlshogiをベースとしたライブラリ勢のソフトで、Lightweightシリーズの最新版にあたります。
コンセプトは「ローカルPC環境でもCPU系/GPU系に限らず、高級スリッパやつよつよインスタンス勢と戦うこと」であり、末尾のEFはモデルに採用しているEfficientNetが由来です。



■第2回電竜戦時からの改良点とdlshogi本家との差異
大きく①②③④⑤の特徴がありますが、本家との差異は以下①②です。
①モデルアーキテクチャ
本家ではResNetを使っていますが、S.Lightweight-EFでは「EfficientNet」にて構築し1から学習しています。
また、本モデルは第2回電竜戦に出場した「Lightweight-EF」のモデルの改良版にあたるため、頭に「スーパー」を意味する「S」をつけています。(イギリス重戦車のS.Conqueror的な)
※ただしEfficientNet単体ではなく、入力部に7層のResidual blockを入れていて、そこから更にEfficientNetに接続しています

②探索部
dlshogiでは、PUCTアルゴリズムに従って探索木を降りていく際、現在ノードの各子ノードに対してUCB値の計算を行い、
UCB値が最大の子ノードを選択しています。(二番絞りはこのときLCB値を利用しているとのこと)
ただ、この処理は子ノードの数だけUCB値計算を繰り返すため、有望な手以外はこのUCB値計算を行わないことで探索を効率化・高速化できるのではと考えました。
事前にいろいろな局面でのbestmoveと各子ノードのPolicy値を調査した上で閾値を設定し、
その閾値を下回るPolicyを示した子ノードはUCB値計算自体をスキップさせています。
この手法を一ヶ月前に開催されたさくらリーグに出場させた「S.Lightweight-AP」で試しており、白ビールに続いてB級2位と感触は得られていたものの、
今回の一次予選の結果があまりふるわなかったことから二次予選以降はdlshogi本家の形に戻しました。

③KLDを使った時間制御
選手権前にdlshogiが検証していたKLDによる時間制御を取り込んでいます。
ただし、これも②と同じく一次予選にのみ使用しています。
中盤に入る前に時間を使いすぎてしまうことと、NPSが75%程度に落ち込んでしまうため、
二次予選では取り除きました。

④マルチストリーム対応
こちらを参照

⑤入力特徴量作成の改善
こちらを参照

※上記②③が功を奏したのか、2次予選の調子は良かったです。


■学習
以下、①②③④⑤を利用しました。その大部分をこちらからお借りしています。(①②④はこちらから利用しました)
①floodgateから抽出した棋譜データ
②gctの自己対局データ(selfplay_gct-001.hcpeから)
③dlshogi本の付属データ(dlshogi_with_gct-01.hcpeから)
④水匠による入玉データ(nyugyoku)
⑤S.Lightweight-EFによる自己対局データ
※本日の対局でQhapaqさんとの会話で②③⑤だけのように言っていた気がしますが、①④も利用していたことに後から気づきました。


■その他
RTX3070, 3080をマルチGPUとして使用すると、平均NPSは約120,000程度になります。
ただこれはあくまでbenchmarkスクリプトによる測定の結果であり、実戦では100,000前後を示すことが多いように思います。
以下は、一次予選における谷合先生の「prelude」との対局中のキャプチャです。