Windows 11のWSLとDocker DesktopとGPUを使用したDeepLearning環境の構築方法（超便利になった！！）

今回は、Windows 11 の Deep Learning環境作成方法の紹介です。(Windows 10 21H2以降でも動くようになりました）

過去の記事

https://qiita.com/kekekekenta/items/ad737c8de0eb9609f991

今まで紹介してきたWindowsのDeepLearning環境の構成とガラッと変わって、コンテナからNVIDIAのGPUを使う方法を紹介します。これで公開されているDeepLearning向けのコンテナをサックっと起動して素早くDeep Learningの環境を手に入れることができます。やったー。


# WSLでCUDAを使うためのWindowsドライバをインストールする
最新のwindows版 CUDA Toolkitを以下のURLからダウンロードしてインストールします。

https://developer.nvidia.com/cuda-downloads?target_os=Windows&target_arch=x86_64

WSL 2 からCUDAを使うことができるようになります。

# Docker Desktopをインストールする
次に、Docker Desktopを以下のURLからダウンロードしてインストールします。

https://www.docker.com/products/docker-desktop

これで準備は完了です！
Docker Desktopがnvidia-dockerに対応したため、コンテナ上からCUDAを使うことができます。以下のURLは紹介の記事。

https://www.docker.com/blog/wsl-2-gpu-support-for-docker-desktop-on-nvidia-gpus/

# UbuntuでCUDAが使えるか確認してみる

NVIDIAのCUDAコンテナを起動して、nvidia-smiを実行してみます。このコンテナは、ご自身でTensorFlowやPyTorchをインストールするときに便利なコンテナです。

コマンド（PowerShellかCommandから実行してください。以下はCUDA11.6がインストールされたUbuntu 20.04を指定）

```
docker run -it --gpus=all --rm nvidia/cuda:11.6.0-base-ubuntu20.04 nvidia-smi
```

実行結果

```
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 510.00       Driver Version: 510.06       CUDA Version: 11.6     |
|-------------------------------+----------------------+----------------------+
| 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  NVIDIA GeForce ...  On   | 00000000:01:00.0  On |                  N/A |
| 30%   30C    P8    31W / 350W |   1187MiB / 24576MiB |     N/A      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+
```

フレームワークによっては対応しているCUDAのバージョンが異なるため、使いたいバージョンのCUDAをコンテナのタグで指定するだけで使うことができます。CUDAとcuDNNの再インストールが不要になりました。以下のURLから使いたいバージョンとOSを見つけてコンテナのタグに指定するだけです。

https://hub.docker.com/r/nvidia/cuda/tags

# TensorFlowでCUDAが使えるか確認してみる

TensorFlowもコンテナから使うだけです。インストールは必要ありません。

コマンド（PowerShellかCommandから実行してください。以下は最新のコンテナを指定）

```
docker run --gpus all -it --rm tensorflow/tensorflow:latest-gpu python -c "from tensorflow.python.client import device_lib; import os; os.environ['TF_CPP_MIN_LOG_LEVEL']='1'; print(device_lib.list_local_devices())"
```

実行結果

```
[name: "/device:CPU:0"
device_type: "CPU"
memory_limit: 268435456
locality {
}
incarnation: 7510238269992894143
xla_global_id: -1
, name: "/device:GPU:0"
device_type: "GPU"
memory_limit: 22681550848
locality {
  bus_id: 1
  links {
  }
}
incarnation: 3708138668520980036
physical_device_desc: "device: 0, name: NVIDIA GeForce RTX 3090, pci bus id: 0000:01:00.0, compute capability: 8.6"
xla_global_id: 416903419
]
```

以下のURLを参考にバージョンを指定できます。

https://hub.docker.com/r/tensorflow/tensorflow/tags

他に、NVIDIAが提供しているNGCのTensorFlowを使うこともできます。tf1はVersion 1系、tf2はVersion 2系ですね。

https://catalog.ngc.nvidia.com/orgs/nvidia/containers/tensorflow/tags

# PyTorchでCUDAが使えるか確認してみる

PyTorchもコンテナから使うだけです。インストールは必要ありません。

コマンド（PowerShellかCommandから実行してください。以下はNGCのコンテナを指定）

```
docker run --gpus all -it --rm nvcr.io/nvidia/pytorch:21.12-py3 python -c "import torch; print('version={}\ncuda is available={}\ncuda device count={}'.format(torch.__version__, torch.cuda.is_available(), torch.cuda.device_count()))"
```

実行結果（一部抜粋）

```
version=1.11.0a0+b6df043
cuda is available=True
cuda device count=1
```

以下のURLを参考にバージョンを指定できます。

https://catalog.ngc.nvidia.com/orgs/nvidia/containers/pytorch/tags

# 実際にプログラムを実行するには

コンテナに慣れた人であれば特に説明は不要だと思いますが、コンテナを起動するときはWindowsのフォルダをマウントすることをお勧めします。マウントしたフォルダでプログラムを編集します。

## Jupyter Notebookを使う
Jupyter Notebookを使う方はポート転送の設定もした方がよいでしょう。

以下のTensorFlow起動では、bashを実行しています。また、WindowsのD:\workフォルダをコンテナの/workにマウント設定して、コンテナの8888ポートをWindowsの8888ポートに転送しています。

```
docker run --gpus all -it -p 8888:8888 -v D:\work:/work nvcr.io/nvidia/tensorflow:21.12-tf2-py3 bash
```

起動後、Jupyter Notebookを起動した後に表示される以下のようなURLを参考に、WindowsのブラウザでJupyter Notebookにアクセスすることができます。

```
jupyter notebook

.
.
.

    Or copy and paste this URL:
        http://hostname:8888/?token=9271c7732acb2837f7ed17c2d4033c8978a6a61a696c2e3a
```

ブラウザでアクセスする際は、hostnameと書かれているところは、localhostに変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32580/633e99d7-a7d6-792f-12b0-7ff608d2b855.png)

## Visual Studio Codeを使う

VSCodeのRemote Developent（Remote - Contaners）プラグインを使うとVisual Studio Codeからコンテナにアタッチしてファイル編集やターミナルやデバッグを使うことができます。（ファイルの編集だけならこのプラグインを使う必要はありません。マウントされているファイルを直接編集できます。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32580/4fd48b01-75b2-5cec-1219-e4c490abadb9.png)

プラグインをインストールしたら、左下をクリックして、コンテナへのアタッチを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32580/04a1343f-0f27-31f8-bcae-640399b8607f.png)

# さいごに
Linux向けにしか提供されていなかったパッケージもこれで難なく動かすことができるようになりましたね。
超便利になった。WSL、CUDA on WSL、Docker Desktop最高！！