Deep Learning 環境の構築 （Ubuntu 18.04, 20.04） 2022/01更新

# Deep Learning 環境の構築
新しく調達したパソコンでDeep Learning環境を構築する際に
NVIDIA GPUと標準のUbuntuのグラフィックドライバーの相性が悪いために
毎回フリーズを起こすなど、手間取ることが多いため備忘録を兼ねて投稿。

(2021/04 更新)
末尾に、処理をまとめて行うshell script相当のコマンドをまとめました。 
RTX3000 / A6000 / A100 用の環境はこちらに記事を記載しています。（CUDA 11.2系）
https://qiita.com/k_ikasumipowder/items/e711186c329b36f53833

(2022/01 更新)
Ubuntu のインストール時にインストールバージョンが 20.04.03 LTS 以降であれば
フリーズすること等の問題が起きにくくなったため、一部内容を非表示・整理しております。

(2022/01 更新)
こちらに、Ubuntu20.03 LTS の場合には短い手順でできるため、必須のものを抜粋し別記事としてまとめました。
https://qiita.com/k_ikasumipowder/items/14a7976f12c0b8c55dd3

本記事はあえてCUDA10系を使うために（古いTensorFlowやonnxruntime-gpuのために）
10系のまま残しております。

## 事前準備
サーバーを起動する際に、 Delete Key or F2 Key などを押して、
BIOSのメニューに入り、Secure Boot を Disabled にしておく。
Secure BootとNvidia Driverの相性が悪いことがあり、特殊な設定が必要になるため、
Secure Bootを切っておくとスムーズです。

## 環境

|||
|:--|:--|
|OS|Ubuntu 18.04|
|GPU|GeForce GTX 1080Ti|


<details><summary></di>フリーズしてしまった場合</summary>
<div>普通にUSBメモリからOSをインストールすると以下のような画面となりフリーズしてしまう。
</div></details>


