ディープラーニング用のGPU Dockerサーバーを作る

#はじめに

最近、機械学習の勉強をしていて問題になるのが開発環境。Pythonの依存関係なども複雑で、環境構築や動かすまで一苦労する事が多く作っては壊せる環境が欲しくなります。AWSでGPUインスタンスを立ち上げるほどではないけど、GPUを使える環境が欲しい。Google Colabも便利だけど、実際に実行環境の構築部分も気になります。某所ではDGX-Stationを買ったりと景気の良い話もあるけれど、とてもそんな予算請求できません...。

という事でゲーミングPCをベースにしてnvidia-dockerでディープラーニング用の開発環境を構築しました。

#前提

予算：15万円 
目的：nvidia-dockerが動く環境
環境：Ubuntu

スペック予定

+ NVIDIA GTX or RTX
+ Core i7 
+ SSD 500Gくらい 

OS不要！

※前にWindows10のゲーミングPCを機械学習目的で購入したけどサクサクで便利過ぎて、環境を壊したくなくなったがそもそものキッカケ。

#ハード構成

上をみたらキリがないので予算を１５万として検討。１０万くらいで買えるGTX1050ノートも考えましたが、常時ONが前提なので省スペースデスクトップをツクモでBTOする事にしました。

[G-GEAR mini GI7J-C190/T](https://www.tsukumo.co.jp/bto/pc/game/mini/2019/GI7J-C190T.html)
Corei7-8700(6Core HT 3.2GHz) / OS無し / 32GB / GeForce RTX2060
SSD 500GB + HDD 2TB（無償アップグレード）

という構成で、本体税抜き15.5万でした（ギリ）。DVDドライブベイが無く高さが低いケースなので足元にも置きやすいです。メモリーを（少しBTO価格は高い気がしますが）多めにしておきました。ストレージはキャンペーンで２倍だったので、ちょうど良いくらいですね。

どうせ買うならということで、GPUはTensorコアがついているRTX2060にしました。また、（過去の経験から）無用なトラブルを回避するためになんとなくRayzenは避けました。

予定納期より１日短く４日で届きました♪

<img width="512" alt="IMG_4987.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14768/72d2ab95-ec96-2826-96ca-fe507c80fbe7.jpeg">

参考：小さくても速い!!　コンパクトゲーミングPC「G-GEAR mini」の実力を試す (1/2)
https://www.itmedia.co.jp/pcuser/articles/1510/23/news078.html

#環境構築

## OSインストール

ここはサクッとUbuntu Desktop 18.04.02 LTSをインストールします。USB起動でインストールしました。このあたりはごく普通なので省略します。SSD側をOSのメインドライブ、HDDをデータとして使う予定です。

メモ：19.04を試しに入れてみたらさくっとNVIDIAのカードを認識していましたので将来的には次からの環境構築の半分は不要になりそうな気がします。

## OSアップデート

お約束でインストール後はupdate & upgradeをしておきます。

```
sudo apt update
sudo apt upgrade
sudo apt install net-tools ssh
```

## NVIDIAドライバーのレポジトリー追加

```sudo add-apt-repository ppa:graphics-drivers/ppa```

一応ずらずらでます。たぶん読み飛ばしOK。実行結果は少し変わるかと思います。

```
$ sudo add-apt-repository ppa:graphics-drivers/ppa
 Fresh drivers from upstream, currently shipping Nvidia.
## Current Status
Current long-lived branch release: `nvidia-410` (410.66)
Dropped support for Fermi series (https://nvidia.custhelp.com/app/answers/detail/a_id/4656)
Old long-lived branch release: `nvidia-390` (390.87)
For GF1xx GPUs use `nvidia-390` (390.87)
For G8x, G9x and GT2xx GPUs use `nvidia-340` (340.107)
For NV4x and G7x GPUs use `nvidia-304` (304.137) End-Of-Life!
Support timeframes for Unix legacy GPU releases:
https://nvidia.custhelp.com/app/answers/detail/a_id/3142
## What we're working on right now:
- Normal driver updates
- Help Wanted: Mesa Updates for Intel/AMD users, ping us if you want to help do this work, we're shorthanded.
## WARNINGS:
This PPA is currently in testing, you should be experienced with packaging before you dive in here:
Volunteers welcome!
### How you can help:
## Install PTS and benchmark your gear:
    sudo apt-get install phoronix-test-suite
Run the benchmark:
    phoronix-test-suite default-benchmark openarena xonotic tesseract gputest unigine-valley
and then say yes when it asks you to submit your results to openbechmarking.org. Then grab a cup of coffee, it takes a bit for the benchmarks to run. Depending on the version of Ubuntu you're using it might preferable for you to grabs PTS from upstream directly: http://www.phoronix-test-suite.com/?k=downloads
## Share your results with the community:
Post a link to your results (or any other feedback to): https://launchpad.net/~graphics-drivers-testers
Remember to rerun and resubmit the benchmarks after driver upgrades, this will allow us to gather a bunch of data on performance that we can share with everybody.
If you run into old documentation referring to other PPAs, you can help us by consolidating references to this PPA.
If someone wants to go ahead and start prototyping on `software-properties-gtk` on what the GUI should look like, please start hacking!
## Help us Help You!
We use the donation funds to get the developers hardware to test and upload these drivers, please consider donating to the "community" slider on the donation page if you're loving this PPA:
http://www.ubuntu.com/download/desktop/contribute
 More info: https://launchpad.net/~graphics-drivers/+archive/ubuntu/ppa
Press [ENTER] to continue or Ctrl-c to cancel adding it.
Hit:1 http://jp.archive.ubuntu.com/ubuntu bionic InRelease
Hit:2 http://jp.archive.ubuntu.com/ubuntu bionic-updates InRelease                                      
Hit:3 http://jp.archive.ubuntu.com/ubuntu bionic-backports InRelease                                    
Get:4 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]                             
Get:5 http://ppa.launchpad.net/graphics-drivers/ppa/ubuntu bionic InRelease [21.3 kB]
Get:6 http://ppa.launchpad.net/graphics-drivers/ppa/ubuntu bionic/main i386 Packages [18.3 kB]
Get:7 http://ppa.launchpad.net/graphics-drivers/ppa/ubuntu bionic/main amd64 Packages [23.8 kB]
Get:8 http://ppa.launchpad.net/graphics-drivers/ppa/ubuntu bionic/main Translation-en [6,096 B]         
Fetched 158 kB in 8s (20.6 kB/s)                                                                        
Reading package lists… Done
```

## 適合するドライバーの検索

```ubuntu-drivers devices```

```
$ ubuntu-drivers devices
== /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0 ==
modalias : pci:v000010DEd00001F08sv000019DAsd00004520bc03sc00i00
vendor   : NVIDIA Corporation
driver   : nvidia-driver-415 - third-party free
driver   : nvidia-driver-418 - third-party free
driver   : nvidia-driver-430 - third-party free recommended
driver   : xserver-xorg-video-nouveau - distro free builtin
```

## ドライバーインストール

とりあえず、recommendedのnvidia-driver-430をインストールします。

```sudo apt install nvidia-driver-430```


## GPUの動作確認

nvidia-smiコマンドで認識状態を確認します。下記のように出れば認識できています。

```
$ nvidia-smi 
Fri May 10 16:41:24 2019       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 430.09       Driver Version: 430.09       CUDA Version: 10.1     |
|-------------------------------+----------------------+----------------------+
| 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 RTX 2060    Off  | 00000000:01:00.0  On |                  N/A |
| 41%   40C    P8    13W / 160W |    159MiB /  5900MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      1145      G   /usr/lib/xorg/Xorg                           105MiB |
|    0      1184      G   /usr/bin/gnome-shell                          52MiB |
+-----------------------------------------------------------------------------+
```


## Dockerインストール


公式情報
https://docs.docker.com/install/linux/docker-ce/ubuntu/#install-docker-ce

必要なパッケージをインストールしておきます。

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

Dockerをインストールし、現在にユーザーにdockerの実行権限を与えます。

```
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable”
sudo apt-get install docker-ce docker-ce-cli containerd.io
sudo usermod -aG docker $USER
```

## Dockerのバージョン確認

以下のコマンドでインストールさればバージョンの確認を行います。

```docker version```


```
$ docker version

Client:
 Version:           18.09.6
 API version:       1.39
 Go version:        go1.10.8
 Git commit:        481bc77
 Built:             Sat May  4 02:35:57 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.6
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.8
  Git commit:       481bc77
  Built:            Sat May  4 01:59:36 2019
  OS/Arch:          linux/amd64
  Experimental:     false
```

## nvidia-dockerのインストール

GPU対応のためにnvidia-dockerをインストールします。

公式の情報は下記になります。
https://nvidia.github.io/nvidia-docker/

```
sudo apt-get install nvidia-docker2
sudo pkill -SIGHUP dockerd
```

## nvidia-docker動作確認

うまくインストールが完了すれば、下記のコマンドにてnvida/cudaのイメージを実行することがきます。

```docker run --runtime=nvidia --rm nvidia/cuda:9.0-base nvidia-smi
```

下記のようにローカルで実行した時と同じようにGPU情報が表示されれば成功です。

```
$ docker run --runtime=nvidia --rm nvidia/cuda:9.0-base nvidia-smi
Unable to find image 'nvidia/cuda:9.0-base' locally
9.0-base: Pulling from nvidia/cuda
34667c7e4631: Pull complete 
d18d76a881a4: Pull complete 
119c7358fbfc: Pull complete 
2aaf13f3eff0: Pull complete 
4d96b2dafaa5: Pull complete 
f8c41b380cab: Pull complete 
d2c1b4858446: Pull complete 
Digest: sha256:0afacc402b0eb2333d1075d051e237710483b29cdd51c4e7de5d60be4cb1468f
Status: Downloaded newer image for nvidia/cuda:9.0-base
Fri May 10 07:51:32 2019       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 430.09       Driver Version: 430.09       CUDA Version: 10.1     |
|-------------------------------+----------------------+----------------------+
| 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 RTX 2060    Off  | 00000000:01:00.0  On |                  N/A |
| 41%   35C    P8    12W / 160W |    222MiB /  5900MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
+-----------------------------------------------------------------------------+
```

## docker-composeのインストール

やはり複数コンテナの管理ができるdocker-composeを入れた方が便利なので入れておきます。

公式サイト手順：
https://docs.docker.com/compose/install/

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

# 完了

これでdocker-nvidiaによりGPUを思う存分使える環境を構築することができました。

２週間ほど使っているのですが、手元の環境をpyenv等を使って細工していたのを、汚さずに何度でも新しい環境ベースでテストできるのは非常に便利です。dockerを常に利用する事で再現性のある環境を作ることを心がけるようになりました。また、別環境にした事でゴミdockerイメージによる SSDの圧迫もなくなりました（これが大きい。