nvidia-docker

ども〜古川です。

今回はnvidia-dockerについて書いてみようかと思います。

nvidia-dockerとは?

CUDAおよびcuDNNなどが梱包されたdockerコンテナイメージを使えるようにするためのツールです。

図のようにホストマシンのDriverを用意をしておけば、CUDAやcuDNNをつかったアプリをコンテナごとに管理できます! nvidia_docker.png

2016年7月時点ではrc版ですが、家のマシンで試したところ安定して使えそうだったので、今回を期に紹介します!

結局nvidia-dockerは何がおいしいの?

Deep Learningライブラリのバージョンが容易になる

ホストマシンにDeep Learningライブラリがある場合を想定してください。

not_use_nvidiadocker.png

Deep Learningライブラリをバージョンアップしたいときが起きますが、その場合、次の作業が必要になることがあります。

  • CUDAのバージョンアップ
  • cuDNNのバージョンアップ

この作業大変ですよね?(とくにCUDAはGB単位あるので、インストールとか非常に時間がかかります)。

また、バージョンアップ後何かしら不具合があったら、切り戻すのも大変ですよね(これを複数台やる必要があるのなら・・・

そこで、このツールでDeep Learningライブラリのバージョンごとにコンテナを管理しておくことで、バージョンの変更はコンテナを切り替えのみで対応できるので、非常に簡単になりますよね。

use_nvidia_docker.png

こういったところにかなりメリットはあるかと思います。

ただし、ドライバはホスト側のを使用するので、ドライバのアップデートは回避できませんのでご注意ください!

導入

導入環境

  • CPU: Core i7 6700K
  • メモリ:32GB
  • GPU: GTX980TI

  • OS: ubuntu 16.04 LTS

  • GPUドライバ:NVIDIA Driver ドライバ(バージョン360台)

docker engineのインストール

nvidia-dockerを使う場合、docker-engineが必要とのことなので、インストールしておきます

# 鍵追加
sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D

# リポジトリ追加
sudo vim /etc/apt/sources.list.d/docker.list

# 内容は次のようにする(ubuntuのバージョンによって内容が変わる)
deb https://apt.dockerproject.org/repo ubuntu-xenial main

# apt-getのアップデート
sudo apt-get update

# docker-engineのインストール
apt-cache policy docker-engine
sudo apt-get install docker-engine
sudo service docker start

nvidia-dockerのインストール

nvidia-dockerをソースからビルドします。 ビルドに成功すれば、/usr/bin/ディレクトリに、nvidia-dockerとnvidia-docker-pluginが作成されます。

git clone https://github.com/NVIDIA/nvidia-docker.git
cd nvidia-docker/
sudo make install
sudo nvidia-docker volume setup

使い方

tensorflow v0.9のコンテナを作り、使ってみる

適当な場所につぎのDockerfileを作ります。

FROM nvidia/cuda:7.5-cudnn4-runtime

RUN apt-get update
RUN apt-get install -y --no-install-recommends python-pip python-dev build-essential git

RUN pip install --upgrade https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.9.0-cp27-none-linux_x86_64.whl

# コンテナ容量節約のため
RUN rm -rf /var/lib/apt/lists/*

ENV LD_LIBRARY_PATH /usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH

# cuDNNの共有ライブラリが必要な位置にないため、シンボリックリンクを貼っている
RUN ln -s /usr/lib/x86_64-linux-gnu/libcudnn.so.4.0.7 /usr/lib/x86_64-linux-gnu/libcudnn.so

ENTRYPOINT ["/bin/bash"]

ここでポイントとなるのは、nvidia/cuda:7.5-cudnn4-runtimeコンテナを指定しているということです。 これを指定することで、CUDA7.5, cuDNN v4が入ったコンテナをベースに作っています。 つまり、CUDAおよびcuDNNのバージョンのコンテナはここで決めればよいということです!

つぎのことにしたがってこのコンテナを決めています。

  • tensorflowのビルド済みのpipパッケージを利用するには、CUDA 7.5 cuDNN v4にする必要があるからです。
    • それ以外はソースからビルドしなければいけません。
  • python版のtensorflowのみ使うということで、nvccは不要です。ということでruntimeの方を使用しています。
    • ただし、nvccが必要な場合はFROM nvidia/cuda:7.5-cudnn4-devel

このDockerfileを用いてイメージをビルドします。イメージ名はtensorflow:v0.9とします。

sudo nvidia-docker build -t tensorflow:v0.9 .

ビルド成功したら、コンテナを動かしてみますが、そのまえにコンテナとの共有ディレクトリ~/docker/shareを作成し、tensorflowサンプルコードをホストマシンの次の場所にいれておきます。こういうことしているのは、コンテナ上で実行した結果(モデルとか)はコンテナ上ではなく、ホストマシン上に格納したいためです。

mkdir -P ~/docker/share
cd ~/docker/share
git clone --depth=1 -b v0.8.0 https://github.com/tensorflow/tensorflow.git

このイメージを使いたい場合は、次のコマンドを打ちます。また-vオプションを入れることでホストマシンの~/docker/share/shareにマッピングしています。また、rwを指定することでコンテナからホストマシンへの書き込みを可能にしてます。

sudo nvidia-docker run -it -v ~/docker/share:/share:rw tensorflow:v0.9

注意: 間違ってもシステムファイルが含まれる場所(例えば, / など)をマッピングしてはいけません!これをするとコンテナ経由でホストマシン自体のデータにアクセスできてしまいます!

では実際にコンテナ上からサンプルコードを動かしてみます。

cd /share
time python tensorflow/examples/tutorials/mnist/fully_connected_feed.py

これで無事に動いたら、tensorflowのコンテナは完成です。

あとは必要に応じてコンテナさえ立ち上げれば使えるようになります!

chainer v1.10のコンテナを作り、使ってみる

つぎはchainerのコンテナを作ってみます!

適当な場所につぎのDockerfileを作ります。tensorflowと違う場所で作ってください!

FROM nvidia/cuda:7.5-cudnn4-devel

RUN apt-get update
RUN apt-get install -y --no-install-recommends python-pip python-dev build-essential git libhdf5-dev zlib1g-dev

RUN pip install numpy==1.11

RUN pip install h5py

ENV CUDA_PATH /usr/local/cuda

RUN pip install chainer==1.10

# コンテナ容量節約のため
RUN rm -rf /var/lib/apt/lists/*

ENV LD_LIBRARY_PATH /usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH

ENTRYPOINT ["/bin/bash"]

chainerでGPU版を使用したい場合はnvccも必要になってくるので、ベースとなるコンテナはnvidia/cuda:7.5-cudnn4-develにしました。nvidia/cuda:7.5-cudnn4-runtimeだとGPUが使えませんでした。

このDockerfileがかけたらこれを用いてイメージをビルドします。イメージ名はchainer:v1.10とします。設定内容はtensorflowと同様です。

sudo nvidia-docker build -t chainer:v1.10 .

tensorflowのときと同じように、コンテナとの共有ディレクトリ~/docker/shareにchainerのサンプルコードを入れときましょう!

cd ~/docker/share
wget https://github.com/pfnet/chainer/archive/v1.10.0.tar.gz
tar xzf v1.10.0.tar.gz
rm v1.10.0.tar.gz

では、コンテナを起動させましょう!

sudo nvidia-docker run -it -v ~/docker/share:/share:rw chainer:v1.10

コンテナ上に入れたら次のコマンドでmnistサンプルを動かしてみましょう!

cd /share
python chainer-1.10.0/examples/mnist/train_mnist.py --gpu=0

エラーがなく動けば、GPU版chainerを使うコンテナは完成です。

まとめ・所感

tensorflowとchainerを題材にnvidia-dockerでコンテナの作り方を紹介しました!

正直CUDAとcuDNNを入れるの大変でしたし、バージョン変えるだけでも色々大変だったので、このツールがあるのはすごく助かりました!

ディープラーニング系のライブラリはまだ枯れていない技術であり、頻繁に更新されると思います!

そういったライブラリとうまく付き合うための一つの手段として利用するといいと思います!