TadaoYamaokaの日記

山岡忠夫Homeで公開しているプログラムの開発ネタを中心に書いていきます。

メモリの非同期転送対応

Mizarさんからプルリクエストを頂き、CPU<->GPU間のメモリの非同期転送に対応した。
TensorRT: 転送・推論を非同期に行う by mizar · Pull Request #67 · TadaoYamaoka/DeepLearningShogi · GitHub

これは第2回世界将棋AI電竜戦のふかうら王に実装されていた改善である。
ふかうら王 アピール文章:
https://drive.google.com/file/d/1aO0gLSYvhph1uL_gaaohLYWTMpe1BdA8/view

非同期処理

CUDAは、ストリームという機能を使うことで、非同期処理に対応している。
CUDAの非同期関数を呼び出すことで、CPU側はGPU側処理の完了を待たずに次の処理を行うことができる。

推論の処理を実行する際に、

  1. CPUからGPUへのメモリ転送
  2. 推論処理
  3. GPUからCPUへのメモリ転送

の一連の処理を非同期で呼び出すことで、各処理で完了を待つ際に発生する時間のロスがなくなる。
最後に一回だけ同期を行うことで、一連の処理をGPU側で連続して実行できるようになる。

改善効果測定

NPSがどれくらい改善するか測定した。
floodgateからサンプリングした100局面を1秒思考した際のNPSを3回ずつ測定した(GPUはRTX3090 1枚)。

master pr pr/master
count 300 300 1.000
mean 28111 29139 1.037
std 2662 2829 1.063
min 17555 18086 1.030
25% 27465 28424 1.035
50% 29050 30227 1.041
75% 29820 30890 1.036
max 31023 32409 1.045

※masterが改善前、prが改善後

平均で3.7%、中央値で4.1% NPSが改善した。

まとめ

CPU<->GPU間のメモリの非同期転送に対応することで、NPSが約4%改善した

Mizarさんのアピール文章には、ストリームを複数使った並列実行についても提案している。

↓この資料によると、並列実行により、スループットが2倍に向上するらしい。
TensorRTをもっと高性能に使う
NPSの大幅な向上が期待できるかもしれない。
今後、dlshogiも並列実行に対応を行う予定である。

Mizarさんプルリクエストありがとうございました!

第2回世界将棋AI 電竜戦 結果報告その2

後々のためにデータを整理しておきたいので、dlshogiとGCTの各種統計情報を調べた。

探索の統計

NPS、思考時間、探索ノード数、探索深さ、詰み手数の統計は以下の通り。

dlshogi 1日目 予選リーグ
nps time nodes depth mate
count 940 940 940 940 58
mean 269585 8023 2221869 40 13
std 63486 9466 2761912 27 9
min 166072 239 62769 1 1
25% 230216 2830 658847 17 7
50% 263775 4154 1074273 33 13
75% 300014 10327 2918621 61 19
max 692304 73763 21028891 126 33
GCT 1日目 予選リーグ
nps time nodes depth mate
count 737 737 737 737 19
mean 300726 8572 2547911 42 9
std 77926 9919 2969933 24 8
min 185368 254 77696 1 1
25% 264242 2911 756212 22 3
50% 287468 4154 1213490 38 7
75% 309234 10970 3320838 60 13
max 695827 60165 18715763 105 27
dlshogi 2日目 A級リーグ
nps time nodes depth mate
count 1385 1385 1385 1385 84
mean 261134 8970 2391951 44 12
std 63373 10838 2954076 26 9
min 160017 233 46848 1 1
25% 227114 2977 703544 21 5
50% 252963 4539 1226180 43 11
75% 280947 10968 2953314 63 19
max 1087192 90986 26410877 147 35
GCT 2日目 A級リーグ
nps time nodes depth mate
count 1510 1510 1510 1510 65
mean 286066 8370 2391778 41 11
std 57541 9823 2800752 23 9
min 159653 235 67044 1 1
25% 257192 2756 737388 21 3
50% 280781 4382 1301523 41 9
75% 303641 11161 3145888 60 17
max 882842 89015 25364783 105 33
考察

dlshogiは15ブロックのモデルでGPUごとに4スレッド、GCTは10ブロックのモデルでGPUごとに5スレッドで動作している。

