日々の学びと煩悩

はじめてのUbuntu Docker導入 [七転八倒記]

これ何

Ubutu何?状態の人間がUbuntuでDocker環境を構築し機械学習を行うまでの備忘録

2020年5月時点での公式ドキュメント

matsuand.github.io

かなり丁寧です

必要なもの
https://github.com/NVIDIA/nvidia-docker/wiki/Installation-(Native-GPU-Support)

  • (当たり前) GNU/Linux x86_64 with kernel version > 3.10:LinuxのOS
  • (当たり前) NVIDIA GPU with Architecture > Fermi (2.1): つまりGPUバイスそのもの
  • NVIDIA drivers ~= 361.93 (untested on older versions): NVIDIA® GPU ドライバ
  • Docker >= 19.03
  • NVIDIA Container Toolkit: DockerのNVIDIA® GPU サポート.DockerとNVIDIAのドライバーがインストールされていることが必要.

手順

目標:研究室にあるGPU付きのUbuntuデスクトップに,Docker環境を構築してGPUを接続し,Jupyter Notebook上で動きを確認する

  1. 現状の確認
  2. Dockerをインストール
  3. nvidia-container-toolkitのインストール
  4. Dockerを起動

なぜDockerか

地道な環境構築で必要なもの

  • NVIDIA製のGPU
  • NIVIDA Driver
  • CUDA: GPUアプリケーション開発環境 (低レベルなプログラミング言語の実行環境) を提供する
  • cuDNN:DNN のためのプリミティブな GPU-accelerated library
  • TensorFlow(GPU版)
  • Keras

地道にGPUを認識するには,ensorflow, Cuda, cuDNNの各バージョンを全て合わせる必要がある。基本的に、tensorflowのバージョンを最初に決めたあと、その他のバージョンを決定する.

https://www.tensorflow.org/install/source#tested_build_configurations

Dockerを使うことでドライバしか必要ないため,互換性を考えなくて済むのが魅力的....

現状,インターネット上での情報はまだまだ上記のやり方が多くて,互換性に苦労している話が多い.

そう,何を隠そう私もそれで挫折した者の1人なので,潔くDockerに乗り換えることにした次第です.

Tensorflow公式サイトより

Docker を使用すると、ホストマシンに必要なのは NVIDIA® GPU ドライバだけになるので、GPU 上で TensorFlow を実行する際の最も簡単な方法となります(NVIDIA® CUDA® ツールキットは不要です)。

DockerでGPUサポートを使うには,追加でNVIDIA Container Toolkit をインストールする必要がある.

現状の確認

Dockerを導入するにはUbuntuは以下のいずれか,64-bitのバージョンであることが必要

# ubuntuのバージョン確認
$ cat /etc/os-release

NAME="Ubuntu"
VERSION="18.04.4 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.4 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic

# グラフィックボードとドライバーの確認
$ nvidia-smi
Fri May 15 01:18:25 2020       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 440.64.00    Driver Version: 440.64.00    CUDA Version: 10.2     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce GTX 108...  On   | 00000000:18:00.0 Off |                  N/A |
| 29%   30C    P8     8W / 250W |      1MiB / 11178MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  GeForce GTX 108...  On   | 00000000:3B:00.0 Off |                  N/A |
| 29%   31C    P8     9W / 250W |      1MiB / 11178MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   2  GeForce GTX 108...  On   | 00000000:86:00.0 Off |                  N/A |
| 20%   31C    P8     8W / 250W |      1MiB / 11178MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   3  GeForce GTX 108...  On   | 00000000:AF:00.0 Off |                  N/A |
| 29%   32C    P8     8W / 250W |      1MiB / 11178MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

Ubuntuデスクトップのバージョンは18.04で,
[GeForce GTX 1080 Ti]が4つ搭載されている. また,既にGPUのドライバーとCUDA Toolkit (バージョンは440) も一式インストールされている.

もしドライバーがなかった場合

  1. コマンドラインで最適なドライバを検索
  2. 公式サイトで確認する

2通りの方法がある.

$ ubuntu-drivers devices

== /sys/devices/pci0000:3a/0000:3a:00.0/0000:3b:00.0 ==
modalias : pci:v000010DEd00001B06sv00001043sd000085E5bc03sc00i00
vendor   : NVIDIA Corporation
model    : GP102 [GeForce GTX 1080 Ti]
driver   : nvidia-driver-415 - third-party free
driver   : nvidia-driver-410 - third-party free
driver   : nvidia-driver-435 - distro non-free
driver   : nvidia-driver-390 - distro non-free
driver   : nvidia-driver-418 - third-party free
driver   : nvidia-driver-440 - third-party free recommended
driver   : xserver-xorg-video-nouveau - distro free builtin

recommendedと記載されているやつをダウンロードする

でも,公式サイトだと f:id:wimper_1996:20200608050053p:plain f:id:wimper_1996:20200608050104p:plain

バージョン430がヒットした。440だとあまり情報がなかったので430のほうが良いかもしれない...

$ sudo apt-get install nvidia-driver-430

Dockerのインストール

HTTP経由で必要なパッケージをインストールする

# sudoは管理者権限でコマンドを実行するという意味

$ sudo apt-get update

$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common

