Consuming My Life

趣味、お仕事、雑感何でも載せていきます。

Facebook実装の囲碁AIをGCP上で実行してみた

FacebookがAlphaGoZero論文の実装をオープンソースで公開

Facebook Open Sources ELF OpenGo – Facebook Research

ちょうど一年前に囲碁世界チャンピオン柯潔を破ったGoogle囲碁AI、AlphaGoZeroの実装をFacebookオープンソースで公開しました。

github.com

AlphaGoZeroのアルゴリズムについてはすでに論文がありますが、1から実装するのは骨だと思います。上記リポジトリでは訓練済みモデルも含め、最低限動く形で公開されているので環境さえ整えられれば自前でbot稼働できますね。また、今はPullRequest来てないようですが開発自体にも参加できると思います。GTP*1の実装もWIPのようで、対応していない命令が多かったです。

今回、GCEでGPU付きVMインスタンスのセットアップを一度やってみたいモチベーションがあったので、READMEに記載されてるスペックでセットアップしてみました。

この記事ではセットアップに際し、詰まったところをメインに解説していきます。コマンド等細かなセットアップ手順は記載せず、代わりに公式サイトのリンクを提示しています。Facebook/ELFも公開されたばかりですし、CUDAなど今後もversion upの激しいライブラリです、今時点の詳細な手順を記載してもすぐに陳腐化するでしょう。

GCPリソースの割り当て

GCPでは、リスクマネジメント・コストマネジメントの観点から利用可能なリソースを制限しています。

https://cloud.google.com/compute/quotas?hl=ja

https://cloud.google.com/compute/docs/gpus/add-gpus?hl=ja

GPUの利用も制限されているので、上記リンクを参考に割り当てリクエストをする必要があります。GCPの中の人の対応に24時間~48時間程度必要ですとのことなので、早めにリクエストしておいたほうがいいですね。今回はTesla K80を利用することにしました。Facebook/ELFは現状Multi-GPU利用は対応していないようなので1つで十分です。

ちなみに最初AWS上でセットアップしようと考えてました。その際、p2xlargeのインスタンスの制限解除リクエストをしたんですが、未だにほったらかしにされてます・・・。AWSだとDeepLearning用ツールコミコミAMIがあるのでGCEより楽かもしれません。

インスタンスDisk100%でssh不可能になるの巻

Facebook/ELFはPythonのanaconda環境を開発環境としています。anacondaのインストールシェルは結構重く、数GBのファイルになります。最初インスタンスのディスクサイズを10GBにしていたためひどいことになりました。CUDAのパッケージもインストールしていたら、10GBすべて使い切ってしまい、慌ててディスクサイズを増設するためにインスタンス停止させたらssh不可能な状態になってしまいました。鍵交換のためのディスク容量がなくsshできないようです。GCEはシリアルポート接続も用意されており、ssh不可能な状態になってもそちらからインスタンスにアクセスできますが、私はLoginIDとPasswordが分からず、ログインができませんでした。

結局インスタンス作成し直したほうが早そうだったので、ディスクサイズ50GBに指定して1から作り直しました。インスタンス停止する前にファイル削除していればよかった。。。

NVIDIA NVML Driver/library version mismatchエラーに捕まるの巻

Facebook/ELFの実行には、CUDA、cuDNN、NCCLが必要です。それぞれ公式の手順に従ってインストールしましょう。

Installation Guide Linux :: CUDA Toolkit Documentation

cuDNN Installation Guide :: Deep Learning SDK Documentation

https://docs.nvidia.com/deeplearning/sdk/nccl-install-guide/index.html

CUDAのInstllation guideにも記載されていますが、最初にドライバのインストールが必要です。GCPは現在(2018/05/05時点)、以下のドライバーしか対応していないようなので、R384ブランチのドライバーをインストールしたほうが無難でしょう。 f:id:neetless777:20180505215324p:plain

私の場合、最初様々なQiita記事やブログ記事に書かれた個人のInstallationGuide参考にしてしまって、ドライバのバージョン間違えていれなおしたりなんやかんやとしているうちにDriver/library version mismatchのエラーが出るようになってしまいました。

結局これもインスタンス作り直しで対応しました。やはりクラウドVMインスタンスは破棄・作成が手軽で楽ですね。

