自作PCにUbuntu16.04 LTS、NVIDIAドライバ、CUDA9.0、cuDNN 7.1をインストール（ディープラーニング用）

## はじめに
機械学習向けにGPU搭載の自作PCの環境構築を行っていて、かなり手こずっていましたがなんとか完了しました。同じようにGPU環境構築している人の参考になってもらえたらなぁという思いを込めて記事を書きます。
## 環境
GPU:GTX Geforce 1080Ti
OS:Ubuntu 16.04 LTS

## 手順
1. CUDA Toolkit のバージョン選択
2. OSのインストール
3. NVIDIAドライバーのインストール
4. CUDA Toolkitのインストール
5. cuDNNのインストール

## CUDA Toolkit のバージョン選択
これが一番大事。GPU用にインストールすべきものはNVIDIAドライバー、CUDA、cuDNNとありますが、cuDNNはCUDAのバージョンに応じて決まり、NVIDIAドライバーとCUDAにも対応するバージョンがあり、<a href="https://devtalk.nvidia.com/default/topic/1028960/cuda-setup-and-installation/looking-for-cuda-compatibility-chart-for-nvidia-drivers/">ここ</a>のように整合性が取れないバージョン同士をインストールすると、正しく作動しなくなります。従って、どのCUDAバージョンを選択するかは大切です。
まずは<a href="http://www.nvidia.co.jp/Download/index.aspx?lang=jp">こちら</a>を参照して自分のGPUに対応しているNVIDIAドライバーのバージョンを入れましょう。表示されるバージョン以下のバージョンなら問題ないです。GTX Geforce 1080 Tiの対応するドライバーはnvidia-390.77でした。
NVIDIAドライバーと対応するCUDAのバージョンは<a href="https://stackoverflow.com/questions/30820513/what-is-version-of-cuda-for-nvidia-304-125/30820690#30820690">こちら
</a>からの引用ですが下図のようです。

