AWSのGPUインスタンス上のDockerコンテナでTensorFlow for Rを試す
TensorFlow for RがRStudioからリリースされたので早速試してみた。環境構築が面倒になってきたのでEC2上にDocker環境を構築し、tensorflow+rstudioコンテナを作ったので手順をメモしとく。
項目 | 設定 |
---|---|
リージョン | オレゴン |
Amazon マシンイメージ | CentOS 7 (x86_64) - with Updates HVM |
インスタンスタイプ | g2.2xlarge |
ストレージの追加 | EBS Cold HDD (sc1) 500GB |
CUDA | 7.5 |
事前にCUDAのインストール、nouveauの無効化はしておくこと。
Docker, nvidia-dockerのインストール
ホストとなるEC2にInstallation on CentOSに従ってインストールする。
# yumのリポジトリにDockerを追加 $ sudo tee /etc/yum.repos.d/docker.repo <<-'EOF' [dockerrepo] name=Docker Repository baseurl=https://yum.dockerproject.org/repo/main/centos/7/ enabled=1 gpgcheck=1 gpgkey=https://yum.dockerproject.org/gpg EOF # Dockerのインストール $ sudo yum install -y docker-engine # centosユーザーをdockerグループに追加 sudo usermod -aG docker centos
Dockerイメージ&コンテナの保存先をControl and configure Docker with systemdを参考にして変更する
$ sudo mkdir /etc/systemd/system/docker.service.d $ sudo touch /etc/systemd/system/docker.service.d/docker.conf $ sudo vi /etc/systemd/system/docker.service.d/docker.conf
CentOS7でDockerのイメージ・コンテナの保存先を変更する設定
nvidia-dockerのインストール
Home · NVIDIA/nvidia-docker Wiki · GitHubに従ってnvidia-dockerをインストールする。
$ wget -P /tmp https://github.com/NVIDIA/nvidia-docker/releases/download/v1.0.0-rc.3/nvidia-docker-1.0.0.rc.3-1.x86_64.rpm $ sudo rpm -i /tmp/nvidia-docker*.rpm && rm /tmp/nvidia-docker*.rpm
Dockerサービスを起動する
$ sudo systemctl status nvidia-docker
CentOS用のCUDA 7.5, cuDNN 5のDockerイメージをpullして動かしてみる。
$ sudo nvidia-docker pull nvidia/cuda:7.5-cudnn5-devel-centos7 $ sudo nvidia-docker run --rm nvidia/cuda:7.5-cudnn5-devel-centos7 nvidia-smi Fri Sep 30 08:19:56 2016 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 367.48 Driver Version: 367.48 | |-------------------------------+----------------------+----------------------+ | 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 Off | 0000:00:03.0 Off | N/A | | N/A 30C P8 17W / 125W | 0MiB / 4036MiB | 0% Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | No running processes found | +-----------------------------------------------------------------------------+
Dockerコンテナ上からGPUにアクセスできていることが確認できた。
Python3 + TensorFlowコンテナの作成
まずPython3 + TensorFlowのイメージを作り、そのイメージを元にR, RStudioを追加していく。Python3 + TensorFlowのイメージはtensorflow/Dockerfile.gpu at master · tensorflow/tensorflow · GitHubを参考にしてDockerfileを以下のように作成した。当初Python3はpyenvでインストールしていたがRのtensorflowパッケージのインストール時にリンクが見つからず対応できなかったのでyumでインストールしている。
nvidia-docker上でTensorFlowを実行するDockerfile
上記のDockerfileを元にDockerイメージを作成する。
$ sudo nvidia-docker build -f ./Dockerfile.tensorflow -t kashitan/tensorflow:latest --no-cache=true .
できたイメージからコンテナを作成してMNISTのサンプルを実行してみる。
# ホストOSでコンテナを起動 $ sudo nvidia-docker run -it --rm -p 8888:8888 ai_team/tensorflow:latest /bin/bash # コンテナ上でMNISTのCNNを実行 $ python3 /usr/lib/python3.4/site-packages/tensorflow/models/image/mnist/convolutional.py I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcublas.so locally I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcudnn.so locally I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcufft.so locally I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcuda.so.1 locally I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcurand.so locally Successfully downloaded train-images-idx3-ubyte.gz 9912422 bytes. Successfully downloaded train-labels-idx1-ubyte.gz 28881 bytes. Successfully downloaded t10k-images-idx3-ubyte.gz 1648877 bytes. Successfully downloaded t10k-labels-idx1-ubyte.gz 4542 bytes. Extracting data/train-images-idx3-ubyte.gz Extracting data/train-labels-idx1-ubyte.gz Extracting data/t10k-images-idx3-ubyte.gz Extracting data/t10k-labels-idx1-ubyte.gz I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:925] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero I tensorflow/core/common_runtime/gpu/gpu_init.cc:102] Found device 0 with properties: name: GRID K520 major: 3 minor: 0 memoryClockRate (GHz) 0.797 pciBusID 0000:00:03.0 Total memory: 3.94GiB Free memory: 3.91GiB I tensorflow/core/common_runtime/gpu/gpu_init.cc:126] DMA: 0 I tensorflow/core/common_runtime/gpu/gpu_init.cc:136] 0: Y I tensorflow/core/common_runtime/gpu/gpu_device.cc:838] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GRID K520, pci bus id: 0000:00:03.0) Initialized! Step 0 (epoch 0.00), 10.7 ms Minibatch loss: 12.054, learning rate: 0.010000 Minibatch error: 90.6% Validation error: 84.6% (以下略)
ちゃんとGPUで処理できていることが確認できた。
また以下のように実行するとjupyter notebookが起動し、http://[EC2のパブリックIP]:8888でコンテナにアクセスできる。
$ sudo nvidia-docker run -d -p 8888:8888 -e PASSWORD=[パスワード] kashitan/tensorflow:latest /run_jupyter.sh
TensorFlow for Rイメージの作成
上記で作成したDockerイメージを元にTensorFlow for Rイメージを作成する。Dockerfileは以下の通り。RStudio-Serverにログインするためのcentosユーザーを追加している。またdevtools::install_github("rstudio/tensorflow")
で/usr/lib64/libpython3.4.soが見つからずエラーとなるのでワークアラウンドとしてシンボリックリンクを作成している。
nvidia-docker上でTensorFlow for Rを実行するDockerfile
上記のDockerfileを元にDockerイメージを作成する。
$ sudo nvidia-docker build -f ./Dockerfile.rstudio --build-arg PASSWORD=[centosユーザーのパスワード] -t ai_team/tensorflow:rstudio --no-cache=true .
以下のように実行するとRStudio-Serverが起動し、http://[EC2のパブリックIP]:8787でコンテナにアクセスできる。
# コンテナを起動 $ sudo nvidia-docker run -it --rm -p 8787:8787 kashitan/tensorflow:rstudio /bin/bash # コンテナ上でRStudio-Serverを起動 $ /etc/init.d/rstudio-server start Starting rstudio-server: [ OK ]
TensorFlow for Rのインストール&確認
あとはGitHub - rstudio/tensorflow: TensorFlow for Rに従ってRのパッケージをインストールするだけ。
install.packages("devtools") library(devtools) Sys.setenv(TENSORFLOW_PYTHON_VERSION = 3) devtools::install_github("rstudio/tensorflow")
ちゃんとCUDAが読み込めていることも確認できた。
> library(tensorflow) I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcublas.so locally I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcudnn.so locally I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcufft.so locally I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcuda.so.1 locally I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcurand.so locally > sess = tf$Session() I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:925] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero I tensorflow/core/common_runtime/gpu/gpu_init.cc:102] Found device 0 with properties: name: GRID K520 major: 3 minor: 0 memoryClockRate (GHz) 0.797 pciBusID 0000:00:03.0 Total memory: 3.94GiB Free memory: 3.91GiB I tensorflow/core/common_runtime/gpu/gpu_init.cc:126] DMA: 0 I tensorflow/core/common_runtime/gpu/gpu_init.cc:136] 0: Y I tensorflow/core/common_runtime/gpu/gpu_device.cc:838] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GRID K520, pci bus id: 0000:00:03.0) > hello <- tf$constant('Hello, TensorFlow!') > sess$run(hello) b'Hello, TensorFlow!' >
以下のTweetにもあるようにgithub上のアクティビティはTensorFlowが一番活発で、最近の論文のリファレンス実行もtorchかTensorFlowが多いとか。
The state of the deep learning frameworks landscape, September 2016. Keras 2nd fastest growing framework after TF. pic.twitter.com/3xnQNuP8fu
— François Chollet (@fchollet) 2016年9月15日
ちょうどTensorFlowの解説書も発売されたので勉強してみる。
TensorFlowで学ぶディープラーニング入門 ~畳み込みニューラルネットワーク徹底解説~
- 作者: 中井悦司
- 出版社/メーカー: マイナビ出版
- 発売日: 2016/09/27
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
以下MNIST For ML Beginnersを実行した結果。
# ライブラリの読み込みとMNISTデータセットのロード > library(tensorflow) > datasets <- tf$contrib$learn$datasets > mnist <- datasets$mnist$read_data_sets("MNIST-data", one_hot = TRUE) > str(mnist) List of 3 $ train : $ validation: $ test : > > x <- tf$placeholder(tf$float32, shape(NULL, 784L)) > > # ウエイト > W <- tf$Variable(tf$zeros(shape(784L, 10L))) > > # バイアス > b <- tf$Variable(tf$zeros(shape(10L))) > > # softmax関数 > y <- tf$nn$softmax(tf$matmul(x, W) + b) > > # 正解データを格納するためのプレースホルダ > y_ <- tf$placeholder(tf$float32, shape(NULL, 10L)) > > # Cross Entropy関数の定義 > cross_entropy <- tf$reduce_mean(-tf$reduce_sum(y_ * tf$log(y), reduction_indices=1L)) > > # オプティマイザの設定 > optimizer <- tf$train$GradientDescentOptimizer(0.5) > train_step <- optimizer$minimize(cross_entropy) > > # 初期化 > init <- tf$initialize_all_variables() > sess <- tf$Session() I tensorflow/core/common_runtime/gpu/gpu_device.cc:838] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GRID K520, pci bus id: 0000:00:03.0) > sess$run(init) > > # 学習の実行 > for (i in 1:1000) { + batches <- mnist$train$next_batch(100L) + batch_xs <- batches[[1]] + batch_ys <- batches[[2]] + sess$run(train_step, + feed_dict = dict(x = batch_xs, y_ = batch_ys)) + } > > # モデルの評価 > correct_prediction <- tf$equal(tf$argmax(y, 1L), tf$argmax(y_, 1L)) > accuracy <- tf$reduce_mean(tf$cast(correct_prediction, tf$float32)) > sess$run(accuracy, feed_dict=dict(x = mnist$test$images, y_ = mnist$test$labels)) [1] 0.9218001 >
Deep MNIST for Expertsを見る限りCNNも簡単に定義できそうだけどmxnetの方が記述は少なくて済みそう。。。