taka5hi’s blog

統計と機械学習の話題をメインに記事を書いています。

Ubuntu 18.04 に NVIDIA Docker をインストール

今年の初めに自宅の Deep Learning 用環境を壊してしまいました。
原因は、不用意に Python モジュールのバージョンを変更してしまったことなんですが、なんだかんだで復旧に数時間かかってしまいました。
この経験から、Deep Learning 環境を Docker 化することを決意しました。
Docker で GPU を扱ったことがなかったのですが、NVIDIA Docker を使うことで対応できるようです。

今回は、Ubuntu 18.04 環境に NVIDIA Docker を使って TensorFlow 環境を用意しますが、CUDA を使うような環境なら基本的な流れは同じなので参考にできるかと思います。

NVIDIA Docker とは

Docker コンテナ内から CUDA を扱えるようにする仕組みです。
上記のプロジェクトの README.md を見ると、コンテナ内にインストールされた CUDA とホストマシンにインストールされている GPU をやり取りさせる仕組みのようです。

NVIDIA Docker が登場する前は、コンテナ内から GPU を扱うためには、ホスト側の GPUバイスファイルをコンテナに渡すみたいなことが必要だったとのこと。
ホストとコンテナでインストールするドライバーに依存関係が発生するため、ポータビリティが損なわれることになります。(GPU 対応した汎用的な Docker イメージを作成・公開できないということにもつながります。)
結果、Docker の利点を大きく損なうことにならざるおえないことに。

一方、NVIDIA Docker を使うと、この点が解決され、GPU 対応済みのポータブルな Docker イメージが作れるようになります。
実際に Docker Hub などで公開されている GPU 対応のイメージを使うことで、環境のメンテコストをかなり抑えることができます。

作業の流れ

NVIDIA Docker をセットアップ手順は以下の通りです。

  1. CUDA、NVIDIA Driver インストール
  2. Docker インストール
  3. NVIDIA Docker インストール

あとは Docker Hub などで公開されている TensorFlow をセットアップ済みの Docker イメージを利用するだけです。

ちなみに、Docker を使わずに環境を用意する場合の手順は下記の通りです。

  1. CUDA、NVIDIA Driver インストール
  2. cuDNN インストール
  3. Python インストール
  4. TensorFlow インストール

手順を並べただけでは、あまり楽になってはいないようにも感じます。
しかし、pip パッケージで用意されている TensorFlow (GPU 対応版である tensorflow-gpu) と CUDA のバージョンに依存関係があるため、若干気を使う必要があります。
また、環境を壊してしまった際の復旧やアップデートを考えると圧倒的に Docker を使う方が有利です。

以下では、NVIDIA Dcoker を導入する手順を説明します。

NVIDIA Docker のインストール

1. CUDA、NVIDIA Driver インストール

基本的に、NVIDIA が公開する CUDA のインストール方法に従えば大丈夫です。
また、NVIDIA ドライバーは、CUDA をインストールする際に対応するバージョンのものが自動的に入ります。(CUDA と NVIDIA のドライバーにもバージョン依存があるので、CUDA と NVIDIA ドライバーを別々に入れることはお勧めしません。)
以下の例は、CUDA 10.0 をインストールする際のコマンドになっています。

古いドライバーなどを入れているとうまく動かない可能性があるので、一度きれいにしておきます。

$ sudo apt-get purge nvidia*
$ sudo apt-get autoremove
$ sudo apt-get autoclean
$ sudo rm -rf /usr/local/cuda*

下記のページの手順にしたがってドライバーをインストールします。

$ wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-repo-ubuntu1804_10.0.130-1_amd64.deb
$ sudo dpkg -i cuda-repo-ubuntu1804_10.0.130-1_amd64.deb
$ sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub
$ sudo apt-get update
$ sudo apt-get install cuda

一度、再起動をします。

$ sudo shutdown -h now

PATH などの設定を行います。

$ echo 'export PATH=/usr/local/cuda-10.0/bin${PATH:+:${PATH}}' >> ~/.bashrc
$ echo 'export LD_LIBRARY_PATH=/usr/local/cuda-10.0/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}' >> ~/.bashrc

