Python
Linux
機械学習
DeepLearning
docker

最短で作るローカルのディープラーニングGPU環境

はじめに

ディープラーニングの学習を実行するにはGPUはほぼ必須ですが、GPUを使用するにはNVIDIAドライバー、CUDAなど色々とインストールする必要があります。
この作業はバージョンの組み合わせやインストール方法で結構ハマることが多いようです。

ubuntu-drivers と NVIDIA Docker を使えばこれらを簡単にインストールできます。

環境

ディープラーニングでGPUを使用するのに必要なもの

  • NVIDIAドライバー
    • LinuxでNVIDIAグラフィックカードのGPUを認識させるのに必要
  • CUDA
    • NVIDIAが開発・提供している、GPU向けの汎用並列コンピューティングプラットフォーム
  • cuDNN
    • NVIDIAが公開しているDeep Learning用のライブラリ
  • CuPy
    • PythonからGPUを使用するためのモジュール
    • 他にもNumba,PyCudaなどがある

使うもの

  • ubuntu-drivers
    • Ubuntu 18.04 LTS から追加された(?)コマンド
    • NVIDIAドライバーのインストールが簡単に行える
  • NVIDIA Docker
    • DockerコンテナでGPUを使うためのツール
  • nvidia/cuda
    • CUDA/cuDNNがインストール済みのDockerイメージ
  • cupy/cupy
    • nvidia/cudaをベースにPythonとCuPyを追加したDockerイメージ

手順

  1. NVIDIAドライバーのインストール
  2. Docker CE のインストール
  3. Docker Compose のインストール
  4. NVIDIA Docker のインストール
  5. Dockerコンテナの作成

1. NVIDIAドライバーのインストール

ubuntu-driversを使用します。

https://linuxconfig.org/how-to-install-the-nvidia-drivers-on-ubuntu-18-04-bionic-beaver-linux

Ubuntu 18.04 LTS 日本語 Remixを通常インストールしていればubuntu-driversは入っていますが、ない場合はaptでインストールします。

sudo apt install ubuntu-drivers-common

あとは以下のコマンドだけでNVIDIAドライバーがインストールできます。

sudo ubuntu-drivers autoinstall

2. Docker CE のインストール

公式ドキュメントの通りインストールします。

https://docs.docker.com/install/linux/docker-ce/ubuntu/#install-docker-ce

一応コマンドを貼り付けておきます。

sudo apt-get update
sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
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

最後にユーザーをDockerグループに追加します。

sudo usermod -aG docker $USER

注意点
Ubuntuではaptdocker.ioというのがインストール可能ですが、こちらでは NVIDIA Docker がインストールできなくなります。必ずDocker CEをインストールしてください。

3. Docker Compose のインストール

こちらも公式ドキュメントの通りインストールします。

https://docs.docker.com/compose/install/#install-compose

sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

4. NVIDIA Docker のインストール

公式ドキュメントの通りインストールします。

https://github.com/NVIDIA/nvidia-docker#ubuntu-140416041804-debian-jessiestretch

# Add the package repositories
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

# Install nvidia-docker2 and reload the Docker daemon configuration
sudo apt-get install -y nvidia-docker2
sudo pkill -SIGHUP dockerd

# Test nvidia-smi with the latest official CUDA image
docker run --runtime=nvidia --rm nvidia/cuda nvidia-smi

5. Dockerコンテナの作成

こちらの記事が参考になります。

nvidia-dockerでGPUコンテナの作成 - Qiita

GPUを使うコンテナのベースイメージは nvidia/cuda になりますが、Pythonは含まれていないので自分でインストールする必要があります。
PythonでCuPyを使うのであれば cupy/cupyがいいでしょう。
こちらはPython2とPython3がインストール済みのイメージがそれぞれ用意されています。

Chainerで作る コンテンツ自動生成AIプログラミング入門

最後に、「Chainerで作る コンテンツ自動生成AIプログラミング入門」という書籍のサンプルコードを動かす環境のDockerfileを書いたので載せておきます。

Dockerfile
FROM cupy/cupy:latest-python3

RUN apt update -y && \
    apt install -y --no-install-recommends \
    wget \
    gdal-bin \
    mecab \
    mecab-ipadic-utf8

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

RUN pip3 install --no-cache-dir \
    pillow \
    h5py \
    chainer
docker-compose.yml
version: '2.3'

services:
  app:
    build: .
    runtime: nvidia
    volumes:
      - ./:/usr/src/app/

実行方法

上記ファイルとサンプルコードを同じディレクトリに配置します。

ファイル構成
project/
    Dockerfile
    docker-compose.yml
    sample/

Dockerイメージをビルドします。

cd project
docker-compose build

コンテナを実行してシェルを起動します。

docker-compose run --rm app bash

以下はコンテナ内のシェルで実行します。

root@7edd84542481:/usr/src/app# cd sample/chapt02
root@7edd84542481:/usr/src/app/sample/chapt02# python3 chapt02-1.py
Downloading from http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz...
Downloading from http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz...
Downloading from http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz...
Downloading from http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz...

root@7edd84542481:/usr/src/app/sample/chapt02# python3 chapt02-2.py 
0   0.9999981
1   2.981141e-15
2   1.2600368e-06
3   9.146645e-10
4   7.1973303e-13
5   8.957497e-09
6   5.611625e-07
7   1.8054458e-10
8   1.08702736e-07
9   1.4337494e-10

GPUとCPUでパフォーマンス比較

書籍のサンプルコードは以下のようになっていて、uses_device = -1とするとGPUを使用しない動作になります。

uses_device = 0                # GPU#0を使用
if uses_device >= 0:
    # GPUを使う
    :
    # GPU用データ形式に変換
    :

GPUを使用する場合(uses_device=0)とCPUを使用する場合(uses_device=-1)で実行時間を比較してみます。

GPUを使用する場合(uses_device=0)
root@7edd84542481:/usr/src/app/sample/chapt03# python3 chapt03-2.py
     total [..................................................]  0.04%
this epoch [##################................................] 37.61%
      2100 iter, 4 epoch / 10000 epochs
    70.473 iters/sec. Estimated time to finish: 18:54:24.318379.
CPUを使用する場合(uses_device=-1)
root@7edd84542481:/usr/src/app/sample/chapt03# python3 chapt03-2.py
     total [..................................................]  0.00%
this epoch [####################..............................] 41.68%
       200 iter, 0 epoch / 10000 epochs
    4.2248 iters/sec. Estimated time to finish: 13 days, 3:30:25.476065.
ソース CPU GPU 比較
chapt02-1.py 100s 83s 1.2倍
chapt03-1.py 315h 19h 16倍
chapt04-1.py 111h 3h21m 33倍
chapt06-3.py 33m 8m 4倍

GeForce GTX 960 は2年前にゲーム用に購入したミドルレンジのグラボですが、それでもこれだけの差が出ました。