A級リーグのdlshogiとGCTのNPSの中央値(50%)※を比較すると、約25万と28万である。
※NPSは、局面によりばらつきが大きいため、中央値で比較するのが良い。
NPSの差は1.1倍程度である。
A100では、15ブロックのモデルと10ブロックのモデルでそれほど差がでないことが分かる。
大会では他の要因もあるためGCTが優勝したが、15ブロックの方が精度が高くできるため、A100では15ブロックが有利なはずである。

探索の深さは、dlshogiとGCTで同じくらいである。
モデルごとの探索パラメータの調整がうまくいっていることを示している。
最大の深さは147で、ディープラーニング系将棋AIは、選択的にかなり深くまで読むことが分かる。

定跡

定跡がヒットした手数、定跡を抜けたときの評価値(定跡に記録されている値)を、手番考慮なし、および手番ごとで集計した。

dlshogi 1日目 予選リーグ
moves cp
both black white both black white
count 10 5 5 10 5 5
mean 13 8 18 63 190 -65
std 7 6 5 159 122 38
min 4 4 11 -101 93 -101
25% 7 4 18 -59 107 -99
50% 15 6 18 43 162 -60
75% 18 10 19 148 194 -57
max 25 18 25 395 395 -7
GCT 1日目 予選リーグ
moves cp
both black white both black white
count 9 4 5 9 4 5
mean 9 11 7 0 0 0
std 5 6 4 0 0 0
min 4 6 4 0 0 0
25% 6 8 4 0 0 0
50% 9 10 7 0 0 0
75% 11 13 11 0 0 0
max 19 19 11 0 0 0
dlshogi 2日目 A級リーグ
moves cp
both black white both black white
count 18 9 9 18 9 9
mean 14 16 13 50 154 -55
std 6 6 7 118 46 51
min 7 7 7 -120 93 -120
25% 9 11 9 -59 122 -80
50% 14 18 10 71 165 -60
75% 18 18 18 159 184 -23
max 26 24 26 214 214 49
GCT 2日目 A級リーグ
moves cp
both black white both black white
count 18 9 9 18 9 9
mean 10 11 9 -31 22 -84
std 5 5 4 86 45 86
min 3 4 3 -251 0 -251
25% 8 8 7 -56 0 -141
50% 10 9 10 0 0 -60
75% 12 12 12 0 0 0
max 21 21 15 127 127 0
考察

A級リーグの定跡がヒットした手数は、dlshogiが平均14、最大26で、GCTが平均10、最大21で、dlshogiの方が長く定跡を持っていたことが分かる。

定跡を抜けたときの評価値は、dlshogiが平均50、GCTが平均-31である。
ただし、GCTの定跡は評価値を0で記録している局面が含まれるため比較はできない。

先手、後手を分けてみると、dlshogiもGCTも先手では一度もマイナスになっていない。
後手は、dlshogiは最小で-120、GCTは-251である。
GCTの定跡には後手番でかなり不利になる手順が含まれていたようである。

まとめ

データを整理しておくと後々比較する際に役に立つので統計情報を整理した。
自分以外には退屈なデータだったかもしれない。

大会のモデルで勝率計測を行っているので、別途記事にする予定。

第2回世界将棋AI 電竜戦 結果報告

11/20(土)、21(日)に開催された第2回世界将棋AI電竜戦に参加しました。

チームdlshogiとして、dlshogi、GCT電竜、python-dlshogi2という3つのソフトでエントリしました。

大会の結果

GCT電竜が優勝、dlshogiが準優勝、python-dlshogi2がC級優勝という結果になりました。
GCT電竜は大会2連覇です。

ディープラーニング系の将棋AIがコンピュータ将棋の大会で優勝したのは、前回の第1回電竜戦が初でしたが、今大会ではA級リーグ(予選リーグの上位10チームの総当たり)のうち5チームがディープラーニング系となり、2017年からディープラーニングを使った将棋AIを開発してきた者としては感慨深いものがあります。

dlshogiは、最終局でGCT電竜と優勝争いとなりましたが、残念ながら負けて準優勝となりました。

