Windows上でDockerを使ってKaggle環境(GPU版)を構築する

#まえおき

今までKaggleの計算環境として、Kaggle notebookやgoogle colab、GCPを使っていましたが、VRAMに限界を感じてきたため、ローカルPCを新調(RTX3090搭載PC)することにしました。GCPの無料クレジットが切れてしまうタイミングで、年末年始の購買欲が後押しして奮発してしまいましたが後悔はありません。

さて、ローカルPCを使用する場合、環境構築をしなくてはなりません。
一応、今までのPCではAnacondaを使って、必要なライブラリは適宜インストールして使ってきましたが、PC新調に伴った環境再構築が面倒だったので、この際Dockerを使ってみることにしました。
ただ、Windowsも使いたくて、デュアルブートにも抵抗があったのでWSL2から構築することにしました。

WindowsでのDockerを使った環境構築の際に色々と詰まった点もあったので、次回以降スムーズに構築できよう作業手順をまとめておきます。
※今回の方法はDocker for windowsを使用しない方法です

#ステップ0：Windows 10 Insider Preview Build 20150 のインストール
https://docs.nvidia.com/cuda/wsl-user-guide/index.html#getting-started
を参考にして、Windows 10 Insider Preview Build 20150 (以降) をインストールしておきます。


#ステップ1：WSL2の導入
MicrosoftストアでUbuntu 20.04 LTSをインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701901/f33ea2b9-22d8-72d0-3ccf-7202ef91b191.png)

Ubuntu 20.04 LTSを起動した後、
アカウント名とパスワードを入力してUbuntuの新しいアカウントを作成します。

下記コマンドにより最新の状態に更新します。

```ruby:Ubuntu
> sudo apt update && sudo apt upgrade -y
```

PowerShellを起動し、WSLを有効にします。

```ruby:PowerShell
> dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
```

仮想マシンプラットフォームを有効にします。

```ruby:PowerShell
> dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
```

ここで一旦PCを再起動します。

WSL2をデフォルト設定にします。

```ruby:PowerShell
> wsl --set-default-version 2
```

ubuntu上で下記コマンドを入力し、WSL2が正しく動作しているか確認します。

```ruby:Ubuntu
> uname -r
```
5.4.91-microsoft-standard-WSL2と出力されれば成功です。
WSL2の表示がない場合は、
[設定]>[更新とセキュリティ]>[Windows Update]>[詳細オプション]からWindowsの更新時に他のMicrosoft製品の更新プログラムを受け取るがオンになってるか確認してください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701901/ca1218d6-8bc7-007f-ea35-205334fd98cc.png)

その後、アップデートしてみてください。

```ruby:Ubuntu
> wsl.exe --update
```

#ステップ2：NVIDIA Drivers のインストール

以下のリンクから、NVIDIA Driverをインストールします。
https://developer.nvidia.com/cuda/wsl

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701901/59829c4a-af40-99ad-981d-bb3fd7814c43.png)

私の場合はRTX3090なので、GEFORCE DRIVERの方をインストールします。
NVIDIAアカウント持っていない場合は「Join now」を選択しアカウントを作成してください。
インストール完了後は、PCの再起動が必要です。

Ubuntu上でもドライバーをインストールしておきます。

```ruby:Ubuntu
> sudo apt -y install nvidia-driver-460
```


#ステップ3：CUDA Toolkit のインストール

```ruby:Ubuntu
> sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub
sudo sh -c 'echo "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64 /" > /etc/apt/sources.list.d/cuda.list'
sudo apt-get update
sudo apt-get install -y cuda-toolkit-11-2
```
※CUDA Toolkit のバージョン はお使いのGPUによって異なります

nvidia-smiコマンドでGPUを認識しているか確認します。

```ruby:Ubuntu
> nvidia-smi
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701901/76803df2-9e6e-1d4a-a06a-b0b78627683e.png)

CUDA11.2をインストールしたつもりなのですが、表示が11.3になっています。
（一応これでもGPUが動作しました）

認識できていない場合は、driverかCUDAのバージョンが間違っていたり、混在している可能性があります。
一旦すべてアンインストールしてやり直しましょう。


#ステップ4：Docker のインストール

```ruby:Ubuntu
> curl https://get.docker.com | sh
```
インストール完了まで数分要します。

#ステップ5：Nvida Container Toolkit のインストール
```ruby:Ubuntu
> distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
curl -s -L https://nvidia.github.io/libnvidia-container/experimental/$distribution/libnvidia-container-experimental.list | sudo tee /etc/apt/sources.list.d/libnvidia-container-experimental.list
```

Nvidiaランタイムをインストールします。

```ruby:Ubuntu
> sudo apt-get update
sudo apt-get install -y nvidia-docker2
```

#ステップ6：Kaggleイメージの構築

Docokeを起動します。

```ruby:Ubuntu
> sudo service docker start
```
※Dockerのアクセス権限が下りない場合は以下コマンドを実行し、自分のアカウントを追加します

```ruby:Ubuntu
>sudo gpasswd -a hoge docker
```

Kaggle公式のdockerイメージをビルドします

```ruby:Ubuntu
>
# https://github.com/Kaggle/docker-python
git clone https://github.com/Kaggle/docker-python.git
cd docker-python

# GPU版のビルド
./build --gpu
```

以上で、DockerからKaggleイメージをビルドすることができるようになりました。
後は、Jupyter notebookなり何なりからモデルを作成し、GPUを使って学習を行っていきます。


#番外編：環境構築に失敗してしまう場合の手引き
うまく環境構築ができなかったり、インストールしたソフトのバージョン管理ができなくなった場合や更新等でエラーが起きてしまうようになった場合は以下のコマンドで一旦全部削除してからやり直してみましょう。

```ruby:Ubuntu
#nvidia系削除
> sudo apt-get --purge remove nvidia-*
#cuda削除
sudo apt-get --purge remove cuda-*
#cuda系削除
sudo apt purge cuda*
sudo apt purge nvidia-cuda-*
sudo apt purge libcuda*
sudo apt-get purge "libcudnn8*"
sudo rm -rf /usr/local/cuda*
#cudnn削除
sudo apt-get --purge remove cudnn*

sudo apt autoremove
```

DockerにGPUが乗らない場合は以下のコマンドを実行します。

```ruby:Ubuntu
> distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
curl -s -L https://nvidia.github.io/libnvidia-container/experimental/$distribution/libnvidia-container-experimental.list | sudo tee /etc/apt/sources.list.d/libnvidia-container-experimental.list

> sudo apt-get update
sudo apt-get install -y nvidia-docker2
sudo usermod -aG docker $USER
sudo service docker restart
```

#参考にした記事
WSL2 + Ubuntu 20.04 + Docker 開発環境構築
https://qiita.com/amenoyoya/items/ca9210593395dbfc8531

WSL2の初歩メモ
https://qiita.com/rubytomato@github/items/a290ecef2ea86ea8350f

ついにWSL2+docker+GPUを動かせるようになったらしいので試してみる
https://qiita.com/yamatia/items/a70cbb7d8f5101dc76e9

GCPとkaggle公式イメージ(docker)でGPU環境の構築
https://qiita.com/taiga518/items/b69de2e00936e48578b0