cuda+ubuntu18.04+anaconda+tensorflow

# 備忘録

cuda+ubuntu18.04+anaconda+tensorflowで使おうとして、ハマったのでメモ。

# 環境

ubuntu 18.04
GPU 2080Ti
tensorflow 2.x
anaconda current

# ハマる主な原因

*   ハマっている記事を参照して、自分もハマる。
*   これ秒でやっちゃえるでしょ精神
*   tensorflow公式チュートリアル通りにいくと思っていた
*   Nvidiaのリソースがわかりにくい・調べにくい・リンクを辿りにくい

# やったこと

## Nvidia GPU driverをインストール

https://www.nvidia.com/download/Find.aspx?lang=jp

ドライバーは、GPUのハードに依存するので、そのハードが利用可能な最新のドライバで良いと思われる。
cudaとの相性はここから調べる。
https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html

ハードに合わせた最新版を自動インストールするのでよければ、次のコマンドでよい。

```
$ sudo ubuntu-drivers autoinstall
```

バージョンを指定する例1

```
$ sudo apt install nvidia-460
```

バージョンを指定する例2(http://us.download.nvidia.com/XFree86/Linux-x86/361.45.11/README/installdriver.html)

```
wget http://jp.download.nvidia.com/XFree86/Linux-x86_64/460.39/NVIDIA-Linux-x86_64-460.39.run
sudo sh NVIDIA-Linux-x86_64-460.39.run
```

ちゃんとインストールできたか確認。

```
$ nvidia-smi
```

## tensorflowのバージョンとcudaの対応を確認

何通りも検証していないので詳細不明ではあるものの、tensorflowは、cudaとcuDNNのバージョンに厳しいということで、自分の使いたいtensorflowのバージョンに合わせて、cuda,cuDNNのバージョンを、マイナーまで、次のページから調べる。

テスト済みのビルド構成
https://www.tensorflow.org/install/source?hl=ja#gpu

## cudaインストール

### cuda toolkit

cuda toolkitをインストール済みの場合は、/usr/local/cuda-xx.x/bin/cuda-uninstallerを実行しておく。
tensorflowに合うバージョンのcuda toolkitをインストールする。runfile(local)などで十分と思う。
インストール時に、Driverもインストールするかどうか聞かれるが、Driverは事前にインストール済みなのでスキップする。
https://developer.nvidia.com/cuda-toolkit-archive

### cuDNNインストール

cuDNNは、Nvidiaの言うとおりやる。（アカウント作成、cuDNNダウンロード）
https://docs.nvidia.com/deeplearning/cudnn/install-guide/index.html

インストール時は、Runtime library, developper libraryでなく、「cuDNN Library for Linux (x86)」を選ぶ。これは.tgz形式のファイル群をダウンロードして、自分でコピーするときのもの。
コピーの仕方はここ。アンインストールは、ただ削除するだけ。
https://docs.nvidia.com/deeplearning/cudnn/install-guide/index.html#installlinux-tar

## tensorflow, anaconda

ここまでできたら、anacondaをインストールして、仮想環境を作って、その仮想環境で自分で使うと決めていたtensorflow2.x以上をインストール。
（tensorflow1.15までは、tensorflowでなく、tensorflow-gpuが必要）

## 環境変数パス

tensorflow公式のGPUサポート（https://www.tensorflow.org/install/gpu?hl=ja）に従い、環境変数パスを追加。
設定するファイルは自由だが、例として、.bashrcへ以下を追記。

vim .bashrc

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/extras/CUPTI/lib64
(ダブルクオート不要)
(/cuda/は、/cuda-xx.x/の方でもOK)

パスを反映

```
$ source .bashrc
```

ここで、動作を確認する。
重要：ここでanaconda-navigatorからjupyterを起動して確認すると、エラー原因がわからなくなる。
anacondaの仮想環境を起動して、CLIのpythonモードにする。
import tensorflowしてみる。

```
import tensorflow
```

ここで、環境変数エラーが出ているときは、足りない環境変数パスを追加する。

```
# NG例（tf公式のチュートにあったパスを通したが、まだライブラリが見つからないエラーがでる）
>>> import tensorflow
2021-02-05 22:18:40.717694: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/cuda-11.0/extras/CUPTI/lib64
```

例えば、以下を追加。

```
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib64
```

再度、パスを反映

```
$ source .bashrc
```

再度、import tensorflowで確認して、successしていればOK。

この時点で、cudaのバージョンが調べられるようになる。

```
$ nvcc -V
```

# GPUの存在確認

tensorflowのバージョンによって異なる。
2系ならば、

```
# GPUの個数をカウント
print("Num GPUs Available: ", len(tf.config.experimental.list_physical_devices('GPU')))
```

あるいは

```
# GPU名をCPUとともに列挙
from tensorflow.python.client import device_lib
print(device_lib.list_local_devices())
```

あるいは、

```
# GPUアクセスができるかどうか
tf.test.is_gpu_available()
```

# kerasを使ってGPUメモリを割いているか確認

```
# 簡単なテストを実行
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(input_shape=(28, 28)),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10)
])
loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
model.compile(optimizer='adam',
              loss=loss_fn,
              metrics=['accuracy'])
model.fit(x_train, y_train, epochs=50)
```

この後に、nvidia-smiで状態確認すると、ちゃんとGPUが消費されていることを確認できる。

# 気づいたこと

昔の記事などで、GUIの機能を削除しなければならないなどの記載が残っているが、削除しないでできる。

# References
* Tensorflow GPU, CUDA, CuDNNのバージョン早見表(https://qiita.com/chin_self_driving_car/items/f00af2dbd022b65c9068)
* NvidiaドライバとCUDAとcuDNNとTensorflow-gpuとPythonのバージョンの対応（https://qiita.com/konzo_/items/a6f2e8818e5e8fcdb896）
* How to install the NVIDIA drivers on Ubuntu 18.04 Bionic Beaver Linux(https://linuxconfig.org/how-to-install-the-nvidia-drivers-on-ubuntu-18-04-bionic-beaver-linux)