NVIDIA 社提供の AMI で DeepLearning

 NVIDIA AMI DeepLearning AWS Docker
2016.10.12

Deep Learning に便利な AMI

 

NVIDIA 提供

2016/09 末に公開された模様。

自分で CUDA をインストールしたことがある方ならわかると思いますが、NVIDIA の GPU ドライバから始まり、CUDA をインストールするのはなかなかの手間でした。(まあ、一度 AMI を作ればってのはありますが) この AMI を使えば、ものすごく簡単にサーバが使い始められます!

AWS 提供

MXNet、Caffe、Tensorflow、Theano そして Torch など人気のフレームワークが事前にインストール・設定・テストされた AMI。

(お試し用テストサンプルが入っていたりするようです)

[ec2-user@ip-10-0-0-10 ~]$ ls -la /home/ec2-user/src/bin
合計 40
drwxrwxr-x  2 ec2-user ec2-user 4096  9月 20 00:48 .
drwxrwxr-x 14 ec2-user ec2-user 4096  9月 28 20:21 ..
-rwxr-xr-x  1 ec2-user ec2-user  350  9月 20 00:12 testAll
-rwxr-xr-x  1 ec2-user ec2-user 1207  9月 20 00:12 testCaffe
-rwxr-xr-x  1 ec2-user ec2-user 1141  9月 20 00:12 testMXNet
-rwxr-xr-x  1 ec2-user ec2-user   70  9月 20 00:13 testTensorFlow
-rwxr-xr-x  1 ec2-user ec2-user   66  9月 20 00:13 testTheano
-rwxr-xr-x  1 ec2-user ec2-user 1058  9月 20 00:13 testTheanoOrTensorFlow
-rwxr-xr-x  1 ec2-user ec2-user  861  9月 20 00:13 testTorch
-rwxr-xr-x  1 ec2-user ec2-user  210  9月 20 00:13 testUtil

起動してみる

NVIDIA CUDA Toolkit 7.5 on Amazon Linux を使い、中身を確認してみます。

起動手順

1. マーケットプレイスでライセンスに承諾

適切なリージョンを選択し continue をクリックします。

1_1.png

スポットインスタンスを使いたいので、マニュアルでの起動を選択。画面の左下にある AMI の ID を控えつつ、(今回の AMI はいまのところ無料ですが)起動時間あたりの利用料を確認し、ソフトウェアの規約に従うことを承認します。

2.png

2. EC2 インスタンスの起動

スポット料金を設定しつつ g2.2xlarge インスタンスを起動します。

1.png

2.png

スポットの金額が市場を下回るとインスタンスが起動します。

3. EC2 に SSH

起動したらサーバに入ってみます。 ssh -i ec2.pem ec2-user@x.x.x.x

インストールされているドライババージョンを確認してみます。

[ec2-user@ip-10-0-0-10 ~]$ nvcc -V

-bash: nvcc: コマンドが見つかりません

なるほど。

[ec2-user@ip-10-0-0-10 ~]$ /usr/local/cuda/bin/nvcc -V

nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2015 NVIDIA Corporation
Built on Tue_Aug_11_14:27:32_CDT_2015
Cuda compilation tools, release 7.5, V7.5.17

はい、しっかり 7.5 ですね。AMI 素晴らしい!!

NVIDIA-docker も入れとこう

1. docker を入れて

公式ドキュメント には従わず1、以下のコマンドで Docker をインストールします。

sudo yum install -y docker
sudo service docker start
sudo usermod -aG docker ec2-user

以後 ec2-user でも docker コマンドが使えるように、いったん SSH から抜けて入りなおします。

2. NVIDIA-docker も入れる

残念ながら 1.0.0 時点では、配布されている rpm の依存パッケージ名が AmazonLinux だとアレなもので、バイナリを持ってきて置くことにします。

wget -P /tmp https://github.com/NVIDIA/nvidia-docker/releases/download/v1.0.0/nvidia-docker_1.0.0_amd64.tar.xz
sudo tar --strip-components=1 -C /usr/bin -xvf /tmp/nvidia-docker*.tar.xz && rm /tmp/nvidia-docker*.tar.xz

3. nvidia-docker-plugin の起動

