2018年07月26日

コンピュータ囲碁プログラム「ELF OpenGo」のインストールと使いかた - Ubuntu編

五月初頭のこと、Facebookがあらたなコンピュータ囲碁プログラム「EFF OpenGo」を開発、テストを終えてオープンソース化したということで、おもしろいニュースがはいってきました。

「ELF OpenGo」GitHubレポジトリ:学習ずみネットワークや棋譜なども公開。
・Linuxバイナリ配布なし、ソースからコンパイル。
・64bit対応。
・GPUバージョンおよびCPUバージョン。

関連記事
Facebookが囲碁AI「ELF OpenGo」をオープンソース化
BSDライセンスで公開された「ELF OpenGo」
オリジナルの「ELF」GitHubレポジトリ

世界ランキング30位にはいる韓国棋士四人と十四局打って全勝した、という話ですから、これはGoogle DeepMindの「AlphaGo」や日本最強の「DeepZenGo」のほうの領域にいるあらたなコンピュータ囲碁プログラムの登場ということになります。
hatakazuの棋力なら「Leela」との対局でじゅうぶんすぎるほど勉強になっているわけで、囲碁の勉強という観点だけからみれば、はっきりいって無用の長物であることはまちがいありません。
それでもまあ、これを動かしてみたいなと思って、なんとか動作条件をみたした(非力とはいえNVIDIA製GPU「GeForce MX150」を搭載した)ラップトップを購入してしまいました。

1. 前提となる環境
インストールするコンピュータの仕様は以下のとおり。

--
Dell Inspiron 14 7472 Core i7モデル 18Q42P
OS:Ubuntu 18.04 LTS 日本語 Remix
CPU:インテル Core i7-8550U (4Mキャッシュ、最大4.0GHz)
GPU:NVIDIA GeForce MX150 GDDR5 2GB
メモリー:8GB DDR4 2400MHz(最大16GB)
保存装置:128GB SSD (Windows10) + 1TB 5400rpm HDD (Ubuntu18.04)
--

「ELF OpenGo」の動作要件は、「ELF OpenGo」GitHubレポジトリの記述によれば、以下のようになっています。

・Ubuntu 18.04
・Python 3.6
・GCC 7.3
・CUDA 9.0
・CUDNN 7.0
・NCCL 2.1.2

64bit OSのみの対応、そしてGPUバージョンを動かすためには、「CUDA 9.0」+「cuDNN 7.0」+「NCCL 2.1」環境が必要です。
この条件を満たしていればGPUバージョンの「ELF OpenGo」を、GPUをもたない環境ではCPUバージョンの「ELF OpenGo」を、使うことになります。
「ELF OpenGo」はFacebook開発の機械学習フレームワーク「PyTorch」に依存しており、GPU版「PyTorch」がインストールされていればGPUバージョン「ELF OpenGo」が、CPU版「PyTorch」がインストールされていればCPUバージョン「ELF OpenGo」が使えるようになります。

・「Anaconda」インストール
「PyTorch」をインストールするにあたって、パッケージ管理ツールとして、「Anaconda」を利用することが推奨されています。
ここでは、「Python 3.6」用の最新バージョンである「Anaconda3 5.2.0」が、あらかじめインストールされているものとします。

・GPUサポート
ここでは、「CUDA 9.0」+「cuDNN 7.0」が「/usr/local/cuda-9.0」ディレクトリへ、「NCCL 2.1」が「/usr/local/nccl-2.1」ディレクトリへインストールされ、そこへのパスがとおっているものとします。

・「PyTorch Nightly Build」インストール
現時点での最新バージョンである「PyTorch 0.4.0」バイナリをインストールしても、「ELF OpenGo」を動かすために必要な機能はカバーされてないらしく、「PyTorch」をソースからインストールするか、あるいは「PyTorch Nightly Build」バイナリをインストールするかしないといけません。
ここでは、「Python 3.6」仮想環境「pytorch」を作成のうえ、その仮想環境に「PyTorch Nightly Build」をインストールすることにします。
GPUバージョン「ELF OpenGo」を動かせる環境をととのえるためには、以下のコマンドを実行します。