$ source ~/.bashrc
$ sudo ldconfig

補足:
下記の README.md に書いてある図を見ると、ホスト環境には cuda-driver だけをいれればよいようにも読み取れるのですが、不安だったので CUDA ごとインストールするようにしました。

2. Docker インストール

下記の手順に従ってください。

# 古いバージョンを削除
$ sudo apt-get remove docker docker-engine docker.io containerd runc
# パッケージの更新
$ sudo apt-get update
# 必要なパッケージをインストール
$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg2 \
    software-properties-common
# GPG key の追加
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 追加したキーの確認
$ sudo apt-key fingerprint 0EBFCD88

次にリポジトリの登録を行いますが PC のアーキテクチャーごとにリポジトリが異なるので、手順のリンク先を確認してください。
x86_64 では下記の通りです。

$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

本体のインストールします。

$ sudo apt-get update
$ sudo apt-get install docker-ce

インストールできたか確認します。
下記のコマンドでエラーが出なければ OK です。

$ sudo docker run hello-world

sudo なしで使う定番設定も入れておくとよいでしょう。

$ sudo usermod -aG docker $USER

3. NVIDIA Docker インストール

まずは、リポジトリの設定を下記に沿って行います。(Debian-based distributions の手順を参考に)

# リポジトリ設定
$ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | \
  sudo apt-key add -
$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
$ curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \
  sudo tee /etc/apt/sources.list.d/nvidia-docker.list
$ sudo apt-get update
# Key の追加
$ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | \
  sudo apt-key add -

次は下記にしたがってインストールします。(Ubuntu distributions の手順を参考に)

# 古いバージョンの削除
$ docker volume ls -q -f driver=nvidia-docker | xargs -r -I{} -n1 docker ps -q -a -f volume={} | xargs -r docker rm -f
$ sudo apt-get purge nvidia-docker
# インストール
$ sudo apt-get install nvidia-docker2
$ sudo pkill -SIGHUP dockerd

インストールできたことの確認します。
nvidia-smi の出力結果が表示されれば、コンテナ内から GPU が認識できています。

docker run --runtime=nvidia --rm nvidia/cuda nvidia-smi

以上でセットアップは終わりです。
あとは、公開されている Docker イメージを使うだけです。

NVIDIA Docker を使う

Docker Hub で公開されている tensorflow/tensorflow を使う場合、下記のコマンドを実行するだけです。
タグで GPU 対応のイメージを指定しています。

nvidia-docker run -it -p 8888:8888 tensorflow/tensorflow:latest-gpu-py3

このイメージでは、Jupyter notebook もセットアップされており、上記のコマンドの場合、ホストの 8888 port でバインドされます。
また、-v オプションを使って /notebooks 配下にボリュームをマウントすれば、マウントしたディレクトリでJupyter notebook が起動します。

nvidia-docker run -it -p 8888:8888 -v <host dir>:/notebooks tensorflow/tensorflow:latest-gpu-py3

ここまで来てしまえば、あとは普通に Docker の知識で行けるので、足りないモジュールを追加して自分用の Docker イメージをビルドしたりも自由にできます。

利用できる Docker イメージ

最後に、公開されている GPU 対応がされた Docker イメージです。あくまで自分が直近で使いそうなもののみを集めただけなので、まだまだたくさんあると思います。

Docker Hub

NVIDIA GPU CLOUD

NVIDIA が公開している Docker レジストリです。
無料の会員登録が必要ですが、いろんなフレームワーク向けの Docker イメージが公開されています。

まとめ

ほぼほぼ公開されているインストール手順に従ってすすめるだけで無事にセットアップできてしまいました。
これだけの作業で、今後環境の再構築やアップデートにかかるコストが格段に下げられるというのは本当にありがたいことだと思います。
たとえ環境を壊してしまっても、すぐに構築しなおせるというのは、いろんなことを試す際の精神的なハードルを下げることにもつながりますし、本当におすすめです。