ubuntu18.04でTensorFlow-gpuを動かす

ubuntu18.04でTensorFlow-gpuを動かすまでの環境構築記事です。
まっさらな環境で導入した際の手順なので、会社や学校、個人で新しく機械学習環境を作る方に役立つ記事だと思います。
それでは、Nvidia driver, CUDA, cuDNN, Anaconda, TensorFlow-gpuを順に導入していきます。


##実施環境
Ubuntu 18.04 LTS 日本語 Remix
NVIDIA Geforce GTX 1050Ti

##Ubuntuのインストール
割愛しますが、参考リンクを載せておきます。
参考：[/homeを残して、Ubuntu 16.04LTS をクリーンインストールする]
(https://qiita.com/hkuno/items/52ef4a300262a51f982e)
公式インストーラー：[Ubuntu 18.04 LTS 日本語 Remix リリース](https://www.ubuntulinux.jp/News/ubuntu1804-ja-remix)

##Nvidia driverのインストール
やることは３つあります。
・**セキュアブートの無効化**
・**nouveauの停止**
・**Nvidia driverのインストール**
上２つはハマリポイントなので注意しましょう。

**・セキュアブートの無効化**
それではまずセキュアブートを無効化します。
PCの電源を入れる際にF2などを押してBIOSの画面を呼び出しましょう。
私はマザーボードがASUSだったので、Advanced modeのbootから設定を無効化しました。
*ちなみに無効化方法すごくわかりにくい。。　*
参考：[UEFI の セキュアブートの設定について: 変更方法や注意点など](https://freesoft.tvbok.com/tips/efi_installation/about_secure_boot.html)

**・nouveauの停止**
次にubuntuに最初からインストールされているグラフィックドライバーのnoveauを停止させます。
まずコンソールを立ち上げ、nouveauが動作していることを確認しましょう。

~~~
~$ lsmod | grep -i nouveau
~~~

↓みたいな感じで表示されます。

~~~
nouveau              1716224  3
mxm_wmi                16384  1 nouveau
ttm                   106496  1 nouveau
i2c_algo_bit           16384  2 nouveau,i915
drm_kms_helper        172032  2 nouveau,i915
drm                   401408  8 nouveau,i915,ttm,drm_kms_helper
wmi                    24576  4 asus_wmi,wmi_bmof,mxm_wmi,nouveau
video                  45056  3 asus_wmi,nouveau,i915
~~~


それではnouveauを停止させていきます。
nouveauを停止させるために、blacklistを作成します。

~~~
~$ nano /etc/modprobe.d/blacklist-nvidia-nouveau.conf
~~~

nanoで↓のように書き込みます。

~~~
blacklist nouveau
options nouveau modset=0
~~~

コンソールに戻って

~~~
~$ sudo update-initramfs -u
~~~

で完了です。
※このタイミングで電源を切ってしまうとディスプレイに表示するグラフィックドライバーがないので、セーフモードで入ることになってしまうことになります、電源は切らないように。

**・Nvidia driverのインストール**

~~~
~$ sudo ubuntu-drivers autoinstall
~~~

これだけです。楽チン。
それでは再起動しましょう。

~~~
~$　sudo reboot
~~~

再起動後に下記コマンドでnouveauが停止し、Nvidia driverが動作していることを確認します。

~~~
~$ lsmod | grep -i nouveau
~~~

何もでなければOKです。
次に、

~~~
~$　nvidia-smi
~~~

こんな感じで何か表示されればOKです。
エラーメッセージが表示された場合は何か問題があります。

~~~
Tue Sep  4 18:49:06 2018       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 390.48                 Driver Version: 390.48                    |
|-------------------------------+----------------------+----------------------+
| 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 105...  Off  | 00000000:01:00.0  On |                  N/A |
| 52%   43C    P8    N/A /  75W |    166MiB /  4036MiB |      2%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      1303      G   /usr/lib/xorg/Xorg                            96MiB |
|    0      1473      G   /usr/bin/gnome-shell                          67MiB |
+-----------------------------------------------------------------------------+ 
~~~

これでNvidia driverのインストールは終わりです。
続いてCUDA cuDNNを導入していきます。

##CUDA9.0とcuDNNのインストール
**・CUDA9.0のインストール**
NVIDIA公式ページからCUDA9.0をダウンロードします。
[CUDA Toolkit 9.0 Downloads](https://developer.nvidia.com/cuda-90-download-archive?target_os=Linux&target_arch=x86_64&target_distro=Ubuntu&target_version=1704&target_type=deblocal)
※**CUDA9.1は推奨しません。**TensorFlowをインストールする際に手順が増えます。
※ubuntuリポジトリからインストールするとCUDA9.1になります。

ダウンロードしたディレクトリで下記コマンドを入力し、インストールします。

~~~
~$ sudo dpkg -i cuda-repo-ubuntu1704-9-0-local_9.0.176-1_amd64.deb
~$ sudo apt-key add /var/cuda-repo-9-0-local/
~$ sudo apt-get update
~$ sudo apt-get install cuda-toolkit-9-0
~~~

次にCUDAのPATHを通します。
nanoで.bashrcを開き末尾にexport以降を書き込みます。

~~~
~$ sudo nano ~/.bashrc

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}}
~~~

再起動して.bashrcを読み込ませます。

~~~
~$　sudo reboot
~~~

起動したら、nvccでCUDAがインストールされたことを確認します。

~~~
nvcc -V
~~~

下記のように表示されれば成功です。

~~~
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2017 NVIDIA Corporation
Built on Fri_Sep__1_21:08:03_CDT_2017
Cuda compilation tools, release 9.0, V9.0.176
~~~
　

**・cuDNNのインストール**
NVIDIA公式ページからcuDNNをダウンロードします。
・cuDNN v7.1.4 Runtime Library for Ubuntu16.04 (Deb)
・cuDNN v7.1.4 Developer Library for Ubuntu16.04 (Deb)
・cuDNN v7.1.4 Code Samples and User Guide for Ubuntu16.04 (Deb)
の３つをダウンロードします。
[Download cuDNN v7.1.4 (May 16, 2018), for CUDA 9.0](https://developer.nvidia.com/rdp/cudnn-archive#a-collapse714-9)

ダウンロードしたディレクトリで下記コマンドを入力し、インストールします。

~~~
~$ sudo dpkg -i libcudnn7_7.2.1.38-1+cuda9.0_amd64.deb
~$ sudo dpkg -i libcudnn7-dev_7.2.1.38-1+cuda9.0_amd64.deb
~$ sudo dpkg -i libcudnn7-doc_7.2.1.38-1+cuda9.0_amd64.deb
~~~

以上で、CUDA9.0とcuDNNのインストールは終わりです。
続いてpythonを動かすために、Anacondaをインストールしていきます。

##Anacondaインストールと仮想環境の構築
Anacondaを公式サイトからダウンロードします。
[Anaconda 5.2 For Linux Installer](https://www.anaconda.com/download/#linux)

ダウンロードしたディレクトリで下記コマンドを入力し、インストールします。

~~~
~$ bash Anaconda3-5.2.0-Linux-x86_64.sh
~~~

ライセンス条項を読み進めて、質問はyesとEnterで回答していきましょう。
インストールが終わったら、下記コマンドでバージョンが表示されることを確認しましょう。

~~~
~$ conda -V
~~~

バージョンが表示されればインストール成功です。

続いて、Anacondaで仮想環境を構築します。
下記コマンドを実行することで仮想環境を作成してくれます。超簡単。

~~~
~$ conda create -n tensorflow pip python=3.6
~~~

下記コマンドで仮想環境をActivateします。

~~~
~$ source activate tensorflow
~~~

ターミナルに(tensorflow)と表示名が出ればOKです。

##TensorFlow-gpuのインストール
最後にTensorFlow-gpuをインストールします。
仮想環境が立ち上がっている状態で、下記コマンドを入力します。

※執筆時点ではtensorflowのバージョンは1.9が最新なのですが、今回は1.8を使用しました。

~~~
~$(tensorflow) pip install tensorflow-gpu==1.8
~~~

エラーが出なければ、TensorFlow-gpuのインストールは完了です。お疲れ様でした。

##おまけ：動作確認
GPUがTensorFlowで動作しているか確認します。
ターミナルで

~~~
python

import tensorflow as tf
tf.test.gpu_device_name()
~~~

と入力してみましょう。

~~~
'/device:GPU:0'
~~~

エラーが表示されず、このように表示されればOKです。

次にGPUのパフォーマンスを確認します。
下記のコードが書き込まれたpythonファイルを作成し実行してみてください。
引用：https://www.kaggle.com/getting-started/47096#post271139

```py3
import tensorflow as tf
import timeit

# See https://www.tensorflow.org/tutorials/using_gpu#allowing_gpu_memory_growth
config = tf.ConfigProto()
config.gpu_options.allow_growth = True

with tf.device('/cpu:0'):
  random_image_cpu = tf.random_normal((100, 100, 100, 3))
  net_cpu = tf.layers.conv2d(random_image_cpu, 32, 7)
  net_cpu = tf.reduce_sum(net_cpu)

with tf.device('/gpu:0'):
  random_image_gpu = tf.random_normal((100, 100, 100, 3))
  net_gpu = tf.layers.conv2d(random_image_gpu, 32, 7)
  net_gpu = tf.reduce_sum(net_gpu)

sess = tf.Session(config=config)

# Test execution once to detect errors early.
try:
  sess.run(tf.global_variables_initializer())
except tf.errors.InvalidArgumentError:
  print(
      '\n\nThis error most likely means that this notebook is not '
      'configured to use a GPU.  Change this in Notebook Settings via the '
      'command palette (cmd/ctrl-shift-P) or the Edit menu.\n\n')
  raise

def cpu():
  sess.run(net_cpu)

def gpu():
  sess.run(net_gpu)

# Runs the op several times.
print('Time (s) to convolve 32x7x7x3 filter over random 100x100x100x3 images '
      '(batch x height x width x channel). Sum of ten runs.')
print('CPU (s):')
cpu_time = timeit.timeit('cpu()', number=10, setup="from __main__ import cpu")
print(cpu_time)
print('GPU (s):')
gpu_time = timeit.timeit('gpu()', number=10, setup="from __main__ import gpu")
print(gpu_time)
print('GPU speedup over CPU: {}x'.format(int(cpu_time/gpu_time)))

sess.close()
```

GPUの速度がCPUの何倍の計算能力があるか表示してくれます。

##おまけ2:どうしてもインストールできなかった場合
一度諦めて、Googleの無料GPUクラウド環境Colaboratoryを使いましょう。
一回落ち着いてから再度トライしてみてください。
使い方はここで詳しく説明してくれています。
[【秒速で無料GPUを使う】TensorfFow/Keras/PyTorch/Chainer環境構築 on Colaboratory](https://qiita.com/tomo_makes/items/f70fe48c428d3a61e131)

##参考記事
・[Ubuntu18.04にNvidia Driver, CUDA, cuDNNを入れる](https://qiita.com/nakamura21/items/2b2ff6524710d167d618)
・[nvidia-driverをubuntu18.04にインストールする](https://qiita.com/ohta6/items/684b9ecd4d67a52e5a7f)