もう迷わない Ubuntu GPU Server 環境構築: 前編

# python * AI 環境構築 on Ubuntu 18.04

* 前編 (Driver / Library install 編)
    - [後編はこちら](https://qiita.com/daichildren98/items/acc1abcca37dfa521fea)

* author : 鈴木 大智 (user名 : sudachi)
    - pc name : AIserver
* 最終更新 : 2020/02/11



---

## TL;DR
研究室で Ubuntu Server 上に GPGPU 環境を構築する機会がありましたので、その際に行ったことをマニュアル化しました。

私自身、ドキュメントが少なくて困ったことも多々あったので、参考にしていただけますと幸いです。

今回は 前編(Driver / Library install 編)と称しまして、 NVIDIA Driver / CUDA / cuDNN のインストールに関して触れていきます。

基本的にコピペでできるように書いているつもりです。ぜひ利用していただけたらと思います。

## マシンの状態を確認
* (CPU) : `cat /proc/cpuinfo`
  * CPU のコア数をチェック : `cat /proc/cpuinfo | grep processor | wc -l`
* (MEMORY) : `cat /proc/meminfo`
　　* `free -h` でも OK (こっちの方が人間フレンドリーかも..)
* (VGA) : `lspci | grep VGA`

    - VGA が NVIDIA のものであるか確認する : `lspci | grep NVIDIA`

        + きちんと NVIDIA 製の GPU が認識されていれば以下のような出力が得られる。

```
01:00.0 VGA compatible controller: NVIDIA Corporation Device 1f02 (rev a1)
01:00.1 Audio device: NVIDIA Corporation Device 10f9 (rev a1)
01:00.2 USB controller: NVIDIA Corporation Device 1ada (rev a1)
01:00.3 Serial bus controller [0c80]: NVIDIA Corporation Device 1adb (rev a1)
```


# これから 3つ (4つ) インストールするものがあります。
* NVIDIA Driver : 430.40
* CUDA : 10.0
* cuDNN : 7.6
* tensorflow-gpu : 1.14 (anaconda > python : 3.6)
    - これらはバージョンを合わせないと依存関係が云々、とエラーを言い渡されます。。
    - 私は上記のバージョンでインストールを行ったところうまく行きましたので以下そのバージョンをインストールしていきます。
    - tensorflow もとい, python は anaconda 環境を利用しています。(この記事では扱っておりません。ごめんなさい。後日, 続編を記載予定です。)

## NVIDIA Driver をインストール
* 一応、apt を最新のものに upgrade しておきましょう。

    - `sudo apt update`
    - `sudo apt upgrade`

        + 好みのエディタがある方はこの辺で入れておくと便利です。
        + 以下、私は `emacs` で編集を行いますが、エディタはお好みで。

* `nouveau` というドライバが動いてないか確認。

```shell
sudachi@AIsever:~$ lsmod | grep nouveau
nouveau              1716224  0
mxm_wmi                16384  1 nouveau
wmi                    24576  2 mxm_wmi,nouveau
video                  45056  1 nouveau
i2c_algo_bit           16384  1 nouveau
ttm                   106496  2 cirrus,nouveau
drm_kms_helper        172032  2 cirrus,nouveau
drm                   401408  5 drm_kms_helper,cirrus,ttm,nouveau
```

* このように出力が返ってきて `nouveau` 動いている場合は以下の作業を行います。

1. blacklist を確認 : `cat /etc/modprobe.d/blacklist.conf`
2. `nouveau` をブラックリストの末尾に追加

* (心配な方は) デフォルトのブラックリストをバックアップしておくと良いでしょう。
    - `sudo cp -p /etc/modprobe.d/blacklist.conf /etc/modprobe.d/blacklist.conf.orig`
    - (確認) : `ls /etc/modprobe.d/blacklist*` して先ほどの `blacklist.conf` と、 `blacklist.conf.orig` が存在していれば OK.

* blacklist.conf に nouveau を登録するために、以下を実行

```/etc/modprobe.d/blacklist.conf
# (前部分 略)

blacklist nouveau
options nouveau modeset=0
```

```shell
echo '' >> /etc/modprobe.d/blacklist.conf
echo 'blacklist nouveau' >> /etc/modprobe.d/blacklist.conf
echo 'options nouveau modeset=0' >> /etc/modprobe.d/blacklist.conf
```

* ここで read only になっている方は root user で編集を行ってください。

```/etc/modprobe.d/blacklist.conf
...
# really needed.
blacklist amd76x_edac

blacklist nouveau
options nouveau modeset=0
```

* こんな感じになったら完了です。

    - 変更を適用
        + `sudo update-initramfs -u` 

        + プロンプトが返ってきたら再起動
            - `sudo reboot` 


* apt のリポジトリに NVIDIA ドライバ のリポジトリを追加

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

  + 途中で「続行するには `Enter` を, 中断するには `Ctrl-C` を押してくれ」と言われるので、続行して良い場合には `Enter` を押します。
  + リポジトリの追加は自己責任でお願いします..

  - apt をアップデート
    + `sudo apt update` 

  - ドライバの推奨バージョンを確認
    + `sudachi@AIsever:~$ ubuntu-drivers devices`

ここで

```
Command 'ubuntu-drivers' not found, but can be installed with:

sudo apt install ubuntu-drivers-common
```

と言われたら `sudo apt install ubuntu-drivers-common` してください。

* こんな感じで NVIDIA Driver の推奨バージョンが出力されます。

```
sudachi@AIsever:~$ ubuntu-drivers devices
== /sys/devices/pci0000:00/0000:00:02.2/0000:03:00.0 ==
modalias : pci:v000010DEd00001F02sv000019DAsd00002516bc03sc00i00
vendor   : NVIDIA Corporation
driver   : nvidia-driver-430 - third-party free recommended
driver   : nvidia-driver-410 - third-party free
driver   : nvidia-driver-415 - third-party free
driver   : xserver-xorg-video-nouveau - distro free builtin
```

* お好きなバージョンをインストール (私は最新版でうまくいきました..責任は取れないですが..)

    - NVIDIA ドライバのインストールをする。

        + `sudo apt install nvidia-driver-{version}`

        + 終了したら `sudo reboot`

    - 再びログインしたら、以下のコマンドでインストールされたかを確認できます:
        + `nvidia-smi`

---
[version 追記]

2019/09/10: `nvidia-driver-435` でも環境構築成功。
2020/02/11: `nvidia-driver-440` でも環境構築成功。

[list]

| nvidia-driver  | CUDA  | cuDNN  | tensorflow | date |
| --- | --- | --- | --- | --- |
| 430  | 10.0  | 7.6.2  | 1.14 | 2019/08/06 |
| 435  | 10.0  | 7.6.2 | 1.14 | 2019/09/10 |
| 440  | 10.1  | 7.6.5 | 2.1 | 2020/02/11 |

---

## CUDA を install 
* とりあえず、インストールしてみよう。

    - `sudachi@AIsever:~$ sudo apt-get install cuda-toolkit-10-0`

```
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package cuda-toolkit-10-0
```

* apt のリポジトリに CUDA があるかどうかでできるかできないか変わる (のだとと思います)。

* ないと言われた場合は追加する。

    - 認証に必要な鍵を取得する。

        + `sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub`

    - もし、ホームディレクトリを汚したくなければ "downloads" フォルダでも作っておくことをオススメします。

        + `sudachi@AIsever:~$ mkdir downloads`

    - web から CUDA (のインストーラー?) を get

        + (downloads フォルダを作った場合は) : `cd downloads`
        + `wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-repo-ubuntu1804_10.0.130-1_amd64.deb`

        + このようにするとダウンロードされたことが確認できます : `sudachi@AIsever:~/downloads$ ls`

```
cuda-repo-ubuntu1804_10.1.168-1_amd64.deb
```

* パッケージ管理システムに追加

    - `sudo dpkg -i cuda-repo-ubuntu1804_10.0.130-1_amd64.deb`

```
Selecting previously unselected package cuda-repo-ubuntu1804.
(Reading database ... 93960 files and directories currently installed.)
Preparing to unpack cuda-repo-ubuntu1804_10.1.168-1_amd64.deb ...
Unpacking cuda-repo-ubuntu1804 (10.1.168-1) ...
Setting up cuda-repo-ubuntu1804 (10.1.168-1) ...
```

* apt に反映
    - `sudachi@AIsever:~/downloads$ sudo apt update`

* CUDA を install
    - `sudo apt-get install cuda-toolkit-10-0`


- PATH を通す (以下の内容を `.bashrc` などに追記します, 心配な方はバックアップを)。

```
export PATH="/usr/local/cuda/bin:$PATH"
export LD_LIBRARY_PATH="/usr/local/cuda/lib64:$LD_LIBRARY_PATH"
```

- シェルの再起動をする。( `exec $SHELL -l` / `source ~/.bashrc` でも可 )

* 以下のコマンドで CUDA のバージョンと有効化できているかを確認することができます。

    - `nvcc -V`

        + 出力の例です。

```
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2018 NVIDIA Corporation
Built on Sat_Aug_25_21:08:01_CDT_2018
Cuda compilation tools, release 10.0, V10.0.130
```


## cuDNN をインストール

* cuDNN のインストール
    - cuDNN には

1. Runtime library
2. developer library
3. code samples and user guide

    の3つがあります。

* このうち `3.` は画像出力による動作確認のサンプルなので、使いませんので今回はスキップします。
    - ( いま ubuntu Server を利用しているのでディスプレイ (グラフィックス) はない想定です。)

* 上記 `1.` `2.` をダウンロードします。(ここから 別の PC (ssh 元などあればそちら) での作業になります。)
    - 本当は wget などしてダウンロードしたいのですが、ユーザ認証か何かで弾かれる (403 Forbidden) ので..
    - 手元に何か利用できる PC があればそこにダウンロードします。(PC名 を `DaiMac`, user名を `sudachi` と仮定)
    - 私はそれ scp で Ubuntu Server (ip address を `10.20.30.40` と仮定) に送信する形で解決しました。

        + ここは改善したいところでもあるので、何かいい方法があればご教授いただきたいです..
        + 本当はコンソールからの操作だけで完了させたい.. 

    - [NVIDIA 公式 HP](https://developer.nvidia.com/rdp/cudnn-archive#a-collapse714-9) に必要ならばユーザ登録してください。 (Google account があれば紐付けできます)。
        + 自分の OS と CUDA のバージョンにあった cuDNN library をダウンロードする。
        + (例 : 今回では ubuntu 18.04 / CUDA 10.0)

* Runtime library を Ubuntu Server に送る:
    - `DaiMac:~ sudachi$ scp /Users/sudachi/Downloads/libcudnn7_7.6.2.24-1+cuda10.0_amd64.deb sudachi@10.20.30.40:/home/sudachi/downloads/`

* developer library を Ubuntu Server に送る:
    - `DaiMac:~ sudachi$ scp /Users/sudachi/Downloads/libcudnn7-dev_7.6.2.24-1+cuda10.0_amd64.deb sudachi@10.20.30.40:/home/sudachi/downloads/`



* (ここから Ubuntu Server での作業に戻ります) パッケージ管理ツールに cuDNN の情報を加える

    - さっき scp で cuDNN library を飛ばした先に移動します。

        + `cd downloads`

        + 必要なら `ls` などで cuDNN の存在を確認してください。

    - パッケージリストに Runtime Library と Developer Library の両方を反映します。
        + `sudo dpkg -i libcudnn7_7.6.2.24-1+cuda10.0_amd64.deb`

```
Selecting previously unselected package libcudnn7.
(Reading database ... 107508 files and directories currently installed.)
Preparing to unpack libcudnn7_7.6.2.24-1+cuda10.0_amd64.deb ...
Unpacking libcudnn7 (7.6.2.24-1+cuda10.0) ...
Setting up libcudnn7 (7.6.2.24-1+cuda10.0) ...
Processing triggers for libc-bin (2.27-3ubuntu1) ...
```

* `sudo dpkg -i libcudnn7-dev_7.6.2.24-1+cuda10.0_amd64.deb`

```
Selecting previously unselected package libcudnn7-dev.
(Reading database ... 107514 files and directories currently installed.)
Preparing to unpack libcudnn7-dev_7.6.2.24-1+cuda10.0_amd64.deb ...
Unpacking libcudnn7-dev (7.6.2.24-1+cuda10.0) ...
Setting up libcudnn7-dev (7.6.2.24-1+cuda10.0) ...
update-alternatives: using /usr/include/x86_64-linux-gnu/cudnn_v7.h to provide /usr/include/cudnn.h (libcudnn) in auto mode
```

* Runtime library のインストール
    - `sudachi@AIsever:~/downloads$ sudo apt install libcudnn7=7.6.2.24-1+cuda10.0`

```
Reading package lists... Done
Building dependency tree
Reading state information... Done
libcudnn7 is already the newest version (7.6.2.24-1+cuda10.0).
0 upgraded, 0 newly installed, 0 to remove and 3 not upgraded.
```

+ すでに最新版と言われます..
+ CUDA と違い、こちらはライブラリなので `dpkg -i` するだけで良いのかもしれない。

* developer library のインストール (確認)
    - `sudachi@AIsever:~/downloads$ sudo apt install libcudnn7-dev=7.6.2.24-1+cuda10.0`

```
Reading package lists... Done
Building dependency tree
Reading state information... Done
libcudnn7-dev is already the newest version (7.6.2.24-1+cuda10.0).
0 upgraded, 0 newly installed, 0 to remove and 3 not upgraded.
```

* 一応、ここで `apt update` と `apt upgrade` を行なっておきました。


* cuDNN インストールされているかの確認:

    - `cat /usr/include/cudnn.h | grep CUDNN_MAJOR -A 2`

```
sudachi@AIsever:~/downloads$ cat /usr/include/cudnn.h | grep CUDNN_MAJOR -A 2
#define CUDNN_MAJOR 7
#define CUDNN_MINOR 6
#define CUDNN_PATCHLEVEL 2
--
#define CUDNN_VERSION (CUDNN_MAJOR * 1000 + CUDNN_MINOR * 100 + CUDNN_PATCHLEVEL)

#include "driver_types.h"
```

## まとめ
以上で Ubuntu Server 上に NDIVIA Driver / CUDA / cuDNN のインストールが終了です。
お疲れ様でした。
快適な GPGPU学習 life を。


## 後編も書きましたので何卒..
* [後編](https://qiita.com/daichildren98/items/acc1abcca37dfa521fea)