Dockerの公式GPG keyを追加

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

OK

鍵を取得し、fingerprintが9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88であることを確認 最後の8文字0EBFCD88が一致していることを確認

$ sudo apt-key fingerprint 0EBFCD88
pub   rsa4096 2017-02-22 [SCEA]
      9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
uid           [  不明  ] Docker Release (CE deb) <docker@docker.com>
sub   rsa4096 2017-02-22 [S]

安定版(stable)リポジトリをセットアップする Ubuntuアーキテクチャを確認し、HPで対応するリポジトリのコマンドをコピーする

$ uname -a

Linux okadaken 5.3.0-51-generic #44~18.04.2-Ubuntu SMP Thu Apr 23 14:27:18 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

f:id:wimper_1996:20200608050606p:plain

つまり今回はx86_64 / amd64の部分のコマンドを選択すれば良い

そのままコピペ

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

DOCKER ENGINEのインストール
Dockerとcontainerdの最新版をインストール

$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io

Dockerコンテナの動作確認

$ sudo docker run hello-world

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete 
Digest: sha256:6a65f928fb91fcfbc963f7aa6d57c8eeb426ad9a20c7ee045538ef34847f44f1
Status: Downloaded newer image for hello-world:latest



Hello from Docker!
This message shows that your installation appears to be working correctly.



To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.



To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash



Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/



For more examples and ideas, visit:
https://docs.docker.com/get-started/

nvidia-container-toolkitのインストール

# Add the package repositories
$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
$ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | $ sudo apt-key add -
$ 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 && sudo apt-get install -y nvidia-container-toolkit
$ sudo systemctl restart docker

nvidia-dockerがインストールされたことを確認

$ sudo docker run --gpus all --rm nvidia/cuda nvidia-smi

Unable to find image 'nvidia/cuda:latest' locally
latest: Pulling from nvidia/cuda
7ddbc47eeb70: Pull complete 
c1bbdc448b72: Pull complete 
8c3b70e39044: Pull complete 
45d437916d57: Pull complete 
d8f1569ddae6: Pull complete 
85386706b020: Pull complete 
ee9b457b77d0: Pull complete 
be4f3343ecd3: Pull complete 
30b4effda4fd: Pull complete 
Digest: sha256:31e2a1ca7b0e1f678fb1dd0c985b4223273f7c0f3dbde60053b371e2a1aee2cd
Status: Downloaded newer image for nvidia/cuda:latest
Thu May 14 16:32:18 2020       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 440.64.00    Driver Version: 440.64.00    CUDA Version: 10.2     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce GTX 108...  On   | 00000000:18:00.0 Off |                  N/A |
| 29%   31C    P8     8W / 250W |      1MiB / 11178MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  GeForce GTX 108...  On   | 00000000:3B:00.0 Off |                  N/A |
| 29%   31C    P8     9W / 250W |      1MiB / 11178MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   2  GeForce GTX 108...  On   | 00000000:86:00.0 Off |                  N/A |
| 20%   32C    P8     8W / 250W |      1MiB / 11178MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   3  GeForce GTX 108...  On   | 00000000:AF:00.0 Off |                  N/A |
| 29%   32C    P8     8W / 250W |      1MiB / 11178MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

現状だとdockerコマンドの前に管理者権限のコマンドsudoが必要

$ sudo docker run ...

これをsudoなしでDockerコマンドを使えるようにする

$ sudo usermod -aG docker $USER
$ newgrp docker

ここまでがDockerの導入.お疲れ様でした....

ようやく次でDockerを導入.

dockerイメージのpull

www.tensorflow.org

gpuサポートかつ,Jupyterを含むイメージをpull*2

tensorflow / tensorflow: のように,カンマの後ろで様々なバージョンのイメージをpullすることができる.

$ docker pull tensorflow/tensorflow:latest-gpu-jupyter

ターミナルでgpuできちんと動くか確認

# 1行目がdockerのシェル内に入って実行,を表す
$ docker run --gpus all -it --rm tensorflow/tensorflow:latest-gpu-jupyter \
python -c "import tensorflow as tf; print(tf.reduce_sum(tf.random.normal([1000, 1000])))"

コンテナ内に入り,ターミナルを起動し,Jupyter Notebookを起動

$ docker run --gpus all -it tensorflow/tensorflow:latest-gpu-jupyter bash

$ jupyter notebook

Jupyter Notebook内でのチェック方法

from tensorflow.python.client import device_lib
device_lib.list_local_devices()

CPUしか認識されてなかったらこれしか表示されない....

[
name: "/device:CPU:0"
device_type: "CPU"
memory_limit: 2789133
locality {
}
]


注意事項 -> gpuを認識させるには docker runコマンドに --gpuオプションが必要.

以下のような定番のコマンドではない

$ docker run -it --rm tensorflow/tensorflow:latest-gpu-jupyter bash

19.03 より前のバージョンでは nvidia-docker2 と --runtime=nvidia フラグが必要です。19.03 以降のバージョンでは、nvidia-container-toolkit パッケージと --gpus all フラグが必要です。


お疲れ様でした自分.

*1:何言ってるのかよくわからない

*2:pullはDockerで使われる用語で,インストールと同じ意味と捉えてOK