sudo mkdir -p /run/docker/plugins/
sudo -b nohup nvidia-docker-plugin > /tmp/nvidia-docker.log

もし後からサーバを再起動する / AMI をとるつもりであれば、以下のようにスクリプトを用意しておくとよいです。

sudo sh -c "cat << EOF > /etc/init.d/nvdocker-plugin
#!/bin/sh
# chkconfig: 345 98 20
# description: NVIDIA-docker plugin
nvidia-docker-plugin > /tmp/nvidia-docker.log
EOF"
sudo chmod +x /etc/init.d/nvdocker-plugin
sudo chkconfig --add nvdocker-plugin

plugin が起動したら、REST API の疎通を確認します。

[ec2-user@ip-10-0-0-10 ~]$ curl 127.0.0.1:3476/v1.0/docker/cli

--volume-driver=nvidia-docker --volume=nvidia_driver_352.99:/usr/local/nvidia:ro --device=/dev/nvidiactl --device=/dev/nvidia-uvm --device=/dev/nvidia0

4. 起動確認

インストールした NVIDIA-docker で nvidia-smi コマンドを実行します。

[ec2-user@ip-10-0-0-10 ~]$ nvidia-docker run --rm nvidia/cuda:7.5 nvidia-smi

Tue Oct 11 00:38:26 2016
+------------------------------------------------------+
| NVIDIA-SMI 352.99     Driver Version: 352.99         |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GRID K520           On   | 0000:00:03.0     Off |                  N/A |
| N/A   25C    P8    17W / 125W |     11MiB /  4095MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID  Type  Process name                               Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

いい感じ2ですね。

検証

推論サーバの起動

GPU を推論に使い、HTTP プロトコルを話す API サーバを使ってベンチマークをとってみます。

1. GRE インストール

NVIDIA 社がデモ用に作った、Caffe での推論を REST API 化した GPU REST Engine3 というアプリケーションを使います4

以下のコマンドで推論サーバを起動します。

cd $HOME
git clone https://github.com/NVIDIA/gpu-rest-engine
cd gpu-rest-engine
git checkout b7fac33
docker build -t inference -f Dockerfile.inference_server .
nvidia-docker run -d --name api -p 8000:8000 inference

2. 起動確認

git リポジトリに同梱されているウサギの画像を推論サーバに問い合わせてみます。

[ec2-user@ip-10-0-0-10 ~]$ IMAGE="./images/1.jpg"
[ec2-user@ip-10-0-0-10 ~]$ curl -XPOST --data-binary @${IMAGE} 127.0.0.1:8000/api/classify

[{"confidence":0.9998,"label":"n02328150 Angora, Angora rabbit"},{"confidence":0.0001,"label":"n02325366 wood rabbit, cottontail, cottontail rabbit"},{"confidence":0.0001,"label":"n02326432 hare"},{"confidence":0.0000,"label":"n02085936 Maltese dog, Maltese terrier, Maltese"},{"confidence":0.0000,"label":"n02342885 hamster"}]

99.98% の確率でアンゴラウサギらしいです。動いてますね。 この状態で SecurityGroup さえ解放されていれば、外部からの推論も行えます。楽しい。

簡易ベンチマーク

検証用クライアントのビルド

rakyll/boom を内包したツールをビルドします。

docker build -t client -f Dockerfile.inference_client .

ベンチマークの実施5

[ec2-user@ip-10-0-0-10 ~]$ docker run --rm -e CONCURRENCY=1 -e REQUESTS=20000 --net=host client

Summary:
  Total:       	258.6445 secs
  Slowest:     	0.0167 secs
  Fastest:     	0.0127 secs
  Average:     	0.0129 secs
  Requests/sec:	77.3262
  Total data:  	6880000 bytes
  Size/request:	344 bytes
[...]

GRE の README.md には「スタンドアローンな Caffe ならだいたい秒間 500 画像処理できる」とありますが、まあ、はい。 一方でこの GRE、マルチ GPU に対応してちゃんとリクエスト捌いてくれるということなので・・

インスタンスタイプ変更

Amazon EC2 では最近、P2 系がリリースされました。 New P2 Instance Type for Amazon EC2 – Up to 16 GPUs | AWS Blog

