電王トーナメント直前ですが、AWSを使って機械学習で使う教師局面を生成してみようと思い、昨日実際にやってみたので、そのノウハウを書いておきます。ノウハウというか、たぶんLinuxに慣れているような人なら誰でも知っているはずのことで、誰得記事ではあるのですが、私は大いに躓いたので記録として残しておきます。
Linuxのspot instanceが使えるようにしろ
AWSを借りる上で大きな違いになるのがOSの種別です。WindowsとLinuxとではお値段が3倍ぐらい異なります。オンデマンドインスタンスとスポットインスタンスとでもお値段が3倍ぐらい異なります。つまり、将棋ソフト向けの機械学習で使うなら普通はLinuxのスポットインスタンス一択です。(Deep Learningは使わないものとします。)
自分の書いた将棋ソフトのソースコードがLinuxでコンパイルが通るようにしろ
そこでLinuxでソースコードがコンパイル出来るようにしないといけません。やねうら王は昨年、gcc/clangでコンパイルが通るようにしました。clangでコンパイルしたほうがgccより実行が少し速いコードが生成されるようですが、数%のことなので誤差かも知れません。clangでコンパイルを通すにはOpenMPを使っているとわりかし難しいようです。(やねうら王では、MSYS2上のclangではOpenMPを使ったビルドは成功していません。MSYS2上のOpenMPまわりの問題のようですが…)
とりあえずそんなこともあって、Windows派の人は、手元のPCにMSYS2をインストールして、gccでコンパイルが通るようにするところまで進めてから、AWSのLinux環境で作業を始めるとよろしいかと思います。
sshが使えるようにしろ
私はAWSではOSとしてUbuntu 16.04を選ぶことにしました。わりと情報がたくさんあるからというのと、AMIが事前に用意させているということからです。そうは言っても、このUbuntuにどうやって接続していいのか、生成されたファイルをどうやって手元のPCに転送していいのかなど、わからないことだらけです。
とりあえず、sshで接続するためにsshクライアントが必要です。WindowsだとsshクライアントとしてPuTTYが有名所のようですが、割愛。macOSからなら、ターミナルを起動して、sshコマンドを使うだけです。やったね(`・ω・´)b
ストレージにS3を借りる
生成された教師局面を配置するのに、巨大なストレージが必要なのでAWSのS3というサービスを使うことにしました。S3の導入手順についてはググれば記事がたくさん出てくるので「Ubuntu S3」などでググってみてください。
ファイルのアップロードとダウンロード
scpというコマンドで出来るようです。ですがファイル一つ一つをscpで転送するのは面倒なのでS3を手元のPCに仮想ドライブとしてマウントできるようなソフトを探します。Windowsだと、これが無償のものは見つからなくて困りました。
そこでCyberduckというFTPクライアントを使いました。このソフトは、FTPクライアントなんですが、S3への接続も対応しているので、FTPクライアントを使う感覚でS3にファイルをダウンロード/アップロード出来ます。
これでファイルの転送準備が完了しました。
gccをインストールしてコンパイルする
Ubuntu 16.04にgccをインストールするまでのコマンドを書いておきます。
sudo apt-get update
sudo apt-get install gcc
sudo apt-get install build-essential
S3をドライブとしてマウントする
Ubuntu 16.04でS3をドライブとしてマウントするところまでのコマンドを書いておきます。(ググれば出てきます)
以下の手順では、s3fsというツールを使ってマウントしています。s3fsを落としてきてinstallするまで。
sudo apt-get install automake autotools-dev g++ git libcurl4-gnutls-dev libfuse-dev libssl-dev libxml2-dev make pkg-config
git clone https://github.com/s3fs-fuse/s3fs-fuse.git
cd s3fs-fuse
./autogen.sh
./configure
make
sudo make install
echo 【S3のシークレットキー】 | sudo tee -a /etc/passwd-s3fs
sudo chmod 640 /etc/passwd-s3fs
sudo mkdir /mnt/s3
sudo s3fs gensfen /mnt/s3 -o rw,allow_other,uid=1000,gid=1000,default_acl=private
これで、/mnt/s3/ が、S3のドライブになりました。CyberduckでS3に転送するとこのフォルダにファイルがやってくるはずです。
このフォルダにコンパイルされたやねうら王と評価関数ファイルを配置して、教師局面もこのフォルダに生成することにしました。
棋譜生成のテストを行なう
試しに、depth 3で教師を生成してみました。無事生成できて、Cyberduckでファイルを回収できるところまで確認しました。
./YaneuraOu-by-gcc threads 2 , hash 1024 , bookfile no_book , gensfen depth 3 loop 1000000 eval_limit 32000 random_move_minply 0 random_move_maxply 20 random_move_count 20 write_minply 1 write_maxply 256 output_file_name gensfen1.bin , quit
sshのpipeがbroken
ずっと接続しているとタイムアウトしてsshのpipeがbrokenになるようです。(「Write failed: Broken pipe」というエラーメッセージとともに切断される。) sshのタイムアウト時間を伸ばすと良いそうなのですが、そもそもsshのコネクションが切断された途端生成が停止してしまうのも考えものですし、バックグラウンド実行を行なうことにしました。
バックグラウンド実行の方法
これにはscreenコマンドを使うのがお手軽のようです。さきほど実行したコマンドの先頭に「screen」と書いて実行します。
screen ./YaneuraOu-by-gcc threads 2 , hash 1024 , bookfile no_book , gensfen depth 3 loop 1000000 eval_limit 32000 random_move_minply 0 random_move_maxply 20 random_move_count 20 write_minply 1 write_maxply 256 output_file_name gensfen1.bin , quit
そうして、実行が開始されたら、Ctrl+A,Ctrl+Dを押します。そうするとbashの画面に戻り、この状態でならログアウトしても実行されたままになります。やねうら王の局面の生成画面に戻るには、「screen -r」とすればいいようです。
spot instanceのシャットダウン対策
spot instanceなのでときどき価格が高くなって自分の入札額を上回ると自動的にシャットダウンしてしまいます。まあ、それは仕方ないとしても、そのときに生成していた教師ファイルが保存されないままになってしまいます。(S3だと、ファイルのcloseをするまで保存されないようです。)
そこで、生成しているファイルを30分ごとぐらいに保存して、別のファイル名でまたファイルをwrite openするようにしました。やねうら王のgensfenコマンドのsave_everyというオプションがそれです。
これで、シャットダウンしても30分程度のロスで済みます。
spot instanceの自動再開対策
シャットダウンして再開したときに自動的に教師生成を行なうようにしておくことが望ましいのですが、そこまで手が回りませんでした。(そもそも入札額を少し高めにしておけば、シャットダウン自体が稀にしか起きないので..) 誰かコメント欄で補足してもらえると助かります。
どのインスタンスを借りるべきですか?
いまのところ、m4がGPUを使わない計算資源としてはコスパが一番良いようですが、相場は刻一刻と変わるので使う前に調べましょう。
どれくらいの費用がかかりますか?
m4.16xlarge(仮想64CPU)、1時間が$0.4〜0.5。性能的には私のPC(Xeon 2698のDualで80HT)とほぼ互角のようです。S3を借りる分とネットワークの転送などにも費用がかかりますが、今回の目的ならばそこはまあ無視できるので、このPCを1日使って1,200円〜1,500円ぐらいかと思います。
やねうら王を用いてdepth 10で教師を生成してみたところ24時間で1億局面生成できました。100億局面生成するのに12〜15万円ですね。
借りられるインスタンス数の上限
このspot instanceがこの値段で100台借りられれば1日で生成が終わって良いのですが、6インスタンス起動したところで生成数の制限に引っかかりました。この生成数の上限を緩和してもらうためには、サポートに連絡しないといけないようです。ただ、サポートが平日しかやっていなくて、すでに詰んでますが…。
AWS、スポットインスタンスの生成数に上限があり、これを解除するのに図の画面で「サービス制限の増加」を選ばないといけないのだが、「制限が増加」だと制限増えそうw
「Request limit increase」の訳なんだろうけど、このlimitは「制限」ではなく「上限」かと。 pic.twitter.com/k79oSHsyIZ
— やねうら王 (@yaneuraou) November 4, 2017
電王トーナメント直前だが、ダメ元でAWSに50万円ほど使ってみようかと思って昨日、久しぶりにAWSを使ってみたのだが、6インスタンスspotで借りた段階で制限に引っかかり(コンパイルなどのテスト用も含めると10インスタンス)、AWSのサポートは平日しかやってない。これは詰んだわ。
— やねうら王 (@yaneuraou) November 5, 2017
※ 「スポットインスタンスは、1リージョンにつき10インスタンスまで」という制限があるようで、リージョンを変更してそれぞれのリージョンで10インスタンスずつ借りるという回避策はありますが、リージョンによってはスポットインスタンスでも結構高いので…。
電気代と比較すると?
我が家の電気代はPC 1台当たり1ヶ月1万円程度のようなので、同スペックのPC 1ヶ月が3,4万円で借りられるなら電気代の3,4倍で済むという言い方も出来るかと思います。物理的な機材も要りませんし、m4.x16ならメモリも256GB搭載していますし、故障したりメンテナンスの必要もありません。瞬間的に100台、200台借りられるのも魅力です。そういう意味では、電気代の3,4倍に収まるならとても安いかと思います。
やねうら王は一昨年前はgccでコンパイルすら通らなかったので、AWSでWindows(+オンデマンド)で借りるしかなく、Linux/spotの10倍ぐらいの値段で借りていたのですが、それからすると格安であり、もう自宅の機械学習用のPCはそのうち処分してもいいかなという気持ちになりました。(少なくともこれ以上、新規で買い足す意味はなさそうです。)
まとめ
コンピュータ将棋の教師局面の生成は、一気にやることで開発時間が大幅に短縮できるので、そういう用途にはAWSが向いています。200台借りることにより、3ヶ月かかるところが12時間で生成が終わるなら、開発期間を大幅に短縮できます。
ただ、上に書いたようにインスタンス数の制限はあるので、日頃から使い慣れてない人間が土壇場で使ってもうまく活用できないんだなぁと思いました。この記事が皆様のお役に立てれば幸いです。
追記 2017/11/06 19:00
チャットで「インスタンス制限の増加」をお願いしたところ、月曜の昼ごろ返信があり、なんやかんやして、その日の夕方に100インスタンスまで作成できるようにしてもらえました。
本日の夕方ごろAWSのスポットインスタンスの制限を緩和してもらえ、100インスタンスまで起動できるようになったのはいいが、100インスタンスだと24時間で15万円であり、私が交通事故にでも遭って半年間意識不明の重体だったら2,700万円の支払いかと思うとうかうか外も歩けやしねぇ… pic.twitter.com/hLveMJc7wX
— やねうら王 (@yaneuraou) November 6, 2017
札束でPCを殴り倒した者が勝ちの展開w
S3から転送する時間とか、教師局面をシャッフルする時間だとか、定跡を作る時間だとか、評価関数を実装する時間だとか、どちらかと言うと時間攻めでやられてるような…(´ω`)
spot instanceの自動再開対策というか、私が使った時の経験から。。
もろもろの環境が出来たらAMIにしといて、spot instanceのリクエスト時に、そのAMIを指定して並列化してました。
リクエスト時のユーザーデータに、起動時に実行されるスクリプトを書けるので、
インスタンスを上げたら記事にあるようなコマンドを実行する startup.sh 的なものを private gist に置いて curl で取ってきて実行させる横着をしてました。
教師データの蓄積は awscli を入れて
aws s3 cp
する方が気分が楽でした。(データがデカいのでfuseが刺さるととても悲しい)あとは、終ったらshutdownを投げてインスタンスを終らせてました。
小市民なのでoneshotで借りてましたが、そんな感じで、自動再開もいけると思います。
あと、tips(?)としては、
spot instanceの中断はがんばれば2分前に警告が拾えます。ので、フォローするかはコスパと相談。
http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/spot-interruptions.html
ただ、私も入札を高めにしてあきらめました。(2分じゃどうにもならんです)
shuffleはIOPSが激しいので、上限がメモリサイズになって良いならtmpを/dev/shmに
ln -s
すると早いです。ファイルが巨大でIOPSが低いデータ(shuffledなデータ)ならアベイラビリティーゾーンを揃えてEBSを光学ドライブ感覚で使う方が良いかもです。
実行ファイルや設定ファイルなど、ファイル共有がちまちま発生するならNFSサーバを用意しとくとらくです。(scpでもいいけど台数が増えると死ぬ)
東京リージョンにこだわりが無いならEFSもありかも、私はつかったこと無いのですが。。
くらいでしょうか。
開発に集中したい開発者はここらの環境はボタン一個でできると良いんですけどね。。
私が知らない用語がチラホラとw
めっちゃ参考になります。ありがとうございます!