python-dlshogi2は、予選リーグは同じ開発者は2つのソフトまでという制限があるため、エンジョイリーグでエントリしました。
そのため、2日目のC級リーグ(予選リーグ29位以下)からの参加でした。
結果は、C級リーグで全勝してC級優勝となりました。

各ソフトの説明とチームの役割分担

dlshogi

dlshogiは、私が2017年から開発しているディープラーニング系の将棋AIで、探索部と学習部、モデルの学習を一人で行っています。

GCT電竜

GCT電竜は加納さんが主開発者で、dlshogiのモデルの学習を行っています。
少ない計算資源で強いモデルを作ることを目標として、Google Colabを活用しています。
dlshogiの自己対局の棋譜を一部共有しています。
探索部と学習部はdlshogiです。

python-dlshogi2

Pythonのみで実装したディープラーニング系将棋AIです。
12/20に発売予定の書籍「強い将棋ソフトの創りかた」のサンプルコードになっています。
書籍の内容は、先日の記事で紹介しています。

エントリの目的が、大会で「強いソフト」であることを示すことだったので、目的が達成できました。

戦型について

今大会では、上位のソフトの戦型は、ほとんどが相掛かりでした。
dlshogiも相掛かりを選択しました。

相掛かりを選択した理由

Youtubuの放送でも話しましたが、相掛かりを選択したのには理由があります。

最近dlshogiのモデルは、定跡なしで平手から指すと、ほとんどの場合、角換わりを選択します。
私は、AIの指し手に人間の手を入れることはしたくないため、はじめは特に手を加えずに、最新のモデルで長時間探索させて大会向けの定跡を作成していました。

定跡の作成方法は、アピール文章にも書いていますが、相手側の指し手はfloodgateの出現頻度に応じた確率で選択し、自分側はMCTSで長時間(今回は1.5億ノード)探索した手を採用するという手法です。
floodgateにない局面では、相手側の確率分布にMCTSで探索した際の訪問回数に応じた分布を使用します。

この手法で掘り続けた定跡では、最善手を指し続けると、角換わりで105手で千日手となりました。
また、floodgateに放流した際も、下位のソフト相手に先手番での千日手になる場合があり、大会で角換わりになると有利な先手番を千日手にされてしまう可能性が高いと考えました。

それと、floodgateの棋譜の戦型別の勝率を調べたところ、角換わりが最も頻度が高いが、勝率は相掛かりが高いことわかりました。

このことから、角換わりになる定跡は使えないと判断しました。
そこで、作成した定跡のはじめの数手で角換わりになる手が最善手の場合、2番目の手と入れ替えて角換わりを回避した上で、定跡を作成し直しました。
その結果、相掛かりを選択するようになっています。

なお、将棋AIは今後も角換わりを指せないというわけではなく、現在の将棋AIの精度では千日手にされやすいというだけです。


GCTも、同様の理由で相掛かりを指していた頃のモデルで作成した定跡に、新しいモデルで定跡を延ばすという方法で、相掛かりを選択しています。

まとめ

今大会は、トップのプロ棋士が検討にdlshogiを導入しているということがニュース記事になったことから、dlshogiに対する期待値が上がっていたので、今までの大会ではなかったプレッシャーを感じていました。
結果は、チームdlshogiで、優勝と準優勝のワンツーフィニッシュとなり、最高の結果となりました。
うれしいというよりほっとしたという気持ちです。

他にも大会で整理しておきたい内容があるので、別途記事を書く予定です。

【書籍の宣伝】強い将棋ソフトの創りかた

12/20に、マイナビ出版から書籍を出します(GCT電竜の加納さんとの共著です)。

前著の「将棋AIで学ぶディープラーニング」の古くなった内容を改めて、加えて、第2回世界将棋AIにも参加しているGCT電竜を超える強い将棋AIを創る方法を解説しています(GCT電竜の強さは第1回世界将棋AI電竜戦基準)。

書籍の内容

ディープラーニング系将棋AIのアルゴリズムの解説と、ディープラーニング系将棋AIの仕組みを実装して理解するためpythonで将棋AIを実装するという内容と、dlshogiライブラリを使用してGCT電竜を超える将棋AIモデルを学習する方法を解説しています。

