RTX3070でKerasでDeep Learningを動かす手順について（Windows 10）

#はじめに

RTX3070搭載のPCを購入したので、Deep Learningで画像認識してみよう！と思ったのですが、
実行できるまでにいろいろとハマって時間がかかってしまいましたので、
忘備録を兼ねて手順を整理しました。




#結論
Windows 10環境に、CUDA+anacondaでRTX3070でDeep Learningを実行できる環境を構築しました。


| Package       | version |
|:--------------|:--------|
|Python         |3.8      |
|tensorflow-gpu |2.4.0    |
|CUDA           |11.0.2   |
|cudnn          |8.0.5    |




__主要手順の概要は、以下の通りです__

1. Visual Studio 2019 （Community版）でC++をインストール
2. CUDAの11.0をインストール
3. cudnnの8.0をダウンロードして、展開。　CUDAのディレクトリに上書き保存
4. Anacondaをダウンロードして、pythonとtensorflow-gpu、kerasなどをインストール
5. サンプルコードを実行（ただし、RTX3070の場合はコードにおまじないが必要）


__GPU立ち上げ時のwarningが気になる場合は、もう３手順必要になります__
6. CUDAの11.1をダウンロードして、インストール。bin/ptxas.exeをどこかに保存しておく
7. CUDAの11.1をアンインストール
8. v11.0のbinにv11.1のptxas.exeを上書き保存



# インストール手順（詳細）
以下、ほかの方のページを参考に上げつつ、手順の詳細について記載していきます。





## 0. バージョンチェック
インストールするパッケージの確認方法については、@konzo_さんの記事を参考にしました。
> NvidiaドライバとCUDAとcuDNNとTensorflow-gpuとPythonのバージョンの対応
> https://qiita.com/konzo_/items/a6f2e8818e5e8fcdb896

私の場合、最終的には下記の組み合わせを選択しました（結論記載の通り）

| Package       | version |
|:--------------|:--------|
|Python         |3.8      |
|tensorflow-gpu |2.4.0    |
|CUDA           |11.0.2   |
|cudnn          |8.0.5    |

2020年04月時点で、RTX 3070のドライバはダウンロード不要でした
（バージョン条件を満たしていました）

ちなみに、コントロールパネル→NVIDIAコントロールパネル→システム情報から
現在のドライバのバージョンを確認できます。


