読み書きプログラミング

日常のプログラミングで気づいたことを綴っています

Leela ZeroのウェイトをCore MLで計算させる

AZ.jsをSwiftに移植しました。

その際に、Leela ZeroのウェイトをCore ML上に移す作業があったのですが、ハマり所があったので、備忘録です。

Leela Zeroのウェイトは、leela-zeroレポジトリのtraining/tfフォルダ以下のスクリプトを使って、TensorFlowに読み込むことができます。なので、後はtfcoremlで.mlmodelに変換すれば完了です。
github.com

以下、ポイントは2点ありました。

  • tfcoremlはテンソルのフォーマットにNHWCしかサポートしていません。レポジトリのtfprocess.pyは(GPU用に)NCHWフォーマットなので、NHWCフォーマットに対応させました。
  • Core MLは、現在、モデルの実装が限定されているようです。無次元+チャンネルの場合バッチあり、2次元+チャンネルの場合バッチなしの2つです。1次元+チャンネルの場合2次元+チャンネルの1次元を要素数1にして代用するようです。なので本当の意味での1次元+チャンネルはサポートされていません。Leela Zeroは1次元+チャンネルを内部でreshapeする構造なのでこのままではCore MLに合わせることはできませんでした。なのでLeela Zeroのモデルを、内部のreshapeを取り払って2次元+チャンネルの入力に変更しました。

ELF OpenGo v1のウェイト(20b, 224c)を変換してみたところ、私のiMac(27インチ ,Late 2012, i5)で推論が1回170--220ms程度でした。同じマシンのChrome(webgl)でWebDNN上のものが360ms前後なので倍ぐらいのスピードですか。Core ML(tfcoreml?)は量子化をしているようで出力の数字が荒っぽくなります。

GeForce RTX 2080 Tiは2枚でAlphaGo Readyと言えるかも

追記 2018/09/06
cuDNNは次元がそれぞれ8の倍数でないとTensor Coreを活用できないようです。
devblogs.nvidia.com
これだと、囲碁AIには使えないですね…

GeForceシリーズの新しいGPUが発表されました。Gamescomに先立って行われた講演では、リアルタイムレイトレーシングが強調されてTensor Coreに関しては搭載されているのかどうかはっきりしないものでしたが、2日経って詳細内容の記事が出てきました。
pc.watch.impress.co.jp

この記事によると、GeForce RTX-20シリーズにはすべてTensor Coreが搭載されていて、その仕様は、

2070 2080 2080 Ti
Tensor Core FP16 60 TFLOPS 81 TFLOPS 108 TFLOPS

とのことです。

TuringアーキテクチャTensor CoreはINT8, INT4もサポートするので、以下の仕様が想像できます。

2070 2080 2080 Ti
Tensor Core FP16 60 TFLOPS 81 TFLOPS 108 TFLOPS
Tensor Core INT8 120 TOPS 162 TOPS 216 TOPS
Tensor Core INT4 240 TOPS 324 TOPS 432 TOPS

AlphaGo Zeroの対局時の仕様はTPU v1 4個なので、INT8が92 TOPS * 4 = 368 TOPSという仕様です。

なので、RTX 2080 Tiを2枚で432 TOPSでAlphaGo Zeroの仕様を(単に数字の上だけですが)超えることになります。
RTX 2070を3枚なら 360 TOPSでAlphaGo Zeroにほぼ並びます。

499ドル 3枚(約17万円)、999ドル 2枚(約22万円)は決して安い値段ではありませんが、半年前にはTITAN V 2枚(80万円)でも届かない性能が今この値段!

なんという世の中でしょう。競争激しいGPU業界のたゆまぬイノベーション努力に感謝致します。

(でも財布の都合で買うならRTX 2070一枚かな…)

GPUEaterでLeela Zeroを動かす

https://pbs.twimg.com/media/DjGFRRyUUAAn2eM?format=png

GPUEaterというGPUサーバーレンタルサービスがあります。

www.gpueater.com

RX Vega 56などハイエンドのPCやワークステーションに搭載されるGPUマシンをお手頃な値段で時間貸ししてくれます。RX Vega 56の場合、1時間$0.4794(≒53円)。

ここではAMDGPUマシンを借りて、Leela Zero、Lizzieをインストールし、VNCで接続して遊ぶ手順を公開します。

手順

GPUEaterでアカウントを作る。

