TadaoYamaokaの開発日記

個人開発しているスマホアプリや将棋AIの開発ネタを中心に書いていきます。

将棋AIの進捗 の検索結果:

将棋AIの進捗 その60(固定プレイアウトで水匠5と互角になる条件)

dlshogiの棋力測定する際に、dlshogiの過去のバージョンとの対局だとレーティング差が実際よりも大きくなる傾向がある。 そこで、棋力測定では水匠5を加えてリーグ戦で連続対局している。普段の棋力測定では、対局条件をフィッシャールールの持ち時間で対局を行っており、dlshogiの30ブロック(A100 1枚)と水匠5(32スレッド)を互角にするには、水匠5の持ち時間を10倍にするとだいたい互角になる。 参考:将棋AI実験ノート:30ブロックの学習 - TadaoYamao…

将棋AIの進捗 その59(第3回電竜戦で見つかった課題と対策検討)

第3回電竜戦では、水匠が準備した先手番角換わりの長手数の定跡が、dlshogiの盲点を突いていて定跡を抜けた時点で大差になっていた。具体的には、以下の局面の85手目の8三角打が先手優勢であることをdlshogiが見つけらず、盲点となっていた。 8三角打から進んだ87手目まで進めると、9七玉で先手有利を見つけることができる。 85手目は、水匠5では8三角打が最善手で先手優勢であること見つけており、dlshogiと水匠5で評価が割れる局面となっている。 モデル精度の課題 モデル精…

将棋AIの進捗 その58(訓練の省メモリ化と高速化)

現状のdlshogiのモデルの訓練の実装では、訓練データが多い場合にメモリを大量に消費する課題があった。dlshogiのモデルの訓練は、訓練データをすべてメモリに読み込んで処理を行っている。 そのため、一度に学習できるデータはメモリに読み込める分に制限される。 それ以上のデータを学習する場合は、訓練データを分割して学習する必要がある。また、1台のマシンでGPUを複数使用して同時に実験を行いたい場合、それぞれメモリを消費するため、メモリが不足する。 対策 メモリ消費を抑えるため…

将棋AIの進捗 その57(SWAの修正)

dlshogiの学習では、SWA(Stochastic Weight Averaging)を導入している。今までは、1世代学習するごとに、平均化した重みを出力して、次の世代ではその重みを使用して学習していた。 しかし、SWAは通常複数エポックに渡って平均化してから、最後に平均化した重みを出力を行う。 また、Leela Chess Zeroでは、複数世代にわたって重みを平均化しているようなので、dlshogiもそのように変更した。 実装方法の変更 dlshogiにSWAを実装し…

将棋AIの進捗 その56(データローダーの並列化)

dlshogiのモデルの訓練に使用しているPythonスクリプトは、ベタなforループで記述しており、ミニバッチ作成部分と、ニューラルネットワークの学習の処理をシーケンシャルに実行しており並列化は行っていなかった。ミニバッチデータの作成は、盤面から入力特徴量を作成する処理が比較的重いため、C++で実装して高速化している。 それでも、ある程度CPU時間を消費している。一方ニューラルネットワークの学習処理は、GPUで処理しているため、CPUは遊んでいる状態になる。 その間に、次の…

将棋AIの進捗 その55(勾配クリッピング)

dlshogiを初期値から学習を開始すると、lossがinfやnanになる場合がある。 初期値からの学習以外でも勾配爆発を防ぐために、勾配クリッピングのオプションを追加した。KataGoでも勾配クリッピングを追加している。学習が安定してからは特に効果はないようだ。勾配クリッピングにより同じデータを学習した場合に結果が変わるか確認した。 勾配クリッピング PyTorchのclip_grad_norm_を使用する。 これは、勾配のノルムが閾値以下になるようにクリッピングを行う。 …

将棋AIの進捗 その54(補助ターゲット)

