A9.jsとA19.jsはコードがほとんど同じだったのですが、碁盤サイズに定数を使っていたため、別のレポジトリとして作りました。
メンテの意味でもそれはあまりに残念なので、コードをマージしてリファクタリングしてドキュメンテーションを充実させたAZ.jsを公開します。
囲碁AI A19.js
以前にA9.jsというブラウザ上で遊べる9路盤囲碁AIを公開しました。
今日は、これの19路盤版、A19.jsを公開しました。
FacebookのELF OpenGoのニューラルネットワークを使っています。
iMac Late 2012(GTX-660M)でニューラルネットワークの評価は380ms前後でした。1秒間に3回評価できるかどうかですが私より強いです^^;
ELF OpenGoのウェイトをLeela Zeroで動かすと1秒間に17回弱評価できるので、もう少し性能出てほしいなぁとも思いますが、何分古いGPUなのでブラウザとしてもWebGL/WebGPUの最適化対象にはなっていない気がします。
WGoエディタ再び
2年弱前にWGoエディタというものを作りました。
新興アプリSabakiが良さげだったので開発をやめました。見立てもよかったようで、今、Sabakiは結構人気のアプリになったようです。
SabakiはLeela/Leela Zeroを使った検討機能も拡張できるのですが(GitHub - SabakiHQ/LeelaSabaki: Leela (Zero) integration with Sabaki.)、自分の欲しいものと違ったので、再びWGoエディタをいじることにしました。
検討したい局面でボタンをクリックすると、Leela/Leela Zeroの読みを盤上でリアルタイムに更新します。(碁処耳赤をご存知の方は、香子さんの変化図表示そのものと思っていただいていいです)
耳赤の生中継でなくても棋譜(SGF)の興味ある局面で香子さんの解説が見られるようなもので、とても楽しく使っています。
良ければご利用ください。
[6月18日追記]
コピーショートカットキー(macOSなら⌘-C)で盤上画面をクリップボードにコピーする機能を追加しました。例えば、局面をツイートしたいときにコピーして、ツイート編集画面でペースト(⌘-V)すると貼り付けられます。自戦記ツイートにとっても便利ですよ〜
[6月19日追記]
サポートファイルをSGFだけでなく、GIB, NGF, UGF, UGIまで増やしました。
(ファイルがすぐ手に入らない都合でGIB以外動作未確認です^^;不具合があればgithub issueでお知らせください)
AlphaGoまとめ
AlphaGo Fan | AlphaGo Lee | AlphaGo Master | AlphaGo Zero (20b) | AlphaGo Zero (40b) | AlphaZero (20b) | ELF OpenGo v1 | ELF OpenGo v2 | PhoenixGo | KataGo | |
---|---|---|---|---|---|---|---|---|---|---|
評価ハードウェア | 1202 CPU & 176 GPU | 48 TPU v1 | 4 TPU v1 | 4 TPU v1 | 4 TPU v1 | 4 TPU v1 | 1 V100 | 1 V100 | Tesla P40 | - |
HW指標 | 1TPUで1600simに0.4秒 | 80k simに50秒 | ||||||||
HW指標(playouts/s) | 16000 | 8000 | 16000 | 1600 | ||||||
レーティング | 3144 | 3739 | 4858 | 4350? | 5185 | ~4800 | 推定4100 | |||
実績 | Fan Huiに5戦5勝 | 李世乭に5戦4勝1敗 | トッププロに60戦60勝。柯洁に3戦3勝。AlphaGo Teachデータ生成 | AlphaGo Masterに100戦89勝11敗 | 韓国トッププロに14戦14勝 | 第1回貝瑞基因杯世界AI囲碁大会優勝 | ||||
アルゴリズム | ポリシーとバリューネットワークとロールアウトのハイブリッドMCTS | 同左 | ポリシーバリューデュアルネットワークとロールアウトのハイブリッドMCTS | ポリシーバリューデュアルネットワークでのMCTS | 同左 | 同左 | 同左 | 同左 | ||
フィーチャー | シチョウを含む48(49)プレーン | 同左 | シチョウを含むnプレーン(推定、n不明) | 8手前までの盤上配置と手番(17プレーン) | 同左 | 同左 | 8手前までの盤上配置と手番(18プレーン) | 8手前までの盤上配置と手番(18プレーン) | 8手前までの盤上配置と手番(17プレーン) | 22プレーン |
ネットワーク | 192フィルタ * 12 CNN * 2 | 256フィルタ * 12 CNN * 2 | 20ブロック ResNet | 256フィルタ * 20ブロック ResNet | 256フィルタ * 40ブロック ResNet | 256フィルタ * 20ブロック ResNet(推定) | 224フィルタ * 20ブロック ResNet | 256フィルタ * 20ブロック ResNet | 20ブロック(batch normとactivationの位置がモダン) | |
学習 | 教師あり学習+強化学習 | 同左 | 同左 | 強化学習 | 同左 | 強化学習 | 強化学習 | 強化学習 | 強化学習 | 強化学習 |
自己対戦ハードウェア | 50 GPU | 2000 TPU v1 | 2000 TPU v1 | 5000 TPU v1 | 2000 V100 | 2000 V100 | WeChat CPU server | 27 V100 | ||
学習ハードウェア | 64 GPU & 19 CPU | 64 GPU & 19 CPU | 64 TPU v2 | |||||||
自己対戦時一手sim数 | 1,600 | 1,600 | 800 | 1,600 | ||||||
自己対戦時着手選択 | 30手まで訪問数分布乱数、それ以後最大訪問数 | 同左 | 同左 | 訪問数分布乱数 | ||||||
ミニバッチサイズ | 2,048局面(対称性ランダム) | 同左 | 4,096局面 | 2,048局面 | ||||||
ウィンドウ | 500,000 | 同左 | 1,000,0000 | 500,000 | ||||||
ミニバッチ処理 | バッチサイズ32で64ワーカーを動かして2,048を処理 | 同左 | ||||||||
学習方式 | 25k局毎1kミニバッチ。テストあり | 同左 | 非同期。約200局毎に1ミニバッチ (30局 for symmetry)。テストなし。約1kミニバッチで更新 | 非同期 | ||||||
総ミニバッチ | 700k | 3.1M | 700k | 1.5M | 639,200 | |||||
総自己対戦数 | (自己対戦から30M局面を抽出) | 4.9M | 29M | 140M (21M for symmetry) | 20M | |||||
自己対戦期間 | 1日+1週間 | 数ヶ月 | 3日 | 40日 | 34時間 | 2週間 | 9日(16日?) | 19日 |
AlphaGo Masterの強さは手作りのフィーチャーにあります。20ブロックのMasterを超えるためにZeroは40ブロック要しました。
一番の要因はシチョウが読めるかどうかと想像しています。20ブロックのZeroでは盤を横断するシチョウが直感できないのではないでしょうか。20ブロックのELF OpenGoがそれを実証しています。
"without Hunman Knowledge"に拘らなければ、シチョウを含めたフィーチャーで強化学習するのが一番ですね。
残る疑問は、シチョウフィーチャーあり40ブロックで強化学習した場合AlphaGo Zero(40b)を超えるのかどうか。
Meteorを使ったリアルタイムアプリのためのデータ構造
Meteor歴5年で今更感があるのですが。
Meteorといえばリアルタイムアプリがターゲットのウェブプラットフォームです。
クライアントとサーバーのDBの同期やリアクティブなレンダリングはとても重宝しています。
さて、MeteorのDBのクライアント-サーバ同期の単位は、コレクションのドキュメントのトップのフィールドです。
(これを確認するには、クライアント側でDDPの通信をモニタしてみるといいです)
例えばチャットアプリを考えてみましょう。
大きく分けて3つのデータ構造が考えられると思います。
- チャット1つずつをそれぞれドキュメントにする
- スレッドをドキュメントにして、チャットID(番号)をトップのフィールドにしてチャットをスレッドのドキュメントに追加していく
- ルームをドキュメントにして、chatsフィールドを配列にしてチャットを追加していく
先に説明した通り、同期の単位はコレクションのドキュメントのトップのフィールドなので、1と2はチャット毎にDDPで同期が取られますが、3はチャットが追加されるたびにchatsフィールドの内容すべてをDDPで送ることになります。
パフォーマンスに大きな影響があるかと思いますので、ご注意ください。
macOS(High Sierra)でTensorFlowをコンパイルする
古いiMac(2012)を使っているのでGPUが馬力がないので、CPUでもIntel MKLを使って高速化をすべく、macOS(High Sierra)でTensorFlowをコンパイルしようとしたら嵌りました。
TensorFlowはコンパイル時にデフォルトのApple clangを使うのですが、このclangはOpenMPをサポートしていないので、omp.hが見つからないというエラーです。
で、コンパイラを変える方針で対処し始めたら相当失敗しました。
結論ですが、HomeBrewでlibompをインストールして、これをtensorflowのthird_partyフォルダーで登録する方法でうまくいきました。以下、必要な手順です。
1. Installing TensorFlow from Sources | TensorFlowでbazel buildを起動する手前まで準備する。
2. HomeBrewでlibompをインストールする
brew install libomp
3. libompをtensorflow/third_partyフォルダに登録する
cd tensorflow/third_pary mkdir libomp cd libomp ln -s /usr/local/opt/libomp/include . ln -s /usr/local/opt/libomp/lib touch BUILD
以下はBUILDの内容です。
licenses(["notice"]) cc_library( name = "libomp", hdrs = glob(["include/*.h"]), visibility = ["//visibility:public"], )
4. tensorflow/tensorflow/core/BUILDを編集する
name="core_cpu_impl"のライブラリで、
copts = tf_copts(),
を
copts = tf_copts() + ["-Ithird_party/libomp/include"],
に変更します。
copts = tf_copts() + ["-Xpreprocessor -fopenmp", "-Ithird_party/libomp/include"],
のほうが筋がいいかもしれませんが、試してません。ヘッダーだけが必要だったようで上記変更でコンパイルはできました。
また、name="core_cpu_impl"のライブラリのdepsに
"//third_party/libomp",
を追加します。
以上で準備完了です。コンパイルしてインストールしましょう。
bazel build --config=mkl //tensorflow/tools/pip_package:build_pip_package && bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg && pip install /tmp/tensorflow_pkg/tensorflow-1.8.0-cp36-cp36m-macosx_10_13_x86_64.whl
動作確認するには、tensorflowフォルダから出てください。(出ないとimport tensorflowが失敗します)
Web WorkerのためのRemote Method Invocation(RMI)
表題のライブラリを作成しました。
山口さんが開発されたPyaq(https://github.com/ymgaq/Pyaq)という9路盤の囲碁AIをJavaScriptの移植(A9.js)したのですが、そのときに、
- UIのレスポンスを維持するためにAIの演算はワーカーで実行したい
- でも、ワーカーではcanvasがまだ使えないのでWebGL/WebGPUを使ったニューラルネットワークアクセラレーションが利用できない
という問題がありました。
なので、メインスレッドとワーカースレッドの小洒落た通信の枠組みが必要になったのでこのライブラリを作りました。
特長は、メインスレッド、ワーカースレッドどちらをクライアントにもできる対称な構成です。
実際、メインスレッドからワーカーに探索をリクエストする部分とワーカーがメインスレッドにニューラルネットワークの評価をリクエストする部分を同じライブラリで実現しています。
(当たり前だと言われたらそれまでですが^^;)
シングルスレッドで設計したクラスの変更がほぼ必要ないところも特長の一つです。
(詳細になりますが、実際には、ニューラルネットワークの評価結果(Float32Array)をTransferListとして渡すとデタッチができないらしく、サーバー側(メインスレッド側)でコピーが必要でした)
必要の際にはご活用ください。
本当はメタプログラミングでクライアント側クラスを自動生成したかったのですが、JavaScriptは未実装メソッドがコールされたときにフックする方法がなさそうなので諦めました。いい方法があれば教えてください。