省略^^:

インスタンスを生成する。

省略^^:
ここでの手順はAMD GPU用なので、インスタンスはa1.rx580, a1.vega56, a1.vegafeのいずれかを選んでください。
ImageはデフォルトのAMD-ROCm 1.8 192+TensorFlow1.8 Ubuntu 16.04 x64ではなく、Ubuntu 16.04 x64を選択してください。ROCmのOpenCLではLeela Zeroが正常動作しませんでした。(a1.vega56インスタンスで確認。)

追記(2018/08/07)
今日、Leela Zero nextブランチ488de43コミットで確認したところ、AMD-ROCm 1.8 192+TensorFlow1.8 Ubuntu 16.04 x64イメージで動きました。なのでこのイメージを使えば以下の「OpenCLのインストール」は必要ありません。
488de43コミットはhalf float auto detectionもサポートしています。ROCm OpenCLドライバはVegaのhalf floatがサポートされているので、amdproドライバと比較してLeela Zeroのパフォーマンスが1.5倍(netbench比較)になりました。
追記(2018/08/08)
動くのは特定ウェイト(62b5417b64c46976795d10a6741801f15f857e5029681a42d02c9852097df4b9)のようで、best-networkでは動かないことを確認しました。イメージは変わっていないので、ROCmドライバにバグがあって、地雷を踏むウェイトとそうじゃないウェイトがあるようです。

SSHで接続してインストール作業をする。

SSH接続手順は省略^^;

OpenCLのインストール

以下のスクリプトを走らせてください。

# OpenCLのインストール

apt update

# AMDのサイトから直接ダウンロードできなかったのでDropboxに落としたものをダウンロード
wget https://www.dropbox.com/s/r1totpsb5e5z1lb/amdgpu-pro-18.20-606296.tar.xz
apt install xz-utils
tar -Jxvf amdgpu-pro-18.20-606296.tar.xz
cd amdgpu-pro-18.20-606296
dpkg --add-architecture i386
./amdgpu-install --opencl=pal
#実行途中でインストールの意思を聞かれるのでYを入力
reboot

最後にrebootするのでSSHが一旦切れます。再度SSHで接続してください。

OpenCLがインストールされたか確認したい場合、以下を実行してください。

apt install -y clinfo && clinfo
Leela Zeroのインストール

以下のスクリプトを実行してください。ウェイトはELF OpenGo移植ウェイトを選びました。

git clone -b next http://github.com/gcp/leela-zero.git
cd leela-zero/src
apt install -y g++ libboost-dev libboost-program-options-dev libopenblas-dev opencl-headers ocl-icd-libopencl1 ocl-icd-opencl-dev zlib1g-dev
make
cd ..
wget http://zero.sjeng.org/networks/62b5417b64c46976795d10a6741801f15f857e5029681a42d02c9852097df4b9.gz

Leela Zeroが動くか確認したい場合、以下を実行してください。

src/leelaz -g --weights 62b5417b64c46976795d10a6741801f15f857e5029681a42d02c9852097df4b9.gz

a1.vega56dでのnetbenchの結果は以下の通りでした。

 1600 evaluations in  4.59 seconds -> 348 n/s
VNC関連のインストール

以下のスクリプトを実行してください。

apt install -y --no-install-recommends ubuntu-desktop gnome-panel gnome-settings-daemon metacity nautilus gnome-terminal
apt install -y vnc4server

(軽量なデスクトップにしてインストール時間を短くしたかったのですが、それだと以下に出てくるxstartupがうまく設定できなかったのでUbuntu 1604のデフォルトデスクトップUnityを使いました。Unityは開発中止になっているので、せめてGnomeのほうがよかったかもしれません。軽量なデスクトップでいいものがあれば設定方法含めて教えてください。)

VNCの初期設定のために以下を実行してください。(これはサーバー起動コマンドです。)

vncserver :1

一旦サーバーは停止させます。

vncserver -kill :1

.vnc/xstartupというファイルが生成されますので、中身を以下に変えてください。

#!/bin/sh

# Uncomment the following two lines for normal desktop:
# unset SESSION_MANAGER
# exec /etc/X11/xinit/xinitrc

#[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
#[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
#xsetroot -solid grey
#vncconfig -iconic &
#x-terminal-emulator -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
#x-window-manager &

export XKL_XMODMAP_DISABLE=1
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS

