CUDA on WSL2の速度比較と環境構築

この記事は「[【マイスター・ギルド】本物のAdvent Calendar 2021](https://adventar.org/calendars/6579)」9日目の記事です。

CUDA on WSL2で機械学習環境を構築した場合に速度を落とさずに学習できるのかが気になったので、調べてみました。機械学習環境を構築する際の助けになれば幸いです。

# はじめに
本記事では、[CUDA on WSL2](https://docs.nvidia.com/cuda/wsl-user-guide/index.html)環境で機械学習をする場合と、Ubuntu直接環境(Ubuntuを直接インストールした環境)で機械学習をする場合の速度比較を行います。
また、その前段階として。2021年11月時点でのCUDA on WSL2の環境構築手順も記載します。

以下の順序で記載します。
1. WSL2のインストール
2. Windows11にアップグレード
3. CUDA導入
4. Pytorch環境構築
5. 速度比較

速度比較の結果だけ見たいんだ！という方は、[5. 速度比較](#5-速度比較)まで飛んでください。


# 開発環境
* CPU：Intel Core i5-10400
* GPU：GeForce RTX 2060
* RAM：8.0GB
* OS：Windows10 21H1(OSビルド：19043.1348) ※手順の途中でWindows11に変わります

# 1.WSL2のインストール
## 1.1. Windowsの機能の有効化
1) コントロールパネルから[プログラム] > [Windowsの機能の有効化または無効化]を選択する。
2) 「Linux用Windowsサブシステム」と「仮想マシン プラットフォーム」を有効にする。
![スクリーンショット 2021-11-27 094717_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438288/5bbb171b-eca7-230f-adca-fce91cd2a04e.jpeg)
3) PCを再起動する。

## 1.2. WSL2にUbuntuをインストール
1)  [WSL2 Linux カーネルの更新ページ](https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi)から、WSL2用Linuxカーネルをダウンロードして、インストールする。
![スクリーンショット 2021-11-11 220614.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438288/ff94dee2-adca-199b-7716-e5495de7c0b8.jpeg)
![スクリーンショット 2021-11-11 220628.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438288/09cb61b4-9520-8d81-d90e-f0814bc1b96a.jpeg)

2)  WSL 2を既定のバージョンとして設定する。
コマンドプロンプト等で以下を入力する。

```
wsl --set-default-version 2
```
3) Microsoft Storeから Linuxディストリビューションをインストールする。
![スクリーンショット 2021-11-11 221030.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438288/a5900a5f-92a1-c75a-1f46-1fd1648aeeae.jpeg)

4)「Ubuntu 20.04 LTS」を選択する。
![スクリーンショット 2021-11-11 221208.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438288/70bbf380-ed28-f961-a35b-7c340b913ceb.jpeg)

5)  初回起動時にのみユーザー名とパスワードを設定する。


# 2.Windows11にアップグレード
WSL2上でCUDAを使用するためには、Windowsのビルドバージョンを20145以上にする必要があります。
以前はWindows Insiderに登録する必要がありましたが、2021年11月時点ではWindows11にアップグレードするだけでOKです。
![スクリーンショット 2021-12-11 003738_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438288/7e037590-092b-65e1-9d85-2db155c3ee1b.jpeg)


# 3.CUDA導入
## 3.1.ドライバアップデート
https://developer.nvidia.com/cuda/wsl からドライバをダウンロードし、インストールする。

## 3.2.CUDA on WSL2をインストール
1) 以下にアクセスする。
https://developer.nvidia.com/cuda-downloads

2) [Linux] - [x86_64] - [WSL-Ubuntu] - [2.0] - [deb(local)] を選択する。
![スクリーンショット 2021-11-12 004038 CUDA WSL.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438288/2ee40a76-9b0e-a1a8-3db8-ff442cc04a29.jpeg)

3) インストールコマンドが表示されるので、Ubuntuを起動し、Ubuntu上でインストールする。

## 3.3.cuDNNをインストール
1) 以下にアクセスする。会員登録が必要です。
https://developer.nvidia.com/rdp/cudnn-download

2) Windows上で以下の2つをダウンロードして、任意のフォルダ(例として`C:\temp`とする)に保存する。
・cuDNN Runtime Library for Ubuntu20.04 x86_64 (Deb)
・cuDNN Developer Library for Ubuntu20.04 x86_64 (Deb)

3) UbuntuからWindowsのフォルダは`/mnt/c/temp`で参照できるので、Ubuntuから以下のコマンドで RuntimeとDeveloperをインストールする。

``` console
$ sudo dpkg -i /mnt/c/temp/libcudnn8_8.3.0.98-1+cuda11.5_amd64.deb
```

※2021/11/22リリースのv8.3.1からRuntimeとDeveloperがなくなって、1ファイルになっているようです。「Local Installer for Ubuntu20.04 x86_64 (Deb)」をダウンロードすれば大丈夫だと思いますが、未確認です。

## 3.4. 動作確認
Ubuntu上で以下のコマンドで、GPUを認識していることを確認する。

