CUDA + TensorFlow + Anaconda + Windowsで作る機械学習環境

# はじめに
ゲーミング用途などで高性能なGPUを持っている方の中にはそれらを活用して機械学習をやりたいと考える方も多いのではないでしょうか？
しかし、Linuxと比べWindows環境ではGPUを汎用的な計算機として使うためにはそれなりの手間がかかり、実際に機械学習のライブラリである[TensorFlowの公式サイト](https://www.tensorflow.org/install/docker?hl=ja)ではLinuxを使ってDockerイメージ(仮想環境)を導入することが推奨されています。
それでも幸いなことにWindows＋CUDAを利用している先駆者は多くいるので、充実しつつあるリファレンスをもとに今までよりも手軽にCUDAを導入することができるのではと思います。

本稿では、Anacondaで作成したPythonの仮想環境にTensorFlowやその他ライブラリを用意し機械学習を行うことを目標としています。



# 私の環境
### マシンスペック
- OS : Windows10 Pro
- CPU : AMD Ryzen 5 3500
- GPU : Nvidia Geforce GTX 1660 Super

### プログラミング環境/使用ツール
- Anaconda
    - 仮想環境 - Python3.6.12
- Microsoft Visual Studio 2019 Community
- GPUドライバのバージョン：460.79（自身のGPUに対応するドライバはこちらから確認できます([NVIDIA Driver Downloads](https://www.nvidia.com/Download/index.aspx))）

### 今回導入したもの
- CUDA Toolkit 10.1
- cuDNN 7.6.5
- TensorFlow 2.3.0



# 事前準備
- GPUドライバのクリーンインストール
    - すでに最新版のドライバをいれてる場合でも念の為にクリーンインストールを実行し、プロファイルを初期化するといいと思います。
   
- Visual Studioのインストール
    - 拡張機能であるNsight(GPUの状態を解析してくれる)を利用するために必要です。こだわりがなければ最新版のVisual Studio 2019で問題ないと思います。
またTensorFlowを自分でビルドして使いたいという方は[こちらの解説記事](https://www.kkaneko.jp/tools/win/vs2019.html)を参照しC++ビルドツールも一緒にインストールしてください(本稿では[すでにビルド済みのパッケージ](https://www.tensorflow.org/install/pip)をインストールすることだけを目的とします)



# バージョン対応関係
**[!重要!] Python, TensorFlow, CUDA, cuDNN, GPUドライバのバージョン対応関係の確認**
CUDAの導入ではこれらのバージョンを自身の環境と合わせ，決められた関係にきっちり対応させる必要があります。

- 基となる対応関係表はこちらを参照してください。[Windowsでのテスト済みのビルド構成(GPU)](https://www.tensorflow.org/install/source_windows#gpu)
- 基本的には導入したいTensorFlowとPythonのバージョンを基準とし、そこから上記表を参考にしながらCUDA、cuDNNのバージョンを決めていってください。
- 比較的新しめのGPUだと特に問題ないですが、GPUドライバとCUDAのバージョンも対応させる必要があるのでこちらから確認してください。[cuda-toolkit-release-notes](https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html#cuda-major-component-versions)
- 私の場合の最終的な導入例は下記の通りです。↓
- TensorFlow＝2.3.0 | Python=3.6.12 | cuDNN=7.6.5 | CUDA=10.1



# 導入の手順
1. **CUDA Toolkitのインストール**
[CUDA Toolkit Archive](https://developer.nvidia.com/cuda-toolkit-archive)
[バージョン対応関係](#バージョン対応関係)にて確認したCUDAのバージョンを上記リンク先から選択しダウンロードし、ダウンロードが終わったらインストールしてください。
無事インストールが完了したらシステム環境変数およびPathの内部にそれぞれ次のようなパスが自動で追加されているはずです。
変数名：「CUDA_PATH」値：「C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1」
変数名：「CUDA_PATH_v10_1」値：「C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1」
Path内部：
「C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\bin」
「C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\libnvvp」




2. **cuDNNのインストール**
[cuDNN Archive](https://developer.nvidia.com/rdp/cudnn-archive)
[バージョン対応関係](#バージョン対応関係)にて確認したcuDNNのバージョンを上記リンク先から選択しダウンロードしてください(Nvidiaアカウントを作成しログインする必要があります)。ダウンロードが終わったらzipを解凍し中身のフォルダを全てCUDAがインストールされているフォルダにコピペし上書きしてください。
そして今度は手動でシステム環境変数にパスを追加します。以下のパスを新規に入力・追加してください。
変数名：「CUDNN_PATH」値 ：「C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1」
>前述した[こちらの対応表](https://www.tensorflow.org/install/source_windows#gpu)にある最新のcuDNNのバージョンは7.4ですが、上記のリンク先にあるcuDNNのアーカイブを見るとCUDAのバージョンが10.0までしか対応していません。私は最初一つ上のバージョンである7.5を導入してみましたが、実際に学習を行おうとした際にエラーが出てしまい、試しにv7系で最も最新の7.6.5で行ったところ無事に成功しました。インストールがうまく行ったあとでも学習時にエラーがでるなどしたらcuDNNのバージョンを変更してみてください(フォルダを上書きするだけなので環境に影響はありません)。

3.　**再起動する**
ここで一旦PCを再起動させておきます。再起動しないとこの後の手順でパスが認識されない可能性があります。

4.　**TensorFlowをインストールする**
すでにビルド済みのTensorFlowライブラリをpipでインストールするだけです．過去にtensorflowをインストールした環境であれば先にアンインストールしてください。ライブラリの競合などでエラーがでる可能性もあるのでなるべく新しい仮想環境を作ってからインストールすることをおすすめします。
またバージョン2.1以降は「tensorflow」のみで[cpuとgpuを同時にサポート](https://www.tensorflow.org/install/pip#windows_1)します。それ以前のバージョンをインストールする場合は「tensorflow_gpu」のようにコマンドを入力してください。

```
pip install tensorflow_gpu
```

```tensorflow.v2.1~
pip install tensorflow
```

5.　**動作確認**

まずtensorflowがGPUを利用するために必要なDLLにパスが通っているか確認します。

```
where cudnn64_7.dll
```
つぎにtensorflowをつかう上で実際にGPUが認識されているか確認します。

```
python -c "from tensorflow.python.client import device_lib;print(device_lib.list_local_devices());"
```
上記のコードを実行し、各種DLLが正常に読み込まれ「device_type: “GPU”」と表示されれば成功です。(私の場合"XLA_GPU"と表示されましたが問題はなさそうです。なぜそう表示されるのかはわかりませんが…)
CPUと表示されてしまう場合はCUDAやcuDNNの導入に失敗している、またはGPUドライバやそれらのバージョンに間違いがある思われます。


# おわりに
私の場合、CUDAの導入は大変な苦労と時間をかけてなし得たものでした…．
以前に挑戦した際はLinux(Ubuntu)をWindows上の仮想環境(Hyper-V)にインストールした上で導入しようとしましたが、うまくいかずに挫折しました(仮想環境マシンとGPUの接続ができなかったのが原因のようでした)。
その他にもWSLを利用しようとInsider Programを導入したはいいものの、アーリー版ゆえにネットワークにつながらないという致命的なバグに見舞われるなど(PCの)生命の危機を感じたりもして紆余曲折がありました。
最終的には生のWindowsのシステムドライブにCUDAもろもろをインストールしたわけですが、これが一番シンプルでエラーも少ないやり方なのではないかと思います。

# 参考サイト
- NVIDIA公式の導入ガイド
[CUDA Installation Guide for Microsoft Windows](https://docs.nvidia.com/cuda/cuda-installation-guide-microsoft-windows/index.html)
- Tensorflow公式の導入ガイド
[TensorFlow 2 をインストールする](https://www.tensorflow.org/install/pip)
- https://www.kkaneko.jp/tools/win/cuda.html