[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
xsetroot -solid grey
vncconfig -iconic &
gnome-session &
gnome-panel &
gnome-settings-daemon &
metacity &
nautilus &
gnome-terminal &

xstartupの中身を変えたら、再度VNCサーバーを起動します。

vncserver :1
Lizzieのインストール

以下のスクリプトを実行してください。

apt install -y default-jre
wget https://github.com/featurecat/lizzie/releases/download/0.5/Lizzie.0.5.Mac-Linux.zip
unzip Lizzie.0.5.Mac-Linux.zip
cd lizzie
# config.txtの設定
mv ~/leela-zero/src/leelaz .
mv ~/leela-zero/62b5417b64c46976795d10a6741801f15f857e5029681a42d02c9852097df4b9.gz network.gz

以上でインストール作業終了です。

遊び方

VNCクライアントソフトでVNCサーバ接続します。(手順省略^^;)

接続すると、ターミナルが開いているのでそこで、以下のコマンドを実行してください。

cd lizzie
java -jar Lizzie.jar

これでLizzieが起動します。(初回はLeela Zeroの起動に少し時間がかかります) Enjoy!

囲碁AI AZ.js

A9.jsとA19.jsはコードがほとんど同じだったのですが、碁盤サイズに定数を使っていたため、別のレポジトリとして作りました。
メンテの意味でもそれはあまりに残念なので、コードをマージしてリファクタリングしてドキュメンテーションを充実させたAZ.jsを公開します。

github.com

囲碁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エディタというものを作りました。

nextliteracy.hatenablog.com

新興アプリSabakiが良さげだったので開発をやめました。見立てもよかったようで、今、Sabakiは結構人気のアプリになったようです。
SabakiはLeela/Leela Zeroを使った検討機能も拡張できるのですが(GitHub - SabakiHQ/LeelaSabaki: Leela (Zero) integration with Sabaki.)、自分の欲しいものと違ったので、再びWGoエディタをいじることにしました。

github.com

検討したい局面でボタンをクリックすると、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 PhoenixGo
評価ハードウェア 1202 CPU & 176 GPU 48 TPU v1 4 TPU v1 4 TPU v1 4 TPU v1 4 TPU v1 1 V100 Tesla P40
HW指標 1TPUで1600simに0.4秒と思われる 80k simに50秒(1600simに1秒)
レーティング 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手前までの盤上配置と手番(17プレーン)
ネットワーク 192フィルタ * 12 CNN * 2 256フィルタ * 12 CNN * 2 20ブロック ResNet 256フィルタ * 20ブロック ResNet 256フィルタ * 40ブロック ResNet 256フィルタ * 20ブロック ResNet(推定) 224フィルタ * 20ブロック ResNet 20ブロック(batch normとactivationの位置がモダン)
学習 教師あり学習+強化学習 同左 同左 強化学習 同左 強化学習 強化学習 強化学習
自己対戦ハードウェア 50 GPU 2000 TPU v1 2000 TPU v1 5000 TPU v1 2000 V100 WeChat CPU server
学習ハードウェア 64 GPU & 19 CPU 64 GPU & 19 CPU 64 TPU v2
自己対戦時一手sim数 1,600 1,600 800
ミニバッチサイズ 2,048 同左 4,096
ミニバッチ内容 直近500k局からランダム局面 同左 4,096
ミニバッチ処理 バッチサイズ32で64ワーカーを動かして2,048を処理 同左
1ステップ当たり自己対戦数 25 25 30
NN選択のためのステップ数 1k 1k 選択なし
総ミニバッチ 700k 3.1M 700k 639,200
総自己対戦数 (自己対戦から30M局面を抽出) 4.9M 29M 21M
自己対戦期間 1日+1週間 数ヶ月 3日 40日 34時間 2週間

AlphaGo Masterの強さは手作りのフィーチャーにあります。20ブロックのMasterを超えるためにZeroは40ブロック要しました。
一番の要因はシチョウが読めるかどうかと想像しています。20ブロックのZeroでは盤を横断するシチョウが直感できないのではないでしょうか。20ブロックのELF OpenGoがそれを実証しています。
"without Hunman Knowledge"に拘らなければ、シチョウを含めたフィーチャーで強化学習するのが一番ですね。
残る疑問は、シチョウフィーチャーあり40ブロックで強化学習した場合AlphaGo Zero(40b)を超えるのかどうか。