$ conda create --name pytorch python=3.6
$ conda activate pytorch
(pytorch) $ conda install --channel pytorch pytorch-nightly cuda90


CPUバージョンの場合は、「cuda90」パッケージをインストールする必要はないので、最後の行だけ以下のように変更します。

(pytorch) $ conda install --channel pytorch pytorch-nightly


仮想環境「pytorch」を有効化した状態で、「Python 3.6」シェルをひらいていくつかコマンドをたたき、GPU版「PyTorch」が正しくインストールされていることを確認します。

(pytorch) $ python


「Python 3.6」シェルで、たとえば以下のようなコマンドをたたいてみて適切な出力をえられれば、GPU版「PyTorch Nightly Build」のインストールは正常に完了しています。

(input)>>> import torch
(input)>>> print(torch.__version__)
(output)2018.05.07
(input)>>> torch.cuda.is_available()
(output)True
(input)>>> torch.cuda.device_count()
(output)1
(input)>>> torch.cuda.current_device()
(output)0
(input)>>> torch.cuda.device(0)
(output)torch.cuda.device object at 0x7f6816184828
(input)>>> torch.cuda.get_device_name(0)
(output)'GeForce MX150'


*****CPU版「PyTorch」をソースからインストール*****
現時点では、「PyTorch」のソースを取得して、「CUDA 9.0」と連携させてビルドすることはできていません。
しかし、CPU版であれば問題なく、現行の「PyTorch」ソースからインストールすることができます。
CPU版を使う場合、「PyTorch Nightly Build」を使うよりもソースからインストールしたほうが、「ELF OpenGo」がはるかに早く動作するようです。
以下に、「~/pytorch」ディレクトリに「PyTorch」ソースをダウンロードし、CPU版「PyTorch」をインストールする手順を記述します。

$ conda activate pytorch
(pytorch) $ export CMAKE_PREFIX_PATH="/home/username/anaconda3/"
(pytorch) $ conda install numpy pyyaml mkl mkl-include setuptools cmake cffi typing
(pytorch) $ conda install -c mingfeima mkldnn
(pytorch) $ cd
(pytorch) $ git clone --recursive https://github.com/pytorch/pytorch
(pytorch) $ cd pytorch
(pytorch) $ NO_CUDA=1 python setup.py install


インストール処理が終わったら、「Python 3.6」シェルをひらいて、「PyTorch」のバージョンを確認しておきます。

(pytorch) $ python
(input) >>> import torch
(input) >>> print(torch.__version__)
(output) 0.5.0a0+4b61760
(input) >>> torch.cuda.is_available()
(output) False


ソースからインストールした「PyTorch」をアンインストールするには、以下のコマンドが機能します。

(pytorch) $ pip uninstall torch


2. 「ELF OpenGo」インストールの準備とソースの取得
「ELF OpenGo」は五月初頭にオープンソース化され、GitHubレポジトリでソースが公開されています。
「ELF OpenGo」のCPUバージョンをビルドするなら、CPU版「PyTorch」がソースからインストールされていること、GPUバージョンをビルドするなら、GPU対応として「CUDA 9.0」+「cuDNN 7.0」+「NCCL 2.1」環境が構築されたうえで、「PyTorch Nightly Build」がインストールされていていることを確認します。
今回はホームディレクトリに「ELF」ディレクトリを作成し、そこに「ELF OpenGo」のソースをダウンロードして、「ELF OpenGo」インストール作業をすすめることにします。
まずは、「PyTorch」をインストールした「Python 3.6」仮想環境「pytorch」を有効化し、必要なライブラリをインストールしていきます。

$ sudo apt-get install cmake g++ gcc libboost-all-dev libzmq3-dev
$ conda activate pytorch
(pytorch) $ conda install numpy zeromq pyzmq


つづいて、ホームディレクトリ直下の「~/ELF」ディレクトリに、ソースをダウンロードします。
いまのところ、最新のソースでは「ELF OpenGo」を走らせることはできないようなので、きちんと動作した六月ころのバージョンを利用します。

