Amazon SageMakerとBlueoilを使って量子化されたDeep Learningモデルを作成する

この記事は、[LeapMind Advent Calendar 2019](https://adventar.org/calendars/3954) 10日目の記事です。

## TL;DR
Amazon SageMakerが使えるようになっていれば、下記の手順で自分でトレーニングした量子化されたDeep Learningモデルが簡単に手に入るよ。

* Repository[https://github.com/hadusam/blueoil-sagemaker] をCloneする
* SageMaker上でJupyter Notebookぽちぽち
* DownloadしたモデルとReadmeにしたがって推論する

## この記事の目的
私が所属しているLeapMindでは、数ヶ月に1度、HackDaysという全社員向けの[自由に好きな開発を好きな人とやって、何かしらの成果を出すことが目的の](https://leapmind.io/blog/2019/04/15/hackdays-2019-2q/)イベントがあります。
本記事では、その期間で実施した、Amazon SageMaker x Blueoilを利用したOn-Demand Trainingについて、その紹介をしようと思います。

## Amazon Sagemakerって？
> Amazon SageMaker は、すべての開発者やデータサイエンティストが機械学習 (ML) モデルを迅速に構築、トレーニング、デプロイできるようにする完全マネージド型サービスです。

Ref: https://aws.amazon.com/jp/sagemaker/

上記にあるように、SageMakerは機械学習モデルの作成からデプロイまでのワークフローに必要な多種の機能を提供しているサービスです。
SageMakerを利用することで、On-demandなGPU利用(学習をJobとして投げるとGPUインスタンスの作成、起動、停止を実施してくれる)や、実験管理(モデルはS3に実験と紐づいて保存される、ハイパーパラメータの管理、実験中のリソースモニタリング)などが可能になります。
今回はAmazon SageMaker Notebooksを利用してTrainingの実行を行います。

## Blueoilって？
> Blueoil is a software stack dedicated to neural networks. It includes special training method for quantization and original networks designed to be highly compatible with FPGA devices. This is done in order to operate a neural network at high speed on a low-powered FPGA. New models can be trained easily by only preparing data. The finished model can be converted into a binary file that runs on FPGA or CPU devices with a single command.

Ref: https://blueoil.org/

Blueoilは[LeapMind Inc.](https://leapmind.io/)が提供している、低消費電力なデバイス上でディープラーニングを実現するためのオープンソースソフトウェアスタックです。
Blueoilを利用することで、量子化されたDeep Learningモデルの学習および、学習したモデルをCPUやFPGAデバイスで実行するためのBinary Fileの生成が可能になります。
今回は[機械学習を使った今までにないデバイスをあまねく世に広める](https://leapmind.io/)ために、BlueoilをGPU環境が手元にない状態でも簡単に利用できるようにするため、SageMakerを試してみました。

## 実行手順
前置きが長くなりました。。。以下に具体的な実行手順を記載します。
### 事前準備
AWSアカウントはすでに作成済みとします。
#### SageMakerのセットアップ
下記の公式DocumentのStep1, Step2にしたがってください

* [ステップ 1: Amazon S3 バケットを作成する](https://docs.aws.amazon.com/ja_jp/sagemaker/latest/dg/gs.html) (sagemaker-から始まるバケットを作成する)
* [ステップ 2: Amazon SageMaker ノートブックインスタンスの作成](https://docs.aws.amazon.com/ja_jp/sagemaker/latest/dg/gs-setup-working-env.html)

`SageMaker` > `ノートブックインスタンス`にて`ノートブックインスタンスの作成`をclick
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79348/096d0664-2dca-6941-30b9-00d717d4f095.png)

Notebookインスタンス内でTraining等は行わないため、最も安価な`ml.t2.medium`で作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79348/e29e4597-79e2-7b79-a550-c3dd68096684.png)

#### Noteboookのセットアップ
* インスタンスが立ち上がったら`アクション`の`Jupyter を開く`をclick
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79348/4fa3605d-d0aa-6aef-904a-e89a36f4983b.png)
* Jupyter Notebookが開くので、新規でファイルを作成(kernelはなんでも良い)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79348/3d7de9ed-3895-97a8-1cac-bdc7b5a080fe.png)
* git cloneを実行

`!git clone https://github.com/hadusam/blueoil-sagemaker`
Ref: https://github.com/hadusam/blueoil-sagemaker#on-sagemaker-notebook-instance
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79348/df8f75ae-a32d-abee-9ee2-96a538c05343.png)

* 元のディレクトリに戻ると`blueoil-sagemaker`というディレクトリが作成されているので、その配下の`blueoil_cifar10_example.ipynb`を開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79348/9f112bf9-1198-8902-7361-408d4358e41d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79348/662aa569-d130-098f-de11-27c9e934e8fb.png)

* kernel選択のダイアログが出るので、`conda_tensorflow_p36`を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79348/ed6f6c07-6e21-ca25-5f81-eeb297ceb55b.png)