![Screenshot from 2018-08-03 21-13-00.png](https://qiita-image-store.s3.amazonaws.com/0/278225/1f91f3e4-13f9-11f7-bb17-b904e31fdda8.png)

CUDA9.2はnvidia-396以上、CUDA9.1はnvidia-387以上、CUDA9.0はnvidia-384以上とのことです。

またCUDA9.1は<a href="https://github.com/tensorflow/tensorflow/issues/15656">ここ</a>をみたところtensorflow1.5, 1.6だとエラーが出るとか出ないとかで若干怪しかったという微妙な理由でやめました。

以上からCUDA9.0に決まりました。

## OSインストール
まずは<a href="https://developer.nvidia.com/cuda-90-download-archive?target_os=Linux&target_arch=x86_64&target_distro=Ubuntu">CUDA Toolkit ダウンロードサイト</a>で確認できるが、CUDAが対応しているOSを調べなければいけません。このリンクはバージョン9.0を検索していますが、"CUDA 9.2"などと欲しいバージョンを検索すればそのバージョン向けのダウンロードサイトがすぐに出てきます。

この対応によると、CUDA9.0は2018.08時点でUbuntu17.10と16.04しか対応していないことがわかります。今回は利用者も多く、以前VirtualBoxで使ったことのあるUbuntu16.04を選択しました。

USBを使ってインストールしました。
具体的な手順は
1. isoイメージのダウンロード
2. USBにインストールディスクを焼くためのソフトウェア(Rufus, Unetbootin等)を用意
3. USBに上記ソフトウェアを用いてisoイメージを焼く
4. 目的のPCにUSBを刺してインストール
詳細なインストール方法は<a href="https://qiita.com/acq27r/items/a802ff2d8c49ac75bc9f">こちら</a>を参考にしてもらえばと思います。また"USBブート ubuntu"等と検索すれば良質な記事が多数あるのでそちらも参照していただけたらなと思います。

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

#### 基本セットアップ
インストールを終えたら次のコマンドを実行しましょう。

``` Bash
$ sudo apt-get upgrade
```

約10分ほどかかります、辛抱して待ちましょう。終わったら次のコマンドを打ちましょう。

``` Bash
$ sudo apt-get update
$ sudo apt-get upgrade
```
なぜか最初にapt-get updateを実行するとエラーが出ます、これはどうもubuntu16.04 特有みたいで、upgradeを行うことにより改善されるみたいです。

#### ドライバー確認
次にnvidiaドライバーとcudaが入っていないかを確認します。OSインストールしたばっかならnvidiaドライバー等は存在せず特に問題ないかと思います。

``` Bash
$ dpkg -l | grep nvidia
$ dpkg -l | grep cuda
```

ドライバーが入っていた場合は次のコマンドでアンインストールしましょう。

``` Bash
$ sudo apt-get --purge remove nvidia*
$ sudo apt-get --purge remove cuda*
$ sudo apt autoremove
```

#### いよいよNVIDIAドライバーインストール
下記のコマンドで apt-get でNVIDIAドライバーを入れる。今回は対応するドライバーのうち最新のnvidia-390を入れた。

``` Bash
$ sudo add-apt-repository ppa:graphics-drivers/ppa
$ sudo apt update
$ sudo apt-get install nvidia-390
```

このとき、

``` Bash
$ nvidia-smi
```

と打って、GPU情報が出力されれば問題ないかと思います(下図)。
![Screenshot from 2018-08-03 22-01-53.png](https://qiita-image-store.s3.amazonaws.com/0/278225/77aa6b24-75dc-3a7d-953b-f607faab5c32.png)

その後、再起動しましょう。

<a href="http://swytel.hatenablog.com/entry/2018/05/08/174943">こちら</a>や<a href="http://tadaoyamaoka.hatenablog.com/entry/2018/01/05/232416">これ</a>を始めとする多くの記事ではX serverをとめたり、Nouveauの無効化を行っていますが、nvidiaドライバーをこの手順で入れたら、おそらくインストールソフトが勝手に無効化してくれたのか、CUDAをインストールしても何も問題ありませんでした。

このときログインループにハマってしまったら、ログイン画面で Ctrl+Alt+F1を押してCUI画面に移動しましょう。このCUI画面は日本語サポートされていないので、<a href="https://qiita.com/yukofeb/items/06419e9ebee53e084fcb">ターミナルの言語を英語にしてみる</a>ことをおすすめします。まずはNouveauが無効化されているかを<a href="http://tadaoyamaoka.hatenablog.com/entry/2018/01/05/232416">これ</a>を参考に確認&実行してみましょう。次にHDMI端子がマザーボードではなく、グラフィックボードに刺さっているか確認しましょう。それでも解決しない場合は<a href="https://qiita.com/musaprg/items/58d9dee4ef70e3882a9d">こちら</a>や<a href="https://hiroyky.hatenablog.com/entry/2017/01/03/050900">こちら</a>を参考にして頂けたらと思います。

もしnvidiaドライバーより先にCUDAをインストールしてしまってもcudaに対応するnvidiaドライバーを入れれば解決すると思います。

## CUDA Toolkit 9.0 インストール
さてログインループから抜け出せたor問題なくnvidiaドライバーをインストールし終えたらいよいよCUDA のインストールです。
<a href="https://developer.nvidia.com/cuda-90-download-archive?target_os=Linux&target_arch=x86_64&target_distro=Ubuntu">CUDA Toolkit ダウンロードサイト</a>からCUDA9.0 debを選択します。Networkでもlocalでもどちらでも大丈夫だと思いますが、networkで筆者はインストールしました。なお各タイプの違いについては<a href="http://gihyo.jp/admin/serial/01/ubuntu-recipe/0456">こちら</a>に詳しく書いてあります。

ダウンロード後はダウンロードサイトに記載の通りコマンドを実行していきます

``` Bash
$ sudo dpkg -i cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64.deb
$ sudo apt-get update
$ sudo apt-get install cuda-toolkit-9-0
```

最後の部分をsudo apt-get install cuda-9-0やcudaとすると、同梱されているnvidiaドライバーもインストールされてしまいます。同時にインストールされるnvidiaドライバーのバージョンが最新のものなため、そのバージョンに対応していないグラフィックボードを搭載している場合はうまく作動しなくなってしまいます。僕は勝手にnvidia-396がインストールされてしまい、原因もわからずログインループにハマってしまい、苦労しました。

インストールが終了したら環境変数の設定です

``` Bash
$ nano ~/.bashrc
```

bashrcの最終行に以下の行を追記

``` Bash
export PATH=/usr/local/cuda-9.0/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
```

下記のコマンドを実行します。


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

パスが通っていれば

``` Bash
$ nvcc -V
```

を実行してCUDAのバージョン情報が現れます。

CUDAのサンプルコードを実行して動作確認します。
サンプルコードをホームディレクトリにコピーするシェルスクリプト（cuda-install-samples-9.0.sh）は　/usr/local/cuda-9.0/bin/ にあるので、CUDAのパスが通っていればそのファイル名を指定するだけで実行できます。

``` Bash
cuda-install-samples-9.0.sh ~ # ホームディレクトリにサンプルコードをコピー。
cd ~/NVIDIA_CUDA-9.0_Samples/
make
cd 2_Graphics/VolumeRender   # サンプルの実行ファイルがあるディレクトリに移動。
./volumeRender
```

上記を実行すると次のようなのが現れました。しっかり3Dなのでドラッグで回転できます。
![Screenshot from 2018-08-03 21-48-35.png](https://qiita-image-store.s3.amazonaws.com/0/278225/b242493e-6703-cb7f-417f-cfe328dc1bee.png)

インストールがうまく行っていない場合は何かしらのエラーが出ると思います。その場合はCUDAとnvidiaの対応バージョン、nvidia-smiが表示されるか等を確認しましょう。

## cuDNNのインストール
<a href="https://developer.nvidia.com/cudnn">cuDNNダウンロードサイト</a>から自分のCUDAのバージョンに合ったcuDNNをダウンロードしましょう。「Runtime Library」と「Developer Library」「Code Samples」の3つをダウンロードします。
ダウンロードしたフォルダに移動し下記を実行

``` Bash
sudo dpkg -i libcudnn7_7.1*+cuda9.0_amd64.deb
sudo dpkg -i libcudnn7-dev_7.1*+cuda9.0_amd64.deb
sudo dpkg -i libcudnn7-doc_7.1*+cuda9.0_amd64.deb
```

以上でgpu環境構築は終わりです。Chainerなりtensorflowなり入れてどしどしディープラーニングしていきましょう！

## 参考サイト
<a href="http://tadaoyamaoka.hatenablog.com/entry/2018/01/05/232416">Ubuntu 16.04 LTSにChainerをインストールする</a>
<a href="http://swytel.hatenablog.com/entry/2018/05/08/174943">Ubuntu 16.04LTSにNVIDIAドライバ(nvidia-390)とCUDA 9.1を入れた時のメモ</a>