Unity ML-Agentsの強化学習はDockerイメージで実行できます。
じゃあGoogle Cloud Buildで実行できるよね?ということを確認してみました。
Unity ML-Agentsのバージョンはv0.9.1となります。
前提
GCPプロジェクトやgcloud
コマンドが利用できる前提です。
コマンドのインストール方法は下記が参考になります。
Cloud SDK のインストール | Cloud SDK のドキュメント | Google Cloud
https://cloud.google.com/sdk/downloads?hl=JA
Unity ML-Agentsの利用方法やDockerイメージの作成については下記をご参考ください。
MacでUnity ML-Agentsの環境を構築する(v0.9.1対応) - Qiita
https://qiita.com/kai_kou/items/268ccf6f961f8ca8cba8
DockerでUnity ML-Agentsを動作させる(v0.9.1対応) - Qiita
https://qiita.com/kai_kou/items/0c2f3c7d22363fd91e4e
Google Cloud Buildを利用してUnity ML-AgentsのDockerイメージを作成する(v0.9.1対応) - Qiita
https://qiita.com/kai_kou/items/5eabbaa2b564527e0b4e
設定ファイルの用意
gcloud
コマンドからビルド実行する前提となります。
> mkdir 任意のディレクトリ
> cd 任意のディレクトリ
> touch cloudbuild.yaml
steps:
- name: 'gcr.io/$PROJECT_ID/unity-ml-agents:0.9.1'
args: ['trainer_config.yaml', '--env', '3DBall', '--train', '--run-id', '$BUILD_ID']
id: 'mlagents-learn'
- name: 'gcr.io/cloud-builders/gsutil'
entrypoint: 'bash'
args: ['-c', 'while [ ! -f models/**/*.nn ]; do if [ -d summaries ]; then gsutil cp -r summaries gs://任意のバケット名; fi; sleep 10s; done']
waitFor: ['-']
- name: 'gcr.io/cloud-builders/docker'
entrypoint: 'bash'
args: ['-c', 'if [ ! -f models/**/*.nn ]; then mkdir -p models/error; touch models/error/error.nn; fi']
waitFor: ['mlagents-learn']
timeout: 3600s
artifacts:
objects:
location: 'gs://任意のバケット名/models/$BUILD_ID/'
paths: [
'models/**/*'
]
パラメータの詳細は下記が参考になります。
REST Resource: projects.builds
https://cloud.google.com/cloud-build/docs/api/reference/rest/v1/projects.builds
定義のポイントを説明します。
Unity ML-Agentsの学習実行
Unity ML-Agentsで学習を開始するステップです。name
でDockerイメージを指定しています。
- name: 'gcr.io/$PROJECT_ID/unity-ml-agents:0.9.1'
args: ['trainer_config.yaml', '--env', '3DBall', '--train', '--run-id', '$BUILD_ID']
id: 'mlagents-learn'
Dockerイメージは事前に作成してGoogle Container Registryへアップする前提です。
作成方法については、下記を参考ください。
Google Cloud Buildを利用してUnity ML-AgentsのDockerイメージを作成する(v0.9.1対応) - Qiita
https://qiita.com/kai_kou/items/5eabbaa2b564527e0b4e
Unityアプリとハイパーパラメータファイルは、gcloud
コマンド実行時にsourceとして指定します。
id
は後ステップのwaitFor
で指定するために定義しています。
Dockerイメージで定義しているendpoint
がmlagents-learn
となるため、args
にはmlagents-learn
のパラメータを指定しています。
--run-id
には$BUILD_ID
を指定し、一意となるようにしています。
$BUILD_ID
は$PROJECT_ID
と同じようにビルド開始時に置換される変数となります。
途中経過ファイルをコピー
gsutil
が利用できるイメージを指定して、学習中にsummaries
ディレクトリへ出力されるファイルを定期的にCloud Storageへコピーするステップです。
waitFor
に-
を指定するとで、前ステップと同時に並行して実行されます。
entrypoint
にbash
を指定して、args
に-c
オプションを利用してコマンドを書いてます。
steps:
- name: 'gcr.io/cloud-builders/gsutil'
entrypoint: 'bash'
args: ['-c', 'while [ ! -f models/**/*.nn ]; do date; if [ -d summaries ]; then gsutil cp -r summaries gs://任意のバケット名; fi; sleep 10s; done']
waitFor: ['-']
コマンドを整形してみます。
while [ ! -f models/**/*.nn ]; do
if [ -d summaries ];
then gsutil cp -r summaries gs://任意のバケット名;
fi
sleep 10s;
done
学習が完了するとモデルがmodels/**/*.nn
ファイルとして作成されます。
なので、モデル作成=学習完了するまで、の間、summaries
フォルダのファイルを定期的にCloud Storageへコピーするコマンドを実行します。
ただ、このままだと学習実行時のエラーなどで、models/**/*.nn
ファイルが作成されないとステップが終了しないため、次の終了処理のステップで対応しています。
終了処理
こちらもbashコマンドを利用しています。
waitFor
をmlagents-learn
とすることで、学習実行のステップが終わったら実行されるようにしています。
- name: 'gcr.io/cloud-builders/docker'
entrypoint: 'bash'
args: ['-c', 'if [ ! -f models/**/*.nn ]; then mkdir -p models/error; touch models/error/error.nn; fi']
waitFor: ['mlagents-learn']
コマンドを整形してみてみると、models/**/*.nn
が存在しなければ、ダミーファイルを作成するコマンドになっています。これで、学習実行がエラーなどで、モデルファイルを作成しない場合もジョブが終了するようになります。
if [ ! -f models/**/*.nn ]; then
mkdir -p models/error;
touch models/error/error.nn;
fi
結果ファイルのコピー
全ステップ完了後、paths
で指定したファイルをCloud Storageへコピーする定義になります。
artifacts:
objects:
location: 'gs://任意のバケット名/models/$BUILD_ID/'
paths: [
'models/**/*'
]
タイムアウト設定
Unity ML-Agentsで学習実行する場合、長時間となる可能性があります。
Cloud Buildではステップごと、ジョブ全体としてタイムアウト時間を指定することができます。
ジョブ全体のタイムアウトは指定しないとデフォルトで10分となりますので、定義しています。
timeout: 3600s
タイムアウトについての詳細は下記が参考になります。
ビルド構成の概要 | Cloud Build | Google Cloud
https://cloud.google.com/cloud-build/docs/build-config?hl=ja
ジョブ実行
実際にCloud Buildでジョブ実行させてみます。
学習するアプリの準備
学習するアプリは下記記事で利用したML-Agentsに含まれる3DBall
を利用します。
すでにDockerコンテナで実行できるビルドファイルがある前提です。詳細は下記をご参考ください。
DockerでUnity ML-Agentsを動作させる(v0.9.1対応) - Qiita
https://qiita.com/kai_kou/items/0c2f3c7d22363fd91e4e
学習に必要となるビルドファイルとハイパーパラメータファイルをZIPファイルに圧縮します。
圧縮ファイルはジョブ実行時にワークスペースへコピーされ勝手に展開されます。
# ビルドファイルとハイパーパラメータファイルを圧縮
> cd 3DBallのビルドファイルがあるディレクトリ
> zip -r 3DBall_App.zip 3DBall.x86_64 3DBall_Data trainer_config.yaml
# Cloud Storageへコピー
> gsutil cp 3DBall_app.zip gs://任意のバケット名/3DBall_app.zip
> cd 任意のディレクトリ
> gcloud builds submit \
--config=cloudbuild.yaml \
gs://任意のバケット名/3DBall_app.zip
Created [https://cloudbuild.googleapis.com/v1/projects/GCPのプロジェクトID/builds/69ebb6e2-280f-4577-a8b5-f83b95929d8e].
Logs are available at [https://console.cloud.google.com/gcr/builds/69ebb6e2-280f-4577-a8b5-f83b95929d8e?project=xxxxxxxxxxxx].
(略)
Step #0 - "mlagents-learn": beta: 0.001
Step #0 - "mlagents-learn": buffer_size: 12000
Step #0 - "mlagents-learn": epsilon: 0.2
Step #0 - "mlagents-learn": hidden_units: 128
Step #0 - "mlagents-learn": lambd: 0.99
Step #0 - "mlagents-learn": learning_rate: 0.0003
Step #0 - "mlagents-learn": max_steps: 5.0e4
Step #0 - "mlagents-learn": memory_size: 256
Step #0 - "mlagents-learn": normalize: True
Step #0 - "mlagents-learn": num_epoch: 3
Step #0 - "mlagents-learn": num_layers: 2
Step #0 - "mlagents-learn": time_horizon: 1000
Step #0 - "mlagents-learn": sequence_length: 64
Step #0 - "mlagents-learn": summary_freq: 1000
Step #0 - "mlagents-learn": use_recurrent: False
Step #0 - "mlagents-learn": vis_encode_type: simple
Step #0 - "mlagents-learn": reward_signals:
Step #0 - "mlagents-learn": extrinsic:
Step #0 - "mlagents-learn": strength: 1.0
Step #0 - "mlagents-learn": gamma: 0.99
Step #0 - "mlagents-learn": summary_path: ./summaries/69ebb6e2-280f-4577-a8b5-f83b95929d8e-0_3DBallLearning
Step #0 - "mlagents-learn": model_path: ./models/69ebb6e2-280f-4577-a8b5-f83b95929d8e-0/3DBallLearning
Step #0 - "mlagents-learn": keep_checkpoints: 5
Step #0 - "mlagents-learn": Setting up 1 worker threads for Enlighten.
Step #0 - "mlagents-learn": Thread -> id: 7f2f44c61700 -> priority: 1
Step #1: Copying file://summaries/69ebb6e2-280f-4577-a8b5-f83b95929d8e-0_3DBallLearning/events.out.tfevents.1566292921.6e8e6580f319 [Content-Type=application/octet-stream]...
/ [1 files][ 678.0 B/ 678.0 B]
Step #1: Operation completed over 1 objects/678.0 B.
Step #0 - "mlagents-learn": INFO:mlagents.trainers: 69ebb6e2-280f-4577-a8b5-f83b95929d8e-0: 3DBallLearning: Step: 1000. Time Elapsed: 11.002 s Mean Reward: 1.149. Std of Reward: 0.612. Training.
Step #1: Copying file://summaries/69ebb6e2-280f-4577-a8b5-f83b95929d8e-0_3DBallLearning/events.out.tfevents.1566292921.6e8e6580f319 [Content-Type=application/octet-stream]...
/ [1 files][ 933.0 B/ 933.0 B]
Step #1: Operation completed over 1 objects/933.0 B.
Step #0 - "mlagents-learn": INFO:mlagents.trainers: 69ebb6e2-280f-4577-a8b5-f83b95929d8e-0: 3DBallLearning: Step: 2000. Time Elapsed: 22.591 s Mean Reward: 1.247. Std of Reward: 0.692. Training.
Step #1: Copying file://summaries/69ebb6e2-280f-4577-a8b5-f83b95929d8e-0_3DBallLearning/events.out.tfevents.1566292921.6e8e6580f319 [Content-Type=application/octet-stream]...
/ [1 files][ 1.2 KiB/ 1.2 KiB]
Step #1: Operation completed over 1 objects/1.2 KiB.
(略)
Finished Step #2
Finished Step #1
PUSH
Artifacts will be uploaded to gs://任意のバケット名 using gsutil cp
models/**/*: Uploading path....
Omitting directory "file://models/24894139-cf12-4f3d-a8ee-1748a5606e51-0/3DBallLearning". (Did you mean to do cp -r?)
Copying file://models/24894139-cf12-4f3d-a8ee-1748a5606e51-0/3DBallLearning.nn [Content-Type=application/octet-stream]...
/ [1/1 files][ 74.8 KiB/ 74.8 KiB] 100% Done
Operation completed over 1 objects/74.8 KiB.
models/**/*: 1 matching files uploaded
1 total artifacts uploaded to gs://任意のバケット名/models/24894139-cf12-4f3d-a8ee-1748a5606e51/
Uploading manifest artifacts-24894139-cf12-4f3d-a8ee-1748a5606e51.json
Artifact manifest located at gs://任意のバケット名/models/24894139-cf12-4f3d-a8ee-1748a5606e51/artifacts-24894139-cf12-4f3d-a8ee-1748a5606e51.json
DONE
------------------------------------------------------------------------------------------------------------------------------
ID CREATE_TIME DURATION SOURCE IMAGES STATUS
24894139-cf12-4f3d-a8ee-1748a5606e51 2019-08-20T09:46:48+00:00 11M49S gs://GCPのプロジェクトID_cloudbuild/source/1566294405.28-c9f8bcd12b5246cc8e1dc8b04e0534f9.zip - SUCCESS
Cloud Functionsからもビルド実行可能ですので、Cloud Storageにzipファイルがコピーされたらジョブを登録・実行して、学習させることもこれで可能になります。
Google Cloud Functions(Python)からCloud Buildでビルド実行してみる
https://qiita.com/kai_kou/items/8f040e261c4a50ef8bfc
まとめ
Dockerを利用して動作させることができると、システム構成に選択の幅が広がって良いですね。メンテナンス性やコスト、想定されるスケールなどを考慮して、適切な選択ができそうです。
参考
Cloud SDK のインストール | Cloud SDK のドキュメント | Google Cloud
https://cloud.google.com/sdk/downloads?hl=JA
REST Resource: projects.builds
https://cloud.google.com/cloud-build/docs/api/reference/rest/v1/projects.builds
ビルド構成の概要 | Cloud Build | Google Cloud
https://cloud.google.com/cloud-build/docs/build-config?hl=ja
Google Cloud Functions(Python)からCloud Buildでビルド実行してみる
https://qiita.com/kai_kou/items/8f040e261c4a50ef8bfc
MacでUnity ML-Agentsの環境を構築する(v0.9.1対応) - Qiita
https://qiita.com/kai_kou/items/268ccf6f961f8ca8cba8
DockerでUnity ML-Agentsを動作させる(v0.9.1対応) - Qiita
https://qiita.com/kai_kou/items/0c2f3c7d22363fd91e4e
Google Cloud Buildを利用してUnity ML-AgentsのDockerイメージを作成する(v0.9.1対応) - Qiita
https://qiita.com/kai_kou/items/5eabbaa2b564527e0b4e