Pythonで実装する将棋AIは、時間制御やPonderという大会にでるソフトが備えている機能も実装した本格的なものになっています。

GCT電竜を超える将棋AIの創り方は、dlshogiライブラリの使い方の解説をしていて、書籍向けに用意したデータセットを使って、Colab(V100)で1日程度の学習でGCTと同等のモデルが学習できます。
Colabの無料は最近はK80しか引けないので、その場合、さすがに1日では無理なので学習済みモデルも用意しています。
発展内容として、強化学習や定跡作成の方法も紹介しています。

book.mynavi.jp

書籍の紹介

書籍の紹介は、本日の第2回世界将棋AIの予選リーグのYoutubeの放送でも話しました。
youtu.be

python-dlshogi2

書籍のPythonで実装したサンプルコードは、python-dlshogi2として明日の第2回世界将棋AI C級リーグに参加します。
予選リーグは一人2チームまでの制約があるので、python-dlshogi2は、はじめからC級リーグでの参加です。


ということで、書籍の方もよろしくお願いいたします。
www.amazon.co.jp

第2回世界将棋AI 電竜戦 1日目結果報告

本日、第2回世界将棋AI 電竜戦の予選リーグがありました。

予選リーグの結果

全46チーム参加で、上位10チームが明日のA級リーグで総当たりで優勝を争います。
11位~28位はB級リーグ、それ以外はC級リーグになります。

私はdlshogiと、チームとしてGCT電竜として、予選リーグに参加しました。
結果は、dlshogiが4位、GCT電竜が7位となり、明日のA級リーグに進みます。

ディープラーニング系の躍進

他にも、dlshogiライブラリを使用したチームが5チーム(※Ryfamateさんは合議)もA級リーグに進むことになりました。
ふかうら王もdlshogi互換のソフトなので、ディープラーニング系のソフトは6チームです。

5月の世界コンピュータ将棋選手権では、決勝に進んだディープラーニング系のソフトは2チームのみでしたので、ディープラーニング系が従来型の将棋AIに拮抗したことになります。

明日のYoubube中継予定

明日は、従来型の将棋AIとディープラーニング系どちらが勝つのかが一つの見どころになります。

大会の様子は、プロ棋士の解説付きでYoububeで中継されます。

【最終日午前の部】第2回世界将棋AI電竜戦、最終日午前の部【2021.11.21】 - YouTube
【最終日午後の部】第2回世界将棋AI電竜戦、最終日午後の部【2021.11.21】 - YouTube

floodgateの序盤3手の統計

序盤3手の戦型と先手勝率について話題になっているので、floodgateの棋譜から統計を調べてみた。

取得した統計

floodgateの2018年以降のR3500以上同士の棋譜から、序盤の出現頻度と先手勝率を調べた。
出現頻度上位21件をグラフにすると以下の通り。

f:id:TadaoYamaoka:20211106000746p:plain
横軸は、文字列を辞書順に並べている。棒グラフが頻度で、線グラフ(右のy軸)が先手勝率である。

上記のTweetで、7六歩(7g7f)→3四歩(3c3d)からは2六歩(2g2f)しか選択肢がないが、これを見ると2六歩(2g2f)以外は勝率が大きく下がることが分かる(将棋に詳しい方にはあたり前のことかもしれないが)。

頻度と勝率

頻度と勝率が必ずしも一致していないのが興味深い。

2六歩(2g2f)→8四歩(8c8d)からは、勝率は2五歩(2f2e)が高いが、頻度は7六歩(7g7f)の方が高い。
floodgateでは、勝率は低くなるにも関わらず、相掛かりより角換わりの方がよく指されているようである。
将棋ソフトの序盤には、角換わりになりやすいバイアスがかかっているのであろうか。

年ごとの傾向

年ごとに傾向に違いがあるか調べた。
(横軸がそろっていないのは、上位21件を抽出しているため)

2018年

f:id:TadaoYamaoka:20211106004225p:plain

2019年

f:id:TadaoYamaoka:20211106004237p:plain

2020年

f:id:TadaoYamaoka:20211106004249p:plain

2021年

f:id:TadaoYamaoka:20211106004301p:plain