(pytorch) $ cd
(pytorch) $ git clone https://github.com/pytorch/ELF
(pytorch) $ cd ELF
(pytorch) $ git checkout 4257b3962c839f912501708cc3abb99f3a198a80
(pytorch) $ git submodule sync && git submodule update --init --recursive


3. 「ELF OpenGo」のインストール
つづいてビルド作業にすすみ、ビルド処理が終わったらテストしておきます。

(pytorch) $ make
(pytorch) $ make test


問題ないことを確認したら、「ELF OpenGo」を動かしてみます。
あらかじめパスをとおすためのスクリプトを実行したうえで、「gtp.sh」スクリプトがある「~ELF/scripts/elfgames/go」ディレクトリへ移動し、そこに学習ずみネットワークをダウンロードします。

(pytorch) $ source scripts/devmode_set_pythonpath.sh
(pytorch) $ cd scripts/elfgames/go
(pytorch) $ wget https://github.com/pytorch/ELF/releases/download/pretrained-go-19x19-v0/pretrained-go-19x19-v0.bin


ここまでの準備が終わったら、以下のコマンドをたたいて、「ELF OpenGo」を走らせてみます。

・CPUバージョン
(pytorch) $ ./gtp.sh ./pretrained-go-19x19-v0.bin --verbose --num_block 20 --dim 224 --mcts_puct 1.50 --batchsize 16 --mcts_rollout_per_batch 16 --mcts_threads 2 --mcts_rollout_per_thread 256 --resign_thres 0.05 --mcts_virtual_loss 1


・GPUバージョン
(pytorch) $ ./gtp.sh ./pretrained-go-19x19-v0.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 1024 --resign_thres 0.05 --mcts_virtual_loss 1


GPUの検出などがおこなわれていろいろメッセージが出ますが、問題なく起動していれば、GTPコマンドを受けつける状態になっているはずです。
「genmove black」「genmove white」などのGTPコマンドを与えてみて、正しく着手を返してくるようなら、インストールは正常に完了しています。
自分が担当する手番のほうもGTPコマンドを使って、「play black q4」「play white d16」などのように着手入力していけば、ターミナル上で「ELF OpenGo」と対局することもできます。

4. 「ELF OpenGo」の設定
推奨されている実行コマンドは、以下のとおりです。

./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


いまのところ、考慮時間をパラメータで直接制御することはできないので、「--mcts_rollout_per_thread」の値を変更することで考慮時間をコントロールします。
hatakazuの環境では、ソースからインストールした「PyTorch 0.5.0a0」でCPUバージョンを走らせる場合は「--mcts_rollout_per_thread 256」で、バイナリインストールした「PyTorch Nightly Build」でGPUバージョンを走らせる場合は「--mcts_rollout_per_thread 1024」で、一手あたりだいたい20〜30秒で打ってくれるようです。
CPUバージョンは、ソースからインストールした「PyTorch 0.5.0a0」で動かすほうが、「PyTorch Nightly Build」バイナリで動かすよりも、二倍以上速いスピードで(半分以下の時間で)着手するように見えます。
おなじ比率で単純計算すれば、ソースからインストールした「PyTorch 0.5.0a0」でGPUバージョンを動かせれば、推奨されている「--mcts_rollout_per_thread 8192」で60秒前後で打ってくれるようになる、と期待できるのではないかと思っています。

5. GTP対応囲碁GUI「GoGui」への思考エンジン登録
「ELF OpenGo」をGTP対応囲碁GUIに連携させて、グラフィカルに利用できるようにしたいと思い、いろいろためしてみましたが、現在のところ「Sabaki」で動かすことはできていません。
そのため、ここでは「ELF OpenGo」を「GoGui」から利用できるよう、設定する方法について記述していきます。
まずは、「ELF OpenGo」をビルドするに先だって「PyTorch」をインストールした「Python 3.6」仮想環境「pytorch」を有効化し、パスをとおすスクリプトを実行したうえで、そのおなじ仮想環境から囲碁GUI「GoGui」を起動します。

$ conda activate pytorch
(pytorch) $ source ~/ELF/scripts/devmode_set_pythonpath.sh
(pytorch) $ gogui &


