はじめに
前回の記事でCUDAおよびCuDNNを自分でインストールする手法を紹介しましたが、Dockerを使うとさらに簡単にディープラーニング環境を構築できます。
さらに、簡単に使えるだけではなく、複数のバージョンやフレームワークを共存させるときにも便利です。
書き終えたときにこんなすばらしい投稿を発見し、これ自体の価値はなくなってしまいましたが、自分用のメモということで公開します。
OS:ubuntu 14.04
準備
AWSのP2インスタンスを立てた後に色々インストールします。
sudo apt-get update -y
sudo apt-get upgrade -y
sudo apt-get install -y build-essential git python-pip python-dev libxml2-dev libxslt1-dev zlib1g-dev libcurl4-openssl-dev libatlas-base-dev linux-image-extra-virtual libopencv-dev python-numpy
sudo apt-get autoremove -y
ホスト側のドライバを無効にする
sudo vi /etc/modprobe.d/blacklist-nouveau.conf
を実行
blacklist nouveau
blacklist lbm-nouveau
options nouveau modeset=0
alias nouveau off
alias lbm-nouveau off
再起動をする
echo options nouveau modeset=0 | sudo tee -a /etc/modprobe.d/nouveau-kms.conf
sudo update-initramfs -u
sudo reboot
nvidia-driverのインストール
事前にGPUに適合するドライバを調べておく
P2インスタンスのGPUはK80
sudo apt-get install -y linux-source
sudo apt-get install -y linux-headers-`uname -r`
wget http://us.download.nvidia.com/XFree86/Linux-x86_64/352.99/NVIDIA-Linux-x86_64-352.99.run
sudo chmod +x NVIDIA-Linux-x86_64-352.99.run
sudo ./NVIDIA-Linux-x86_64-352.99.run
nvidia-dockerのインストール
ここからが肝です。
Dockerは仮想化技術の1つで、コンテナ型と呼ばれます。これは、仮想マシンごとにゲストOSが必要でハードウェアリソースの一部を占有するハイパーバイザ型と異なり、1つのOS上で実行することができるので、オーバーヘッドを少なくすることができます。Dockerはコンテナを管理するためのエンジンで、コンテナはアプリケーション単位で独立させることができるので、バージョン違いの複数バージョンのライブラリを動かすことができます。
以上、"Dockerとは" とググると出てくるような情報でした。
いつかDockerに関する記事もかけたらいいな、と思います。
コンテナとホストはファイルやデバイスを共有させることもできるので、Dockerのコンテナを立ち上げ、そこからホストのGPUにアクセスできるようにします。
まず、Dockerをインストールします。
curl -fsSL https://get.docker.com/ | sh
Dockerはsudo権限が必要なので、ユーザをdockerグループに加えます。
sudo groupadd docker
sudo gpasswd -a $USER docker
# exitして再ログインすると反映される。
sudo systemctl restart docker
exit
次にnvidia-dockerをインストールします。
自力でdockerの--device
オプションを用いて実行することも可能であるのですが、nvidia-dockerはそれらの処理のラッパーのような役割を担ってくれるので非常に便利です。
インストールは上記GitHubページを参考に実行します。
# Install nvidia-docker and nvidia-docker-plugin
wget -P /tmp https://github.com/NVIDIA/nvidia-docker/releases/download/v1.0.0-rc.3/nvidia-docker_1.0.0.rc.3-1_amd64.deb
sudo dpkg -i /tmp/nvidia-docker*.deb && rm /tmp/nvidia-docker*.deb
次にテストします。
nvidia-docker run --rm nvidia/cuda:7.5 nvidia-smi
やっていることとしては、nvidia/cudaイメージをダウンロードして、コンテナを立ち上げてnvidia-smi
コマンドを実行しています。
GPU情報が出たらOKです。
caffeのDockerイメージを作成
Dockerはイメージを作成して、それをコンテナとして起動、というような流れで利用します。
Docker Hub等からダウンロードして使うことができます。(さきほどのテストイメージはこれを利用)
一方自分でイメージを作成する場合はDockerfileを作成してビルドするのがおすすめです。
これは
- ベースのイメージに何を使うか
- どんなSWをインストールするか
- 起動時のデフォルトコマンドは何か
といった情報をコードで記述することができるため、バージョン管理や何をしているかの確認が容易になります。
CaffeのGithubレポジトリにはすでにCaffeイメージ用のDockerfileが用意されているため、そちらを使います。
git clone https://github.com/BVLC/caffe.git
cd caffe/docker
docker build -t caffe:gpu standalone/gpu
ビルドには結構時間がかかります。
Dockerファイルはここなのですが、やっていることとしては
- ベースイメージとしてCUDA7.5およびCuDNN5が入っているものを利用。つまりこれらのインストールが不要!
-
apt-get
でもろもろインストール - /opt/caffeに移動し、Caffeのビルド
- パスを通す
という感じです。
テスト
それでは最後にテストしてみましょう。
nvidia-docker run -it caffe:gpu
これで作成したCaffeのコンテナを起動し、コンテナ上でBashが使える状況です。
あとはよくあるmnistのサンプルを実行します。
cd /opt/caffe/
./data/mnist/get_mnist.sh
./examples/mnist/create_mnist.sh
./examples/mnist/train_lenet.sh
ちゃんとジョブが実行されますね!
その他
上記テストだとコンテナを落とした後結果が残りません。
--volume
でホストとコンテナのボリュームを共有させるなり、docker cp
でコピーするなりしましょう。