[Project Bonsai] Bonsaiのシミュレータを触ってみる【番外編】

# はじめに
Project Bonsaiについて調べてみましたの3回目の番外編です。
過去の内容はこちら。
1回目は[「Bonsaiを触ってみる」](https://qiita.com/masaya3/items/5cca56a773386bb80262)
2回目は[「Bonsaiをいじってみる」](https://qiita.com/masaya3/items/42d3050354c9c8141042)
3回目は[「Bonsaiのシミュレータを触ってみる」](https://qiita.com/masaya3/items/05b1d578d1921f8ae20f)
4回目は[「[Bonsaiをローカル環境で使ってみるる」](https://qiita.com/masaya3/items/1b7df03eb87747a3a4bc)
ローカルシミュレータの実行速度が遅すぎるので、実用に耐えられるようBonsaiのシミュレータに登録してみたいと思います。


# [Bonsai](https://azure.microsoft.com/ja-jp/services/project-bonsai/)って何？
Microsoftが提供している自律システム向け機械教示サービスです。（現在はPublic Preview）
産業制御システムに焦点を当てた汎用ディープ強化学習プラットフォームのようです

## 学習時間を速くする
### ローカルシミュレータが遅すぎる件について
ローカルシミュレータでもなんとかなるかなと思い、1日以上動かしてみたりしましたが、何ともなりませんでした。
通信トラブルで止まったり等もあり、散々です。

現在、学習させている内容は、1エピソードを50回にしているので、1回学習カリキュラムの実行回数は最大50回
Bonsaiは、70万エピソードを実行するか、これ以上学習が不要な状態になるまで実施しますので、
70万（学習回数） × 50回（エピソード） = 3500万回
の処理回数（最大）が必要となります。

私の環境の場合、ローカルシミュレータの実行速度は1秒当たり約6回
単純に、3500万 ÷ (6/s × 3600) = 約1620時間（約2か月・・？）

ローカルでやっては絶対ダメなやつでした。

### シミュレータをコンテナ化する

シミュレータをコンテナ化することで、複数のインスタンスを実行させ、高速に学習させることができます。
[「BonsaiをBonsaiのシミュレータを触ってみる」](https://qiita.com/masaya3/items/05b1d578d1921f8ae20f)では、VisualStudio上から実行しましたが、こちらを[Dockerのコンテナ化](https://github.com/microsoft/microsoft-bonsai-api/tree/main/CSharp/samples/Microsoft.Bonsai.Api.Samples.Cartpole)します。

#### シミュレータのパッケージを出力する
まずは、VisualStudioからシミュレータのパッケージを出力します。

プロジェクトを右クリックし、メニューから「発行」を選択します。
![発行](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189829/b6a28ccd-02c3-9098-ccaa-84b411af996e.png)

「発行」ボタンをクリックして、パッケージを出力します。
![出力](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189829/44292ada-ed10-1af8-b4b7-94b02db3062c.png)

#### まずはローカルで動作確認をする
Bonsaiに登録する前に、ローカル環境下で問題なく動作するか確認してみます。

##### Dockerのイメージを作成する
「Microsoft.Bonsai.Api.Samples.Cartpole」フォルダから以下のコマンドを実行します。

```bash
docker build -t csharp-cartpole .
```

正常に終了すると、Dockerのイメージが作成されます。
![イメージ出y六](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189829/2aec9fd4-a791-226c-6176-d8d38ad8583e.png)

シミュレータのパッケージ出力ができてない場合は、エラーになりますので注意ください。

##### Dockerをイメージを実行する

コンテナが実際に動作するか実行して確認します。

以下のコマンドを実行し、起動させます。

```bash
docker run --rm -it -e SIM_WORKSPACE="SIM_WORKSPACE" -e SIM_ACCESS_KEY="SIM_ACCESS_KEY" -e SIM_API_HOST="https://api.bons.ai"   csharp-cartpole
```
`SIM_WORKSPACE`には、Bonsaiのworkspace IDを設定します。
`SIM_ACCESS_KEY` には、BonsaiのAccessKeyを設定します。

起動すると、デバッグ時と同じように、Bonsaiとの接続待ちのログが出力されます。
![実行](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189829/a887315f-614e-48a9-1f68-e444a1646de7.png)

##### デバッグ機能で動作を検証する
Dockerで動いているシミュレータが、Bonsai上と接続できているか確認します。
「Simulators」に、「CartPole-CSharp Unmanaged」が追加されていれば接続は問題ありません。

次に、シミュレータがうまく動作するかBonsaiのデバッガ確認します。
※確認方法は、[「Bonsaiのシミュレータを触ってみる」](https://qiita.com/masaya3/items/05b1d578d1921f8ae20f)をご確認ください。
![動作確認](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189829/38899e41-8943-ff20-b90b-c57b900b5230.png)

### シミュレータをBonsaiで使うために準備する

動くことを確認したら、次は[Azureでシミュレータを動かします](https://docs.microsoft.com/ja-jp/bonsai/guides/add-simulator?tabs=add-cli%2Ctrain-inkling&pivots=sim-platform-othe)。

ちなみに、Bonsaiによって管理されるシミュレータを実行すると、課金されます。
必ずローカルでテストしてから実施してください。

#### シミュレータをBonsaiに追加する

まずは、以下のコマンドを実行し、Azure Container Registry（以下ACR）インスタンスにログインします。

```bash
az acr login --name ACR_NAME
```

Docerfileからイメージをビルドします。
※ローカルで実行した場所と同じ場所で実行してください。

```bash
az acr build             \
  --image IMAGE_NAME:TAG \
  --registry ACR_NAME    \
  --file Dockerfile .
```

ビルド完了後、以下のコマンドを実行することで、リストが表示され正常にアップロードされているか確認できます。

```bash
az acr repository list --name ACR_NAME --output table
```
#### Bonsaiにシミュレータをパッケージとして登録する

次に、Bonsainiシミュレータを追加します。
「Simulators」右にある、「＋Add Sim」をクリックします。
![一覧呼び出し](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189829/6461c09e-7fc7-59c9-d3c8-0503e80721c6.png)

クリックすると、シミュレータの追加画面が表示されるので、一覧から「Other」を選択します。
![シミュレータの選択](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189829/4c55b70d-e443-cff2-ec4c-a81f78d99c16.png)

ACRにアップロードしたシミュレータを指定します。
image pathは、ビルド時に指定した`IMAGE_NAME`を指定します。
今回はdisplay nameも同じにしています。

最後に、シミュレータの環境を設定しますが、Cores及び、メモリは、既存値の使用（1コア、1Gメモリ）が推奨されているようです。
※Max instanceは、コストと速度からベストな数を選んでください。

![シミュレータの登録](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189829/7be35069-4cbb-d8d3-b688-0e74b9f88c23.png)

すべて入力が終わったら、「Create simulator」をクリックすることで、シミュレータが追加されます。
　
![シミュレータの追加](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189829/6c1700e8-97d3-1cef-092c-796a67c6fc84.png)

「csharp-cartpol（Unmanagedがついていない）」がSimulatorsが登録されます。
また、ローカルシミュレータの時にはなかった、Packageも表示されています。

### 教育カリキュラムの呼び出し先に指定する
シミュレータのPackage名を設定することで、直接シミュレータを指定することができます。（チュートリアルと同じ）

```bash
source simulator(Action: SimAction):SimState{  
  package "csharp-cartpole"       
}
```
# まとめ
今回はローカルのシミュレータを、Bonsaiに登録するまでを試してみました。
正直、シミュレータをデバッグする状況でない限り、ローカルで動かすのは得策ではないことを身をもって実感しました。
ちなみにBonsai上で動かすと、インスタンス数が1でも、ローカルの10倍以上速かったです。

Bonsai登録後は、課金されるのに躊躇していましたが、使わないと作業が終わらないことがわかりました、、
ただ、使うたびに課金されますので、しっかりデバッグしてから実施ください。