深層強化学習では、メインの学習タスクに加えて、補助タスクを同時学習することで、パフォーマンスを改善するということが行われている。 [1611.05397] Reinforcement Learning with Unsupervised Auxiliary Tasks 囲碁AIの例 囲碁AIのKataGoでは、 占領した領域 スコア が補助ターゲットとして使用されている。 チェスAIの例 チェスAIのLeela Chess Zeroでは、 残り何手で終局か(Move Left…

将棋AIの進捗 その53(MultiPVの実装)

Qhapaqさんからのプルリクエストをもらっておきながら対応していなかったMultiPVに遅ればせながら対応しました。 MultiPVを使わない際の速度には一切影響しない形で実装したかったので、リファクタリングしてから取り込もうと思いつつ、探索部の改良を行っていたので遅くなってしまいました(・ωGitHubのソースからビルドが必要な状態なので、メモリ使用量を減らす改良なども行ったうえでバイナリもリリースするつもりです。

将棋AIの進捗 その52(探索部の改良)

ここ数週間、探索部の細かい改良をしては測定していた。 小さなレーティング差を計測するには多くの対局数が必要になるので、一つの改良の確認に時間がかかるのがつらいところである。 1手1秒と1手3秒で結果が異なることもあるため、長時間思考で強くしたいため1手3秒での測定を基本にしている。 測定は、変更前後の自己対局と、水匠2 2スレッド1000万ノードとの対局(dlshogiは1GPU3スレッド)で確認している。 水匠2との対局は、対局数が少ないと誤差が大きくでるので、500対局以…

将棋AIの進捗 その51(floatの桁落ち)

dlshogiの現在の実装では、長時間思考して探索ノード数が大きくなった場合に、ノードにバックアップされる価値の合計がfloat型になっているため、誤差が許容できないという指摘をやねうらお氏から頂いた。floatに[0,1]の価値の値を足し合わせていく場合に、桁落ちは当然気を付けるべきだが、ディープラーニングを使用している場合、探索ノード数それほど多くならないので、指摘されるまで意識していなかった。 しかし、現状ではGPUを8枚使用するような状況になったので、長時間思考で問題…

将棋AIの進捗 その50(メモリ使用量削減)

dlshogiは、1ノードにつき平均2KBのメモリを消費する(局面の平均合法手を80とした場合)。 通常GPU 1枚で探索した場合、NVIDIA RTX 3090で最大4.5万NPS程度なので、5分探索したとすると、探索ノード数は1350万ノードで、約27GBのメモリを消費する。複数枚GPUを使用して、定跡を作成する場合には、さらに多くのノードを探索することになる。 5000万ノードを探索すると、100GBのメモリが必要になる。 なお、使用メモリ量が搭載物理メモリ以上になると…

将棋AIの進捗 その49(並列化の課題)

dlshogiでは、複数GPUを使用して並列化した場合に、ノードの衝突が発生しやすくなりNPSが1/3近くになる場合がある。例として、電竜戦でA100×8使用した時、以下の局面でNPSが初期局面に対して1/3近くなっていた。 局面 NPS 初期局面 342985 position startpos moves 7g7f 8c8d 2g2f 8d8e 8h7g 3c3d 7i8h 2b7g+ 8h7g 3a4b 2f2e 4b3c 6i7h 4a3b 3i3h 7a6b 3g3…

将棋AIの進捗 その48(NPS改善)

ノード再利用の方式見直しを行った後、強くなっているかApery(WCSC28)と1手3秒100局で確認を行った。結果、勝利は62%で、変更前は69%だったので、強くなっていないことがわかった。 考察 理由としては、以下が考えられる。 Ponderなしの秒読みではノード再利用が少なく時間がかかっていないこと、秒読みでも探索打ち切りを行っているので、探索ノード数変わらないことから、そもそもノード再利用の遅延の影響がない 合流を処理しなくなった分、合流するノードの探索数が減っている…

将棋AIの進捗 その48(PV表示対応)

Qhapaqさんからプルリクをいただいたので、dlshogiをPV表示に対応しました。プルリクにはなかったのですが、USIオプション「PV_Interval」を追加しました。 「0」にするとPV表示なし、0以上にすると、設定したms間隔でPVを表示します。masterブランチに反映しましたが、バイナリは配布しないので使用したい方は各自でビルドをお願います。Qhapaqさん、ありがとうございました! あと、対局プログラム実行用のDockerfileも共有していただきました。 D…

将棋AIの進捗 その47(Linuxのマルチスレッド排他処理)

昨日の記事で、dlshogiのゲーム木の管理をロックレス方式に見直しを行った。Windowsでは、ノード単位の排他制御をmutexを用いずに、atomic_flag (TAS機能)で実現することで10%NPSが向上したが、Linuxで測定すると800NPSくらいしかでないという悲惨な結果になった。 原因 Linuxのスレッドは、Windowsのスレッドとは異なり、プロセスの一種にすぎない。 そのため、コンテキストスイッチのコストが高い。atomic_flagでビジー待機を行っ…

将棋AIの進捗 その46(ノード再利用の見直し)

世界コンピュータ将棋オンライン大会でノード再利用の処理に問題があることがわかったので、見直した。先日の記事で、Leela Chess Zeroのゲーム木の管理方法を調査して、合流を処理しないでC++のヒープ管理を利用してツリー状にノードを管理していることが分かった。 利用しなくなったノードは、最上流のノードをガベージコレクタに追加することで、別スレッドで芋づる式にヒープから削除される。 この方式によって、ノード再利用の待ちをほぼ0にできる。 Leela Chess Zero方…

将棋AIの進捗 その45(大会直前の性能改善)

いよいよ本日から世界コンピュータ将棋オンライン大会が始まりました。概要 http://www2.computer-shogi.org/wcso1.html 参加チーム https://www.apply.computer-shogi.org/wcsoc/team.html 棋譜中継 http://live4.computer-shogi.org/wcso1/ 特設サイト http://sizer.main.jp/wcsoc2020/ dlshogiは直前にきて、致命的な処理遅…

将棋AIの進捗 その44(大会直前の調整)

世界コンピュータ将棋オンライン大会はいよいよ明日から開催です。今日は、直前に簡単に変更できる部分をいくつか調整を行っていました。 探索延長の条件変更 今までは、ルートの訪問数が1番目の手と2番目の手の差が1.2倍未満の場合に、1.5倍探索を延長していましたが、floodgateで時間を余す傾向があったので、1.5倍未満もしくは勝率が逆になっている場合に、2倍探索を延長するようにしました。 本番のルールはfloodgateと異なるため、どうなるか多少不安があります。 大会中に修…

将棋AIの進捗 その43(探索パラメータ調整)

未訪問ノードのQの初期値の変更と、FPU reductionを導入してから、探索パラメータの再調整を行っていなかったので、Optunaで最適化を行った。FPU reductionはKataGoを参考に、ルートノードは0としていたが、パラメータにして調整するようにした。 また、Leela Chess Zeroでは、ルートノードとゲーム木内のノードで、パラメータを分けているので、同様に別のパラメータとした。 Optunaの分散実行 Optunaは、分散実行に対応しているので、複数…

将棋AIの進捗 その42(TensorRT対応)

TensorRTがdlshogiのDNNの推論においても効果があることがわかったので、TensorRTをdlshogiに組み込んだ。 Tensorコアを搭載したGPUでは、以前のcuDNN版に比べて推論が大幅に高速化される。 実装 ONNXから読み込んだネットワークのビルドには数十秒近く時間がかかるため、ONNXファイルと同じディレクトリに、ビルド済みのネットワークをシリアライズしキャッシュすることにした。 GPUごとバッチサイズごとに最適化が行われるため、拡張子に、「..s…

将棋AIの進捗 その41(1サイクルあたりの生成局面数)

dlshogiの今の10ブロックの192フィルタのモデルは、2018年6月から学習を開始して、何度かモデルの精度が飽和して強くならなくなったが、そのたびに新しい手動を導入して現在まで継続して強くできている。201サイクル目からはリーグ戦を導入して、218サイクル目からはQの初期値を変更したことで、精度が大幅に向上した。レート3500以上のfloodgateの棋譜との一致率と、USIエンジン(elmo(WCSC28))との勝率は以下のようになっている。 floodgateの棋譜…

将棋AIの進捗 その40(マルチGPUの性能)

以前のdlshogiは、マルチGPUで動かした場合、4GPUまでは線形にNPSが伸びるがそれ以上GPUを増やしてもNPSが伸びなかった。 ハッシュテーブルのロックにボトルネックがありそうだ思っていたので、今回ロックの範囲を修正してマルチGPUでの性能を改善した。 ロックの範囲 dlshogiは、ハッシュテーブルをハッシュキーの番地から空きエントリをインデックスをインクリメントしながら線形に探索する方法で実装している。 空きエントリを探す処理は複数スレッドで排他制御する必要があ…

将棋AIの進捗 その39(リーグ戦)

年末にCPUを3970Xに変えてから、USIエンジンをリーグに加えた強化学習を行っている。 USIエンジンを各探索スレッドにつき2つ、GPUにつき探索スレッドを3つ、3GPUで探索を行っているので、合計18プロセス起動している。 メモリの制約が厳しくこれ以上は起動できなかった。リーグの構成は、1/8はUSIエンジンと対局して、残りは自己対局を行っている。 1手500msだと局面生成速度は、リーグなしと比べて7割くらいになる。 USIエンジンには、elmo(WCSC28)を使用…

将棋AIの進捗 その38(SWA)

dlshogiの学習にSWA(Stochastic Weight Averaging)を実装して、測定した。 SWA SWA(Stochastic Weight Averaging)は、一定間隔での重みを平均化することで、ニューラルネットワークのテスト精度を改善するテクニックである。 一般的なアンサンブルの手法では予測の結果を平均化するが、SWAでは重みを平均化することで実現する。 SWAの実装 SWAの実装は、PyTorchの実装を参考にした。 この実装では、学習開始時点か…

将棋AIの進捗 その37(FPU reduction)

昨日、MCTSで未訪問のノードの価値を、動的に親ノードの価値で初期化する方法を試した。 その結果、技巧2(4コア)に対する勝率が、60%から69%(R+68.6)になった。 昨日の結果の考察 今までは0.5(引き分け)で初期化していたため、劣勢の局面で未探索のノードがすべて1回は探索されることになるので、終盤の合法手の多い局面では探索が広すぎる条件になっていた。 十分な数の探索が行われれば問題ないが、探索の深いノードでは十分な数の探索が行われないので、すべてのノードが探索対象…

将棋AIの進捗 その36(UCBの価値の初期値)

AlphaZeroのMCTSのUCBには、 という式が使用されており、このUCBで行動価値の信頼区間の上限を見積もっている。は、行動の行動価値を、探索を行った結果得られた価値の平均で推定する。 ここで、のときは未定義であるため、何らかの値で推定する必要がある。 AlphaZeroでは0で初期化、つまり、未探索のノードの価値を0(負け)としている。 dlshogiでは、これを0.5(引き分け)で初期化している。 以前に、これをAlphaZeroに合わせて0で初期化してみたところ…

将棋AIの進捗 その35(PyTorchに移行)

年末に新しいCPUが届いたので、正月はPCを組んでいた。 同時にフルタワーケースを買ったのだが、GPU3枚だと熱対策をしないと安定動作しなかったので、ドリルで加工してファンを増設したりと正月から働いてしまったorz 安定動作するようになったので、前回記事にしたUSIエンジンをリーグに加えた強化学習を走らせている。 10サイクルほど学習したら結果を記事にする予定である。 SWA(Stochastic Weight Averaging) Leela Chess Zeroの最新動向…

将棋AIの進捗 その34(終盤力の強化)

前回の日記からしばらくぶりですが、その間SENetの学習を続けていました。 自己対局中の詰み探索の深さ ディープラーニング+MCTS系は終盤に弱点があるので、dlshogiでは自己対局中にルート局面でdf-pnによる詰み探索を行い、詰みが見つかった場合は、ゲームを打ち切り勝ち負けを正確な報酬として与えて学習している。 詰みの手順を学習しなくなるが、終盤の局面の価値評価が正確になる。 対局時は、ルート局面で並列で詰み探索を行っているので、詰みの手順は覚えなくても良いと割り切って…

将棋AIの進捗 その33(末端ノードでの詰み探索)

dlshogiでは末端ノードで短手数(7手)の詰み探索を実施しているが、終盤ではゲーム木中に詰みの局面が多くなり、王手の合法手も多くなるため、探索速度が大幅に低下することがあった。 先日、MCTSにAND/OR木を組み込む実装を行ったことで、MCTSで詰み探索を行うことができるようになったので、詰みの手数を短くしても良いのではないかと思って、5手に減らして強さを確認してみた。以下のような終盤の局面で、7手の場合と5手の場合で速度を比較すると、 position sfen 7n…

将棋AIの進捗 その32(MCTSの探索にAND/OR木を導入する)

Leela Chess Zeroの状況を定期的にウォッチしないとなと思って、issueを眺めていたら"Exact-Win Strategy for Overcoming AlphaZero" #799という投稿がされていた。 Leela Zeroのissue#2276にも同様の投稿がある。 ざっくり説明すると、子ノードが勝ちの場合、そのノードを再度探索しないという探索のアイディアである。元の論文「Exact-Win Strategy for Overcoming AlphaZ…