メニューバーの「プログラム」から「新規プログラム」を選び、あらわれた画面の「コマンド:」欄に囲碁思考エンジンの絶対パスと、起動時にわたすパラメータを一行でつづけて入力します。
たとえば「ELF」ディレクトリを「~/ELF」に設置した場合、「コマンド:」欄に入力する絶対パスは「/home/username/ELF/scripts/elfgames/go/gtp.sh」のようになります。
それにつづけて、考慮時間などの観点から採用するパラメータ、たとえば「/home/username/ELF/scripts/elfgames/go/pretrained-go-19x19-v0.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 1024 --resign_thres 0.05 --mcts_virtual_loss 1」を入力します。
最終的に、入力するコマンドは以下の例のようになり、これを一行でつづけて「コマンド:」欄に入力します。

/home/username/ELF/scripts/elfgames/go/gtp.sh /home/username/ELF/scripts/elfgames/go/pretrained-go-19x19-v0.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 1024 --resign_thres 0.05 --mcts_virtual_loss 1

※CPUバージョン「ELF OpenGo」の場合は、「--gpu 0」を削除し、考慮時間短縮のために「--mcts_rollout_per_thread」の値を非常にちいさく設定します。


「OK」ボタンを押下して何度か「待機」をクリックしながら待っていると、「[名前のないプログラム]が不正な応答を送りました」というエラーが出ますが、「警告を再表示しない」にチェックをいれて「閉じる」をクリックしてしまいます。
すると、ステイタスバーに表示されていた「プログラムの開始中」メッセージが消えて新規プログラム登録画面が開くので、「ラベル:」欄にたとえば「ELF OpenGo」などと入力して「OK」ボタンを押下します。
これで登録完了となるので、次回以降はメニューバーの「プログラム」 -> 「プログラムの起動」とすすんで「ELF OpenGo」を選ぶと、「ELF OpenGo」が起動して対局や棋譜分析に利用できるようになります。
登録した囲碁思考エンジン「ELF OpenGo」と対局するには、「ELF OpenGo」を起動した状態で、メニューバーの「対局」から「碁盤サイズ」「置石」「コンピュータの手番」を指定したうえで、「新規対局」をクリックします。
検討したい局面を指定して、そこで「ELF OpenGo」がどう打つかをみることもできます。
「ELF OpenGo」を起動したあと、メニューバーから「コンピュータの手番」を「なし」にして、どんどん石を置いていって対象となる局面をつくり、黒番の局面なら「ELF OpenGoに黒を打たせる」、白番の局面なら「ELF OpenGoに白を打たせる」アイコンをクリックします。
そのさい「GTPシェル」を開いておけば、読み筋や評価値も表示されるので、着手の意味を考えるときに参考になります。

以下の内容を記述したスクリプトを作成してそれを「~/ELF/scripts/elfgames/go/ELF-OpenGo.sh」として保存、実行権限を付与したうえで「GoGui」の新規プログラム画面で「/home/username/ELF/scripts/elfgames/go/ELF-OpenGo.sh」コマンドを指定してやれば、この「ELF-OpenGo.sh」スクリプトを編集することで「ELF OpenGo」の起動パラメータを調整できるようになります。
この場合でも、「PyTorch」がインストールされている仮想環境から「GoGui」を起動する、という点には注意が必要です。

#!/bin/bash
cd /home/username/ELF/
source scripts/devmode_set_pythonpath.sh
cd /home/username/ELF/scripts/elfgames/go/
./gtp.sh ./pretrained-go-19x19-v0.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 1024 --resign_thres 0.05 --mcts_virtual_loss 1

※CPUバージョン「ELF OpenGo」の場合は、「--gpu 0」を削除し、考慮時間短縮のために「--mcts_rollout_per_thread」の値を非常にちいさく設定します。



参考ウェブページ一覧表(順不同)

https://github.com/pytorch/ELF
https://github.com/pytorch/pytorch
https://pytorch.org/
https://github.com/pytorch/ELF/issues/27
https://github.com/pytorch/ELF/issues/30
https://github.com/pytorch/ELF/issues/33
posted by hatakazu at 22:53| Comment(0) | 囲碁ソフトのこと | 更新情報をチェックする
この記事へのコメント
コメントを書く
コチラをクリックしてください