ということで、せっかくなので p2.16xlarge でもベンチマークをとり比較しようと思います6。GPU そのものも K80 だし、何から何まで高スペックになるので期待が高まりますね!

p2.16xlarge で再取得

10月12日現在、スポットインスタンスが意味不明な金額に高騰しているので素直にオンデマンドで起動します。上述の手順同様に7 GRE までのインストールを済ませ8、nvidia-smi を流してみます。

[ec2-user@ip-10-0-0-10 ~]$ nvidia-docker run --rm nvidia/cuda:7.5 nvidia-smi | grep K80 | wc -l
16

これを参考に CONCURRENCY の値をよしなに変更しつつ、ベンチマーク取得コマンドを打ってみます。

[ec2-user@ip-10-0-0-10 ~]$ docker run --rm -e CONCURRENCY=16 -e REQUESTS=20000 --net=host client

Summary:
  Total:        14.1379 secs
  Slowest:      3.9332 secs
  Fastest:      0.0055 secs
  Average:      0.0110 secs
  Requests/sec: 1414.6341
  Total data:   6880000 bytes
  Size/request: 344 bytes
[...]

おーなるほど。

更に、p2 系では GPU 最適化 が行えるので、その上でもう一度やってみます。

nvidia-docker run --rm --privileged nvidia/cuda:7.5 nvidia-smi -pm 1
nvidia-docker run --rm --privileged nvidia/cuda:7.5 nvidia-smi --auto-boost-default=0
nvidia-docker run --rm --privileged nvidia/cuda:7.5 nvidia-smi -ac 2505,875
[ec2-user@ip-10-0-0-10 ~]$ docker run --rm -e CONCURRENCY=16 -e REQUESTS=20000 --net=host client

Summary:
  Total:        7.9519 secs
  Slowest:      0.0200 secs
  Fastest:      0.0055 secs
  Average:      0.0063 secs
  Requests/sec: 2515.1144
  Total data:   6880000 bytes
  Size/request: 344 bytes
[...]

そもそも p2 系はスペック的に学習に最適なサーバだと思いますが、推論でもこれだけ違いがでてくるとわくわくしますね!!

利用する GPU デバイス数を変えてみる

NVIDIA-docker はやれる子なので、docker コンテナに引き渡しアプリで利用するデバイスを自由に指定できます。(当然ながら docker コンテナからは渡された GPU しか見えません)

現在動いているサービスを一度止め

docker stop api
docker rm api

5 GPU に制限して起動し直します。

NV_GPU=0,1,2,3,4 nvidia-docker run -d --name api -p 8000:8000 inference
[ec2-user@ip-10-0-0-10 ~]$ docker run --rm -e CONCURRENCY=5 -e REQUESTS=20000 --net=host client

Summary:
  Total:        25.8224 secs
  Slowest:      0.5705 secs
  Fastest:      0.0055 secs
  Average:      0.0064 secs
  Requests/sec: 774.5201
  Total data:   6880000 bytes
  Size/request: 344 bytes
[...]

それっぽい値ですね! おわり。

 

更新履歴

  1. yum update でカーネルが更新されてしまうと、再起動時に必要なモジュールが読み込まれなくなるため。 sudo sh -c 'echo "exclude=kernel*" >> /etc/yum.conf' などで対処しておいてもいいかもしれない 

  2. docker: Error response from daemon が返ってきたら再度実行してみてください。2度目なら通ると思います 

  3. Go の http サーバ経由で Caffe での推論を行う薄いラッパーです 

  4. 参考: GPU REST Engine のセットアップと動作確認 

  5. 画像の推論はせず、CUDA の kernel call のみを計測するアプリケーション も同梱されています。 

  6. 上限緩和しないと使えないのですが、そもそも申請フォーム上 p2 系が選択できないため、コメント欄で「p2 使わせて!」と懇願してしばらく待ちましょう 

  7. g2 などでの AMI 化がうまくいっていないと p2 起動後に絶望するので、間違いなく動作する、NVIDIA 公式 AMI からスクリプトをあてていく手順をお勧めします。慣れていなければ。 

  8. 推論サーバは GPU 分の初期化処理(モデルのロードなど)が走るため、起動までしばらく時間がかかります。docker logs -f api などで “Starting server listening on :8000” が表示されるまで気長に待ちます。