### On-Demand Training
準備ができました。
ここからはJupyter Notebook上で`Shift + Enter`していくだけですが、せっかくなので個々について解説します。
#### SageMaker用のBlueoil Docker Imageの作成
Dockerhub上の[blueoil/bueoil:latest](https://hub.docker.com/r/blueoil/blueoil)をpullし、SageMakerから実行されるPython scriptを追加してBuildし直し、ユーザーのECR上の`blueoil-sagemaker`というrepositoryにPushします(なければRepositoryを作成します)。
詳細については実行しているshell scriptを確認してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79348/70507839-b4cf-ff0c-4507-9efad9701a14.png)

#### データセットの準備
Trainingに利用するデータセットを準備してS3へアップロードします。
今回はSampleとしてCifar10(のCaltech101フォーマット)を利用していますが、Blueoilでサポートしているデータセットフォーマットであればなんでも良いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79348/ae35fe7b-6a58-70d9-cc00-96b220b5c7e0.png)

#### Training用のConfigの準備
BlueoilのConfigファイルを作成してS3へアップロードします。このコンフィグ内にはNWの指定やハイパーパラメータ等が含まれます。今回はSampleがRepository内に配置されているのでそちらを用います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79348/bac02b20-f471-df61-5ba9-182f5f7633eb.png)

#### Training実行
いよいよTrainingです。
*今回はNotebookインスタンス上ではなく別途GPUインスタンスを起動してTrainingを実行するのでCase1: On your local GPU serverはスキップしてください。*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79348/b4a593b3-dc84-e1df-9d31-61f504dee319.png)

実行環境(docker image)や学習に使用するインスタンスサイズ、ハイパーパラメータ(実行スクリプトに与えるコマンドライン引数)を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79348/b20bc137-4661-815f-7f15-0f74686db576.png)

S3に保存したデータセットやコンフィグを指定して`estimator.fit`でTrainingを実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79348/027b2f82-188f-bda2-60e3-39b7954da7a9.png)

以上で学習を実行することができました！
SageMaker上でGPUインスタンスが立ち上がり、学習が完了すると結果ファイルをS3に保存してくれます。

### Trainingの確認
SageMakerでは実行したTrainingをGUIで一覧確認できます。
#### Training一覧
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79348/fb3ac79c-1561-56ad-231c-5c4d10cdaf4b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79348/8b633745-9c20-e510-cf37-03466279b2bb.png)

#### 作成されたModelのダウンロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79348/aa051686-d427-776a-81f2-453eeec7af8b.png)

#### メトリクス確認
CPU/Mem/Diskだけでなく、GPUリソース利用状況がみれる！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79348/b0252e71-f9d4-b35f-dc0a-2c2756a4d153.png)

### 推論の実行
今回作成したModelをダウンロードして下記の手順に従うことで、CPUやFPGA上での推論が可能になります！

* [Run inference script on x86 Linux (Ubuntu 16.04)](https://docs.blue-oil.org/tutorial/image_cls.html#run-inference-script-on-x86-linux-ubuntu-16-04)
* [Run a trained neural network on the FPGA board](https://docs.blue-oil.org/tutorial/run_fpga.html#run-a-trained-neural-network-on-the-fpga-board)


## まとめ
SageMaker上でBlueoilを利用したTrainingが実行できました！
今回はTrainingのみに焦点を絞りましたが、SageMakerを利用することで、他にもAnnotation([SageMaker Ground Truth](https://aws.amazon.com/jp/sagemaker/groundtruth/))やGreengrassとの連携によるモデルデプロイなど様々な拡張が可能なので、夢が広がりますね！
このように、AWSなどが提供しているMLエコシステムを利用すれば、手元にGPUがなくても、簡単にDeep Learningを試してみることができます。
皆さんもぜひ、自分の手で、今回のSageMaker x Blueoilを試してみてください！