Tensorflow2.4 Install to Ubuntu18.04 備忘録

#概要
年末に組んだ自作PCでもTensorflow(TF)が使えるようにセットアップしたのでその備忘録
前回のCuda10のインストールよりも格段に簡単になっていた
TFオフィシャルの手順だけではうまくいかない箇所があったので書き残す

- 実施時期: 2021年2月
- OS: Ubuntu18.04LTS
- CPU: Ryzen 5600X
- GPU: GeForce RTX3070
- Python: AnacondaのPython3.7

##経緯
RTX2000シリーズと比べ格段に性能が向上したとされるRTX3000をどうしてもトレーニングに使ってみたい。
購入前から何気に知ってはいたが、最新TF2.4はcuda11+cuDnn8が要件となっている。
購入後に知ったのは、RTX3000シリーズのnvidia driverは450以降しかなく、しかしこれはcuda10のサポート外であること。
つまりpipインストールでは、RTX3000シリーズで使用できるTFはTF2.4以降となる。
TF2.4で実装された[新機能](https://blog.tensorflow.org/2020/12/whats-new-in-tensorflow-24.html)も試したいので、cuda11へのアップグレードは必須となる。
condaインストールではTF2.3までだが、これでは性能が向上したcuda11のパワーが使えない。

本当はcudaなどインストールせずにcondaでTF2.4 with cuda11を入れたいところだが、下記のようにcondaの最新版はTF2.3まで

https://anaconda.org/search?q=tensorflow-gpu

二月ほど待ったけど、condaからリリースされる様子がないので、仕方なくcuda+cuDnnを入れることにした。
TF2.4はコンパイルせずにcondaの仮想環境にpipでインストールする。

###吉報！
**2021/3/9にconda-forgeを確認したらTF2.4.1がリリースされていた。**

https://anaconda.org/anaconda/tensorflow

##前準備
CUDA対応NVIDIAボードが刺さっていることを確認する。


```Terminal
$ lspci | grep -i nvidia
07:00.0 VGA compatible controller: NVIDIA Corporation Device 2484 (rev a1)
07:00.1 Audio device: NVIDIA Corporation Device 228b (rev a1)
```

##Nvidia Driverのインストール
ディスプレイドライバが標準のnouveauでなくてもよければ、これは入れておく必要がある。
cudaをインストールする、しないは関係ない。
このPCの構成でインストール可能なドライバを探す。

```Terminal
$ sudo ubuntu-drivers devices
== /sys/devices/pci0000:00/0000:00:03.1/0000:07:00.0 ==
modalias : pci:v000010DEd00002484sv00001462sd00003909bc03sc00i00
vendor   : NVIDIA Corporation
driver   : nvidia-driver-460 - distro non-free recommended
driver   : xserver-xorg-video-nouveau - distro free builtin
```

recommended表示のバージョンをインストールする。
これは環境によるが少なくとも450以降でなければならない。これもTF2.4の要件のひとつ

```Terminal
$ sudo apt install --no-install-recommends nvidia-driver-460
```

インストールされたか確認する。

```Terminal
$ sudo nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 460.39       Driver Version: 460.39       CUDA Version: 11.2     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  GeForce RTX 3070    Off  | 00000000:07:00.0  On |                  N/A |
|  0%   48C    P8    17W / 220W |    180MiB /  7979MiB |      1%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|    0   N/A  N/A      1189      G   /usr/lib/xorg/Xorg                115MiB |
|    0   N/A  N/A      1496      G   /usr/bin/gnome-shell               27MiB |
|    0   N/A  N/A      2113      G   ...gAAAAAAAAA --shared-files       34MiB |
+-----------------------------------------------------------------------------+
```
ここで、"CUDA Version: 11.2"と表示される。
しかし、driverのインストールだけでCUDAは入らないので、11.2が何なのかは知らない。

##cuda, cuDnnのインストール
下記のTFオフィシャルの手順をそのまま実行する。

https://www.tensorflow.org/install/gpu?hl=ja

オフィシャルにはdriver 450のインストール手順も含まれていたが、すでに行っているので削除した。
またスクリプト中のコメントにも書かれてあるとおり、インストールするのはruntimeである。
cudaで開発したい人はdeveloper向けcudaをインストールしなければならない。

cudaやcuDnnのバージョンはTFの指定があるので、スクリプト中のバージョン番号は変えてはならない。
nvidia driverは450.X以降であればOK

```Terminal
$ sudo apt install --no-install-recommends nvidia-driver-460
# Add NVIDIA package repositories
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin
sudo mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub
sudo add-apt-repository "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/ /"
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

wget https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/libnvinfer7_7.1.3-1+cuda11.0_amd64.deb
sudo apt install ./libnvinfer7_7.1.3-1+cuda11.0_amd64.deb
sudo apt-get update

# Install development and runtime libraries (~4GB)
sudo apt-get install --no-install-recommends \
    cuda-11-0 \
    libcudnn8=8.0.4.30-1+cuda11.0  \
    libcudnn8-dev=8.0.4.30-1+cuda11.0

# Install TensorRT. Requires that libcudnn8 is installed above.
sudo apt-get install -y --no-install-recommends libnvinfer7=7.1.3-1+cuda11.0 \
    libnvinfer-dev=7.1.3-1+cuda11.0 \
    libnvinfer-plugin7=7.1.3-1+cuda11.0
```

TFのオフィシャル手順に記載はなかったが、.bashrcに下記の2行を追加する。

```Terminal
export PATH=/usr/local/cuda-11.0/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda-11.0/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
```
もちろん下記のフォルダが作成されていることは少なくとも確認する。
/usr/local/cuda-11.0/bin


##Tensorflowのインストール
コンパイルせずに、簡単なpipでインストールする。
これもTFのオフィシャルを一読しておく。

https://www.tensorflow.org/install/pip?hl=ja

書かれているインストール要件は下記なので、"-V"で確認しておく
対応Python: 3.5, 3.6, 3.7 ,3.8
pip: 19.0以降

現時点でpython3.8に対応していないパケージも多いのでPython3.7で作成することをお勧めする。

インストールする仮想環境を作成する。
別の用途でOpenCVも使うためPython3.7で仮想環境"hoge"を作る。

```Terminal
$ conda create -n hoge python=3.7
$ conda activate hoge
```
pipでここにTFをインストールする。動作確認用にjupyterとnumpyなど諸々もインストールしておくこと。

```Terminal
(hoge)$ pip install tensorflow
(hoge)$ conda install jupyter
```

jupyter notebookを起動し、セルで下記を確認する。

```Terminal
import tensorflow as tf
print(tf.__version__)
print(len(tf.config.list_physical_devices('GPU'))>0)
```

インストールされたTFのバージョン（バージョン未指定だったので最新がインストールされているはず）と、GPUボードを認識している'true'が表示されること。

試しにオイラの昔使ったモデルを実行したが、fit()の箇所で下記のエラーが発生した。

**Could not create cudnn handle: CUDNN_STATUS_INTERNAL_ERROR**

下記を参考にTF_FORCE_GPU_ALLOW_GROWTHをTrueにすることでエラーは出なくなった。

https://qiita.com/ysuzuki19/items/b727bbcb45f1cad37630

GPUのメモリを際限なく使用する設定がデフォルトであり、これに制限をかけるときに使うコマンドらしい。
これは環境によるので必ずしも必要ではないが、いつも制限をかけてよいのであれば.bashrcに書いておけば良い。
詳細は下記を参考

https://www.tensorflow.org/guide/gpu#gpu_%E3%81%AE%E3%83%A1%E3%83%A2%E3%83%AA%E5%A2%97%E5%8A%A0%E3%82%92%E5%88%B6%E9%99%90%E3%81%99%E3%82%8B

以上