2018年は、2六歩(2g2f)→8四歩(8c8d)→7六歩(7g7f)が高かったが、
2019年に、2六歩(2g2f)→8四歩(8c8d)→2五歩(2f2e)が増えて、
2020年に、2六歩(2g2f)→8四歩(8c8d)→2五歩(2f2e)の方が多くなっている。
2021年には再び、2六歩(2g2f)→8四歩(8c8d)→7六歩(7g7f)の方が多くなっている。

勝率は、2020年のみ2六歩(2g2f)→8四歩(8c8d)→7六歩(7g7f)が少し高くなっているが、
それ以外は、2六歩(2g2f)→8四歩(8c8d)→2五歩(2f2e)が高い。
2021年は、同じくらいになっている。

レーティングごとの傾向

上位のレーティング(R4200以上)のみに絞って調べた。
f:id:TadaoYamaoka:20211106005310p:plain

上位ソフト同士では、序盤3手は13パターンに絞られていた。
頻度は、2六歩(2g2f)→8四歩(8c8d)→7六歩(7g7f)が多く、勝利は2六歩(2g2f)→8四歩(8c8d)→2五歩(2f2e)の方が高いという傾向は、変わっていなかった。

将棋ソフトの序盤は、角換わりを選択しやすくなる何らかの原因があるようである。

まとめ

floodgateの棋譜から、序盤3手の統計を調べてみた。
2020年は、相掛かりが流行っていたが、2021年には再び角換わりが流行っているようである。
また、興味深いことに頻度と勝率は一致していないことがわかった。
これは将棋ソフトの序盤にはまだ課題があることを示唆しているのかもしれない。

Windows11+WSL2+Dockerでdlshogiを動かす 続き

昨日、Windows11でCUDA on WSLを試したが、なぜかWindows上でdlshogiのNPSが低下する問題が発生した。

WindowsのCUDAのバージョンが古かったため、新しいバージョンで試してみた。

CUDAインストール

TensorRTの最新版(8.2.0.6)に対応した、CUDAの最新版(11.4)をインストールする。

昨日インストールしたドライバをそのままにして、CUDA 11.4をインストールしようとしたが、インストールでエラーが発生した。

そこで、CUDA on WSLに対応したドライバをアンインストールしてから、インストールしたところ、インストールできた。
ドライバは、CUDA11.4に付属するものをインストールした。

Windows上でのNPS測定

この状態で、dlshogiをCUDA、cuDNN、TensorRTの最新版とリンクするようにしてビルドし、NPSを測定した。
結果は以下の通り、昨日測定したWSLのDocker上で測定したNPSとほぼ同じになった。

info nps 40857 time 5022 nodes 205188 hashfull 20 score cp 72 depth 25 pv 2g2f 8c8d 2f2e 8d8e 7g7f 4a3b 8h7g 3c3d 7i8h 2b7g+ 8h7g 3a2b 6i7h 2b3c 3i3h 7a6b 3g3f 6c6d 5i6h 6b6c 9g9f 9c9d 1g1f 1c1d B*3a

Docker上での測定

この状態で、WSLのDockerでCUDAが使用できるか確認したが、問題なく使用できた。
CUDA on WSL対応のドライバのインストールは不要だったようである。

Docker上でも再度NPS測定してみた。

info nps 40301 time 5032 nodes 202796 hashfull 20 score cp 195 depth 29 pv 2g2f 3c3d 7g7f 8c8d 2f2e 8d8e 6i7h 8e8f 8g8f 8b8f 2e2d 2c2d 2h2d 4a3b 2d3d 2b3c 5i5h 5a5b 3g3f 8f7f 8h7g 7f7d 3d7d 7c7d P*2h P*8b 7i6h 3a4b P*7b

Windows上とほぼ同じNPSがでている。

まとめ

CUDA on WSLに対応したドライバを使用すると、Windows上での古いバージョンのCUDAの性能が低下する問題が発生した。
CUDA on WSLに対応したドライバしてアンインストールして、CUDA11.4に付属のドライバをインストールすることで、Windows上で性能が低下しなくなった。
また、WSLのDocker上でも問題なくCUDAが使用でき、性能が低下しないことがわかった。