``` console
$ sudo cp /usr/lib/wsl/lib/nvidia-smi /usr/bin
$ sudo chmod +x /usr/bin/nvidia-smi
$ nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 510.00       Driver Version: 496.49       CUDA Version: 11.5     |
|-------------------------------+----------------------+----------------------+
| 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 |
| 32%   34C    P8     8W / 160W |    593MiB /  6144MiB |     N/A      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

$ nvcc -V
NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2021 NVIDIA Corporation
Built on Mon_Sep_13_20:11:50_Pacific_Daylight_Time_2021
Cuda compilation tools, release 11.5, V11.5.50
```


# 4. Pytorch環境構築
Ubuntu上でPytorch環境を構築します。

## 4.1. venvで仮想環境を構築
``` console
$ sudo apt-get update
$ sudo apt install python3.8-venv
$ python3 -m venv pytorchenv
$ source pytorchenv/bin/activate
```
## 4.2. Pytorchをインストール
https://pytorch.org/ で表示されるコマンドでインストールを行う。
![スクリーンショット 2021-11-13 102748.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438288/9cea5383-2b8a-5607-c496-7b33b369b932.jpeg)

※ ダウンロード途中で頻繁に通信エラーになったため、ブラウザでダウンロードしてインストールしました。

```
$ pip3 install torch-1.8.2+cu111-cp38-cp38-linux_x86_64.whl
```

# 5. 速度比較
Python(Pytorch：MNIST)とC言語(darcknet)を対象に機械学習の速度の比較を行いました。それぞれ、3回試行の平均値です。

## テスト環境
### 共通
* CPU：Intel Core i5-10400
* GPU：GeForce RTX 2060
* RAM：8.0GB
* CUDA ： 11.5
* cuDNN ：8.3.0

### CUDA on WSL2環境
* OS：Windows11 Pro(21H2) + WSL2(Ubuntu 20.04 LTS)

### Ubuntu直接環境
* OS：Ubuntu 20.04 LTS

## 結果(Pytorch：MNIST)
* 学習対象：[PytorchのMNISTのサンプルプログラム](https://github.com/pytorch/examples/blob/master/mnist/main.py)
    * 14epoch分のトレーニング開始～終了までの時間(画像のダウンロード時間は含まない)
* Python：3.8
* Pytorch：1.8.2

| 環境     | 学習時間 | 
|:-----------|-------:|
| CUDA on WSL2環境  | 139.4秒   |
| Ubuntu直接環境     | 107.0秒   | 


【参考】
参考までに、Windows11で直接実行した場合、Windows11でGPUを使用しなかった場合、Google Colaboratoryを使った場合の時間です。

| 環境     | 学習時間 | 
|:-----------|-------:|
| Windows11(GPU使用)環境  | 146.6秒  | 
| Windows11(CPU使用)環境  | 1185.8秒  | 
| Colabo(Tesla K80)環境| 332.7秒|
Windows11(GPU使用)環境はCUDA on WSL2環境よりさらに遅かったです。

Colaboratoryは無償版では性能の劣るK80しか割り当たりませんでした。有償版のProができたので、無償版では性能のいいP4やT4は割り当たらないようですね。残念。

## 結果(darcknet)
* 学習対象：[AlexeyAB/darknet](https://github.com/AlexeyAB/darknet)(C言語で書かれた物体検出yoloアルゴリズム)
    * バッチサイズ：32
    * バッチの繰り返し回数：6000

| 環境     | 学習時間 | 
|:-----------|-------:|
| CUDA on WSL2環境  | 2時間8分   |
| Ubuntu直接環境     | 48分   | 


# まとめ
CUDA on WSL2環境はUbuntu直接環境より、Pytorch：MNISTで1.3倍、darcknetで2.6倍の時間がかかるという結果になりました。言語、ライブラリ、学習対象によって差異はあると思いますが、Ubuntu直接環境の方が学習速度は速そうです。
1.3倍程度だったとしても本格的に機械学習を行う場合は、数時間・数日かかることになると思うので、Ubuntu直接環境を構築した方が効率がいいかもしれません。

WindowsとUbuntuをデュアルブートで入れたい方は、以前に手順を記載したので、[【備忘録】Ubuntu 20.04 LTS + GPU 環境構築 (2021年3月版)](https://qiita.com/SwitchBlade/items/5d5bc645822229ee0ed9)をご参考ください。少し前の情報ですが、ほぼそのままの手順で構築可能だと思います。


# 参考にしたサイト
* [NVIDIA CUDA on WSL User Guide](https://developer.nvidia.com/cuda/wsl/download)
* [WSL2 + Ubuntu20.04 + CUDA 11.4 で TensorFlow 環境構築 (2021.08)](https://zenn.dev/ylabo0717/articles/48796b7f3470c7)
* [WindowsにWSL2をインストールしてLinux（Ubuntu）環境を構築する](https://www.4peace.co.jp/tech/569/)
* [WSL 2(Windows Subsystem for Linux 2)の違いとインストール方法](https://www.pc-koubou.jp/magazine/40465#section03)
* [待ってました CUDA on WSL 2](https://qiita.com/ksasaki/items/ee864abd74f95fea1efa)