▼USBメモリから起動した際の画面
![ios__________.jpg](https://qiita-image-store.s3.amazonaws.com/0/69701/729eeb4b-2c4e-9d42-5913-66d0e856f99b.jpeg)
原因は nouveau （デフォルトのグラフィックドライバー）とNVIDIA製のGPUと相性が悪いため。

## nouveauの無効化
この画面で `Install Ubuntu にカーソルを合わせて　e` を押すと起動オプションの設定が可能。

nouveau を無効化する
![ios__________ (1).jpg](https://qiita-image-store.s3.amazonaws.com/0/69701/96493124-f321-077c-ed69-c9b9de7c3733.jpeg)

```quiet splash ---``` 
となっているところを
```quiet splash nomodeset ---```
と書き換えるとnouveauを無効化できる。 
![ios__________ (2).jpg](https://qiita-image-store.s3.amazonaws.com/0/69701/c575f879-1f5c-2c96-85fe-f22287b5d7ff.jpeg)

書き換えたら、```Ctrl-x```で起動。
表示は崩れるものの、起動が可能となる。

## 指示に従いインストール
![image.png](https://qiita-image-store.s3.amazonaws.com/0/69701/d260a90a-3c57-bf3f-4200-c82df38a1f29.png)

## 再起動
インストール後も同様に nouveauの設定を行わないとフリーズするため注意。
GRUBはBIOSメニューが消えたあとに、SHIFTを連打or長押しすることで表示が可能

GRUBに行けたら、
e を押して、```quiet splash``` となっているところを
```quiet splash nomodeset```に書き換える。
書き換えたら、```Ctrl-x```で起動。


# 主要なライブラリのインストール

packageのアップグレードを行う

    sudo apt-get update
    sudo apt-get upgrade

主要なライブラリをインストール

    sudo apt-get install -y vim csh flex gfortran g++ \
                     cmake xorg-dev patch zlib1g-dev libbz2-dev \
                     libboost-all-dev openssh-server libcairo2 \
                     libcairo2-dev libeigen3-dev lsb-core \
                     lsb-base net-tools network-manager \
                     git-core git-gui git-doc xclip gdebi-core libffi-dev \
                     make build-essential libssl-dev zlib1g-dev libbz2-dev \
                     libreadline-dev libsqlite3-dev wget curl llvm \
                     libncurses5-dev libncursesw5-dev \
                     xz-utils tk-dev libffi-dev liblzma-dev python-openssl


## G++-7 と BoostLibが動作しているか検証
C++のコンパイラとBoostLibが動作しているかを、
以下のテストプログラムをコンパイル、実行して確認する。


```test_boost.cpp
    #include <boost/lambda/lambda.hpp>
    #include <iostream>
    #include <iterator>
    #include <algorithm>

    int main()
    {
        using namespace boost::lambda;
        typedef std::istream_iterator<int> in;

        std::for_each(
            in(std::cin), in(), std::cout << (_1 * 3) << " " );
    }
```

### コンパイルと実行確認

```
g++-7 test_boost.cpp -o test_boost
echo 3 6 9 | ./test_boost
```
```9 18 27```と出力されればOK


## CUDAのインストール
#### 2020/08更新、2019/03 追記
#### この章は変更が激しいので、以下の手順で上手く行かない場合は各DNNライブラリ（TensorFlow, PyTorchなど）の公式のインストール方法を参照してください。

▼TensorFlow GPU support ページ
https://www.tensorflow.org/install/gpu?hl=ja


2020/08 現在でのインストール手順
後半の libcudnn 以降のところは、１行ずつ実行しないとエラーとなるため注意

```bash

# Add NVIDIA package repositories
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-repo-ubuntu1804_10.1.243-1_amd64.deb
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub
sudo dpkg -i cuda-repo-ubuntu1804_10.1.243-1_amd64.deb
sudo apt-get update
wget http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/nvidia-machine-learning-repo-ubuntu1804_1.0.0-1_amd64.deb
sudo apt install ./nvidia-machine-learning-repo-ubuntu1804_1.0.0-1_amd64.deb
sudo apt-get update

# Install NVIDIA driver まだ nvidia-driverをインストールしていない場合のみ
#sudo apt-get install --no-install-recommends nvidia-driver-455
# Reboot. Check that GPUs are visible using the command: nvidia-smi

sudo apt-get install --no-install-recommends libcudnn7=7.6.4.38-1+cuda10.1
sudo apt-get install --no-install-recommends libcudnn7-dev=7.6.4.38-1+cuda10.1

# Install TensorRT. Requires that libcudnn7 is installed above.
sudo apt-get install -y --no-install-recommends libnvinfer6=6.0.1-1+cuda10.1
sudo apt-get install -y --no-install-recommends libnvinfer-dev=6.0.1-1+cuda10.1
sudo apt-get install -y --no-install-recommends libnvinfer-plugin6=6.0.1-1+cuda10.1
```

Pathを通すために、 `~/.bashrc` などに以下を記載する

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

インストールしたドライバーによっては、すでにCUDAが入っている場合もある。
※最新のものをインストールしても良いが、使用しているライブラリによっては指定通りでないと動かないものも多いので注意。
※ライブラリのバージョンによってCUDA8.0を使うなどのケースもある。
※OSとの依存性があり、Ubuntu 18.04とCUDA9.0は公式にはサポートされていない。
複数CUDAバージョンの同居は推奨されていないため、ここでは説明しないがnvidia-docker2 などを使うなどの方法が有効。
2018/11/30時点でのTensorFlow 1.12.0での Software requirements は以下の通り

|ライブラリ|version|
|---|---|
|NVIDIA® GPU drivers | CUDA 9.0 requires 384.x or higher.|
|CUDA® Toolkit | TensorFlow supports CUDA 9.0.|
|CUPTI| ships with the CUDA Toolkit.|
|cuDNN SDK |(>= 7.2)|
|(Optional) NCCL |2.2 for multiple GPU support.|
|(Optional) TensorRT |4.0 to improve latency and throughput for inference on some models.|

最新Driverのインストール時に導入されるCUDA10.0は、利用しても動かないライブラリがあるため注意。（TensorFlowなど）

``` sudo apt-get install cuda ```をしてしまうと、nvidia-driverが削除され、```nvidia-smi```が通らなくなるため、以下のコマンドでCUDA9.0をインストールします。


```

sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub
wget http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-repo-ubuntu1604_9.1.85-1_amd64.deb
sudo apt install ./cuda-repo-ubuntu1604_9.1.85-1_amd64.deb
wget http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1604/x86_64/nvidia-machine-learning-repo-ubuntu1604_1.0.0-1_amd64.deb
sudo apt install ./nvidia-machine-learning-repo-ubuntu1604_1.0.0-1_amd64.deb
sudo apt update

# CUDAとツールと、NCCL 2.xのインストール
sudo apt install cuda9.0 cuda-cublas-9-0 cuda-cufft-9-0 cuda-curand-9-0 \
    cuda-cusolver-9-0 cuda-cusparse-9-0 libcudnn7=7.2.1.38-1+cuda9.0 \
    libnccl2=2.4.2-1+cuda9.0 cuda-command-line-tools-9-0
```
※バージョンは頻繁に変わるため、存在しない場合は
`apt-cache madison [パッケージ名]` などで検索を行う

## CUDA 10.0 のインストールはこちら 2020/04/20 更新

```
sudo apt-get install --no-install-recommends \
        cuda-10-0 \
        libcudnn7=7.6.5.32-1+cuda10.0  \
        libcudnn7-dev=7.6.5.32-1+cuda10.0  \
        libnvinfer6=6.0.1-1+cuda10.0  \
        libnvinfer-dev=6.0.1-1+cuda10.0  \
        libnvinfer-plugin6=6.0.1-1+cuda10.0
```


---
## cuDNNのインストール (どうしてもマニュアルでやる必要がある場合　基本的に不要)
公式サイトからダウンロードする。
ダウンロードにはメンバーシップにサインインし、規約に同意する必要があることに注意。
※CUDAのバージョンと紐付きがあるので、確認してダウンロードする。
▼公式サイト
https://developer.nvidia.com/rdp/form/cudnn-download-survey

![image.png](https://qiita-image-store.s3.amazonaws.com/0/69701/a0852a8a-43d1-7476-0bf8-f78db4207b0d.png)

以下のコマンドを実行して、libcuptiをインストールする。

```
sudo apt-get install libcupti-dev
```

ランタイムのライブラリはcuDNN7.4.1ではインストーラー形式になっている。
バージョンによっては以下のようなコマンドを実行する。

```
cd ~/ダウンロード
tar -zxvf cudnn-9.2-linux-x64-v7.2.1.38.tgz
sudo cp -P cuda/lib64/libcudnn* /usr/local/cuda-9.2/lib64/
sudo cp cuda/include/cudnn.h /usr/local/cuda-9.2/include/
sudo chmod a+r /usr/local/cuda-9.2/include/cudnn.h /usr/local/cuda/lib64/libcudnn*
```

## Pythonのインストール
Ubuntu18.04では、デフォルトで以下のpythonが入っています。
複数バージョンを使い分ける必要がある場合、ここでpyenvを入れておくと良いでしょう。

```
$ python -V
Python 2.7.15rc1
$ python3 -V
Python 3.6.7
```

## pyenvのインストール
```
git clone https://github.com/yyuu/pyenv.git ~/.pyenv
```

パスを通します。

```
# ~/.bashrc にPATHを通す (最近内容が変わりました。 2021/05 あたり？)
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init --path)"' >> ~/.bashrc
echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n  eval "$(pyenv init -)"\nfi' >> ~/.bashrc
```

```
$ source ~/.bashrc
```

好きなPythonをインストールして、利用できるようにしましょう。

```
pyenv install 3.6.8
pyenv install 3.7.2
pyenv global 3.6.8
pyenv rehash
python -V # 3.6.8
```

※3.7.2 は 2019/01/10現在、TensorFlowの公式サポート対象外です。

pyenvのトラブルシューティングページ
うまくインストール出来ない場合、ここを見れば解決できることが多いです。
https://github.com/pyenv/pyenv/wiki/common-build-problems


## テスト
そのままDeep Learningライブラリを入れてしまうと環境が汚れてしまうので、
venvを利用して仮想環境を作成します。

```
$ cd
$ mkdir workspace
$ cd workspace
$ mkdir test
$ sudo apt-get install python3-venv
$ python3 -m venv venv36testTF
$ source venv36testTF/bin/activate
```

仮想環境に入ったらTensorFlowをテストしてみましょう。

```
$ pip install tensorflow-gpu==1.12.0 
```

mnistが動作するか、確認してみましょう。
```test_mnist.py```という名前で、以下のファイルを作成します。

```test_mnist.py
import tensorflow as tf
mnist = tf.keras.datasets.mnist

(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(512, activation=tf.nn.relu),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=5)
model.evaluate(x_test, y_test)
```

記述できたら実行してみましょう。

```
$ python3 test_mnist.py
```

60秒程度で学習が進んだら、GPUでの学習成功です。

```
python test_mnist.py
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
11493376/11490434 [==============================] - 0s 0us/step
Epoch 1/5
60000/60000 [==============================] - 7s 121us/step - loss: 0.2010 - acc: 0.9397
Epoch 2/5
60000/60000 [==============================] - 7s 118us/step - loss: 0.0806 - acc: 0.9748
Epoch 3/5
60000/60000 [==============================] - 7s 118us/step - loss: 0.0528 - acc: 0.9836
Epoch 4/5
60000/60000 [==============================] - 7s 119us/step - loss: 0.0373 - acc: 0.9882
Epoch 5/5
60000/60000 [==============================] - 7s 118us/step - loss: 0.0290 - acc: 0.9904
10000/10000 [==============================] - 0s 43us/step
```

以下のコマンドでGPUの稼働状況を確認してみましょう。
GPU稼働率などが学習時に上がっていれば、GPUを使っていることが確認できます。
バージョン関連エラーが起きる場合、再起動すると治ります。

```
nvidia-smi -l
```



---

## トラブルシューティング用Nvidia driver のインストール方法

コマンドラインからインストールが可能
xxxxxxxxxxxxx にはドライバーのバージョン指定が入る。
https://www.nvidia.com/Download/index.aspx
公式ページにて、使用したいドライバーが対応している最新バージョンを調べる。

```
sudo apt-get purge nvidia-*
sudo add-apt-repository ppa:graphics-drivers/ppa
[enterキーを押す]
sudo apt-get update
sudo apt-get install nvidia-xxxxxxxxxxxxx
```

以下のコマンドで、ドライバーのリストを確認が可能。
インストールしたいものを指定する

```
sudo apt-cache search nvidia-*
```

2018/11/30 現在では、 1080Ti 向けでは 410.78 が最新だったため、以下のコマンドを使用
した。

```
sudo apt-get install nvidia-driver-410
```

2020/03/09 現在では、 1080Ti 向けでは 410.78 が最新だったため、以下のコマンドを使用
した。

```
sudo apt-get install nvidia-driver-440
```


## 再起動
フリーズしないことを祈りつつ、再起動を行う。
ディスプレイの設定が直っており、以下のコマンドで、GPUの稼働状況が確認できればインストールに成功している。

```
nvidia-smi
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/69701/4f3bfb6b-dc33-9fec-f611-353dc18a525e.png)



# 一括で行うためのスクリプト

```
# ライブラリのアップデート
sudo apt-get update
sudo apt-get upgrade -y

# 主要ライブラリのインストール
sudo apt-get install -y vim csh flex gfortran g++ \
                 cmake xorg-dev patch zlib1g-dev libbz2-dev \
                 libboost-all-dev openssh-server libcairo2 \
                 libcairo2-dev libeigen3-dev lsb-core \
                 lsb-base net-tools network-manager \
                 git-core git-gui git-doc xclip gdebi-core libffi-dev \
                 make build-essential libssl-dev zlib1g-dev libbz2-dev \
                 libreadline-dev libsqlite3-dev wget curl llvm \
                 libncurses5-dev libncursesw5-dev \
                 xz-utils tk-dev libffi-dev liblzma-dev python-openssl

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

sudo apt-get install --no-install-recommends nvidia-driver-455 -y

sudo reboot
```

再起動後以下を実行

```
sudo apt-get install -y --no-install-recommends libcudnn7=7.6.4.38-1+cuda10.1
sudo apt-get install -y --no-install-recommends libcudnn7-dev=7.6.4.38-1+cuda10.1

sudo apt-get install -y --no-install-recommends libnvinfer6=6.0.1-1+cuda10.1
sudo apt-get install -y --no-install-recommends libnvinfer-dev=6.0.1-1+cuda10.1
sudo apt-get install -y --no-install-recommends libnvinfer-plugin6=6.0.1-1+cuda10.1

sudo apt-get install -y --allow-downgrades --no-install-recommends \
        cuda-10-0 \
        libcudnn7=7.6.5.32-1+cuda10.0  \
        libcudnn7-dev=7.6.5.32-1+cuda10.0  \
        libnvinfer6=6.0.1-1+cuda10.0  \
        libnvinfer-dev=6.0.1-1+cuda10.0  \
        libnvinfer-plugin6=6.0.1-1+cuda10.0


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

# .bashrcの読み込み
source ~/.bashrc 

git clone https://github.com/yyuu/pyenv.git ~/.pyenv


echo 'export PYENV_ROOT=${HOME}/.pyenv' >> ~/.bashrc
echo 'export PATH=$PYENV_ROOT/bin:${PATH}' >> ~/.bashrc
echo "eval $(pyenv init -)" >> ~/.bashrc

source ~/.bashrc 

pyenv install 3.7.9
pyenv global 3.7.9
pyenv rehash
python -V # 3.7.9
```

# Docker が必要な場合、更に以下を実行

```
# Docker のインストール
sudo apt-get remove docker docker-engine docker.io containerd runc

sudo apt-get update

sudo apt-get install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

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


sudo docker run hello-world

sudo usermod -aG docker $(whoami)
sudo systemctl restart docker

docker run hello-world
```

# 更に、NVIDIA Container Toolkitをインストールする場合
※旧NVIDIA Docker / NVIDIA Docker2
様々なCUDAバージョンを利用する際にインストールしておくと便利です。

```
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-docker2
sudo systemctl restart docker

# cuda 9.0 系を叩く
docker run --gpus all --rm nvidia/cuda:9.0-base nvidia-smi
```