細かいところを見ていくと、CUDA toolkitはディストリビューションのパッケージマネージャでインストールする方法とRunfileで対話形式に進めていくものがあるようですが、前者の方で進めていきました。また、driverは有志の方がリポジトリにまとめており、nvidia公式ページからダウンロードせずともレポジトリを登録すればドライバをインストールできるようになります。

Proprietary GPU Drivers : “Graphics Drivers” team

私の場合、最終的にはすべて公式の手順通り、公式からダウンロードしたパッケージを使ってインストール進めました。

NVIDIAドライバダウンロード

インストールするべきドライバのバージョンはここから確認できます。利用するGPU、OS、CUDAのバージョンを指定して対象のドライバをダウンロードします。今回はGCPの都合上R384のドライバをインストールしないといけなかったので、CUDAは9.0を利用することになります。

ここでダウンロードしたパッケージをGCEインスタンス上にもってきて、インストールするわけですが、公式から持ってきたものをインストールするときはちょっと注意で、パッケージ名がnvidia-XXXではなく、cuda-driversになります。(どこにも記載されてない気がする・・・)

# nvidia-384ではインストールできない
$ sudo apt install cuda-drivers

botの実行までこぎつけたの巻

Facebook/ELFには対象のOSがUbuntu18.04ですが、16.04で環境構築しました。18.04に指定されている理由は、ビルドツール、GCCとCMAKEがVersion高めなものを使っているからでしょう。GCC7系とCMAKE11系を16.04でインストールすれば、ELF自体のビルドも可能でした。

訓練済みモデルでbotを動かしてみるとこんな感じになります。 f:id:neetless777:20180506004440p:plain

GTPで制御可能で、自分が一手打つときは、

# play命令。引数1はb or w(黒番or白番)、引数2は盤上の座標を渡す。
play b q16

botに一手打たせるときは、

# genmove命令は引数1つだけ。b or w(黒番or白番)を渡す。
genmove w

です。GTPの命令*2は他にもいろいろあるんですが、実装されていないものもあります。ハンデ戦やundoもまだ実装されていないですね。

# 実装されているのはこれだけ
list_commands

= boardsize
clear_board
exit
final_score
genmove
komi
list_commands
name
play
protocol_version
quit
showboard
version

facebook/ELFの性能・かかった金額

公開されてるpretrainedモデルを使って実際に動かしてみましたが、READMEに記載されている実行時パラメータだとあまり強くありませんでした*3

./gtp.sh path/to/modelfile.bin --verbose --gpu 0 --num_block 20 --dim 224 --mcts_puct 1.50 --batchsize 16 --mcts_rollout_per_batch 16 --mcts_threads 2 --mcts_rollout_per_thread 8192 --resign_thres 0.05 --mcts_virtual_loss 1

ELF OpenGo used the v0 pretrained model (publicly available for download). For each move, ELF OpenGo used 2 threads with 40000 rollouts per thread (grouped into batches of 16). This took around 50 seconds per move on a V100 GPU.

pretrainedモデル自体はLeelaZeroに勝ったもののようです。READMEの実行コマンドだと、rolloutsの設定が小さくなってますね。それでトッププロ以上に強くなるかは見てないですが、Tesla K80だとrollouts数8192で1手90秒ほど、40000に設定すると1手400秒ほどかかりました。V100だと50秒で済むとのことですが、思考時間結構長いですね。

GCEインスタンスは26時間の使用で約1000円でした。botとして常時利用すると1ヶ月3万円かかるのは流石にきついですね。。。思考時間の長さも鑑みてあんまりbotとして運用するような気にはなれませんでした。

終わりに

今回初めてGCEでGPUマシンをセットアップしましたが、うん十万円するGPUを手軽に使い始められるのはめっちゃ便利ですね。GPU利用環境の構築はなかなか骨が折れました。個人ブログの情報も参考にはなりますが情報の鮮度、細かさの観点では最終的には公式のガイドに従うべきですね。トライアンドエラーでいろいろ試しながらnvidiaツール周りを理解してきましたが、インスタンスの削除、作成でクリーン環境からのやり直しも手軽でクラウドサービス最高ですね(小並感)

*1:Go Text Protocol。囲碁botとのコミュニケーションのためのProtocol。

*2:https://www.lysator.liu.se/~gunnar/gtp/gtp2-spec-draft2/gtp2-spec.html#SECTION00070000000000000000

*3:マチュア4段くらい?