## 1. VS2019 C++のインストール
以降の基本的な手順については、@osakashoさんの記事を参考にしました。
> [【Windows】GPUでKerasを利用するメモ【Tensorflow-GPU】](https://qiita.com/osakasho/items/e3b0b14bd26ae1060413)


以下のURLからCommunity版がダウンロード可能です。
https://visualstudio.microsoft.com/ja/downloads/

> 今回は、2019年版をインストール。
> インストール時に「C++ ワークロードを使用したデスクトップ開発」を必ず選択してください。

の注意点の通りです。


## 2. CUDA 11.0のインストール

以下のURLから、CUDAの11.0 (cuda_11.0.2_451.48_win10.exe)をダウンロードします。
network版でもローカル版でもどちらでも大丈夫だと思います。

> https://developer.nvidia.com/cuda-11.0-download-archive?target_os=Windows&target_arch=x86_64&target_version=10

インストールは基本Yesで問題なかったです。

デフォルトであれば、
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0
にディレクトリが生成されます。



## 3. cudnnのダウンロード

> https://developer.nvidia.com/rdp/cudnn-archive

から、

* Download cuDNN v8.0.5 (November 9th, 2020), for CUDA 11.0　タブの
* cuDNN Library for Windows (x86)　をクリックして
* cudnn-11.0-windows-x64-v8.0.5.39.zipをダウンロード

します。アカウント登録が必要です。

zipを解凍して、中身をCUDAがインストールされているディレクトリ
(C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0)にコピペします。



## 4. Anaconda環境でtensorflow-gpuとkerasのインストール

### 4.1 Anacondaのインストール
> https://www.anaconda.com/products/individual

のDownloadボタンからanacondaをダウンロードします。

すべてデフォルトでインストールしました。


インストール後、WindowsメニューなどからAnaconda Promptを立ち上げます。


### 4.2 仮想環境の構築

ここでは、仮想環境名をkeras-gpuとしました。

まずは、pythonのバージョン3.8を指定して仮想環境を構築します。

```
conda create -n keras-gpu python==3.8
```

その後

```
conda activate keras-gpu
```

で、仮想環境に入ります。
以降では、仮想環境に必要なパッケージをインストールしていきます。

```
pip install tensorflow-gpu==2.4.0
pip install keras
conda isntall pandas
conda install matplotlib
conda install spyder
```

ここで、重要な点は、tensorflow-gpuとkerasはpip経由でインストールすることです。
他の方が記載されている通り、
conda経由でインストールした場合、GPUが認識されませんでした。

pandas, matplotlib, spyderは趣味です。


### 4.3 GPUの動作確認

pythonコンソールないしは、spyderを立ち上げて、
以下のコマンドを実行します。


```
from tensorflow.python.client import device_lib
device_lib.list_local_devices()
```

実行結果に、

```
name: "/device:GPU:0"
 device_type: "GPU"
```

のような記載があれば、GPUが認識されています。


詳細は以下の方の記事の通りです：
> [TensorFlowからGPUが認識できているかを2行コードで確認する](https://thr3a.hatenablog.com/entry/20180113/1515820265)


# 5. RTX3070における実行時の注意点

インストールまでは完了したのですが、このままでは実行時にエラーがでてしまいます。
その回避方法について調査しました。


## 5.1 実行時エラーの回避
Denseレイヤー以外の複雑なレイヤーを使おうとすると、以下の実行時エラーが発生しました。

> Failed to get convolution algorithm. This is probably because cuDNN failed to initialize, so try looking to see if a warning log message was printed above.


https://github.com/tensorflow/tensorflow/issues/46209 の書き込みによれば、

> Add this to the start of your code
>
> physical_devices = tf.config.list_physical_devices('GPU')
> tf.config.experimental.set_memory_growth(physical_devices[0], True)

とのことで、kerasなどのインポートの前、コードの最初に
GPUのメモリ使用量を抑えることで、回避できるようです。

CUDAとcudnnのバージョンの組み合わせを間違っていても、
同じような文言のエラーがでるようでだいぶ試行錯誤

参考：
> [tensorflow2.0 + kerasでGPUメモリの使用量を抑える方法](https://qiita.com/studio_haneya/items/4dfaf2fb2ac44818e7e0)

## 5.2 GPUの無効化（速度比較を行うため、※おまけです）


> [TensorFlow、Kerasで機械学習する際にGPUを無効化する](https://itips.krsw.biz/tensorflow-keras-gpu-deactivate/)
> [Jupyter上でKerasを使うときにGPUを無効化する方法](https://pcyaranaika.com/blog/machine-learning/how-to-disable-gpu-with-keras-on-jupyter.html)

の方たちが記載されている通り、

```
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
import keras
```

のコードで、Kerasをインポートする前に環境変数でGPUを無効化することで、CPUのみを使ってコードを実行できます。


## 5.3 動作確認

タスクマネージャーのパフォーマンスタブのGPUの項目を表示します。
右側のパネルの中のグラフの１つで、上部の表示項目（3DとかCopyとか）を
Cudaに変更します。

これで、CUDAを動作させた時の負荷をグラフで確認できます。



# Warningを除去するための追加手順

これまでの手順でも問題なく動いているようですが、
初回実行時（GPUの立ち上げ時）に以下のwarningがたくさん表示されます。


> SubProcess ended with return code: 4294967295

https://github.com/tensorflow/tensorflow/issues/45170
での記載によれば、

> The SubProcess ended with return code: 4294967295 error is most likely relates to PTX compiler (ptxas.exe) not supporting your GPU (sm_86) in CUDA <= 11.0.

とのことで、

> copy C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\bin\ptxas.exe into C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0\bin\ptxas.exe.

で解決できる、とのことでした。

以下では、この解決策を実行するための手順について述べます。




## 6. CUDA 11.1.1のダウンロードとインストール

>https://developer.nvidia.com/cuda-11.1.1-download-archive?target_os=Windows&target_arch=x86_64&target_version=10

C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA
直下に、v11.1が生成されます。

v11.1/bin/ptxas.exeをコピーして、どこかに退避しておきます。


## 7. CUDA v11.1のアンインストール

プログラムの追加と削除から、CUDAのv11.1をアンインストールします。
6個のコンポーネントがありますので、個別にアンインストールしていきます。
※v11.0のコンポーネントをアンインストールしないように注意してください。

* NVIDIA CUDA Development 11.1
* NVIDIA CUDA Document 11.1
* NVIDIA CUDA Nsight NVTX 11.1
* NVIDIA CUDA Runtime 11.1
* NVIDIA CUDA Samples 11.1
* NVIDIA CUDA Visual Studio Integration 11.1

※ここでは、容量節約のために削除していますが、
　環境変数の切り替えなどで対処可能なんじゃないかなーとは思います。


※もっと良い解決方法をご存じの方がいらっしゃったら、ご教示いただければ幸いです

## 8. ptxas.exeの上書き

C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0\bin\ptxas.exe
と退避しておいたv11.1のptxas.exeを差し替えます。

終わったら再起動すると吉です。



# おわりに
以上の手順で、今のところうまく動かせるようになりました。
プログラムにもよるのでしょうが、

CPU利用時 936[s]
GPU利用時 104[s]

のように、9倍近く処理時間が短縮されました。

この記事が、誰かのお役に立てば幸いです。