ようやくゲームしながらUbuntuコンテナで機械学習もできる最高や!、と考え
WSL2にGPU入れようとしたら詰まって色々調べたのでまとめた。
大まかにCUDA公式のリファレンスに沿って既存の環境から構築しようとしてダメだった部分を載せていきます。
docker desktop
との共存は現時点(2020/07/16)では諦めた方が早いです。
前提となる環境
6月18日のアナウンス以降のwindows insider programでWSL2からGPUを叩けるようになった。
実際に使用するためには下記の環境が必要となる。
- windows 10 : ビルド番号 20150.1000以降
- WSL2: 4.19.121以降
- cudaドライバ: 455.41_gameready_win10系列
- docker(WSL上): 19.03以降
このうち、May 2020 Update以前のinsider programでWSL2+dockerが使える状態からGPU
を有効にしようとすると色々つまづいたので対処した内容も含めて導入部を書き綴っていくことにする。
windows側
インストーラーでガシガシインストールしていく。
windows10 20150以降のインストール
現状だと windows10 の 20150以降のバージョンは insider program をファスト(最近だとdevチャネル)に合わせてインストールする。
導入自体は直接躓くことは無かったことと分量が多くなるため、割愛する。
参考元:
Windows10 Insider Program で最新バージョンにアップデートする方法
windowsにCUDAドライバをインストールする
WSL2でCUDAドライバを利用するにはNVIDIA Drivers for CUDA on WSL
を使用する必要がある。
NVIDIA Drivers for CUDA on WSLのページからexeファイルをダウンロードし実行する。
NVIDIA Developer Program に登録しておく必要があるので Nvidiaアカウントを作成・ログインしておく。
455.41_gameready_win10~
が落ちてくるので必然的にCUDA11が入る。プレビュー版であるためドライバダウンロードページで検索できるドライバよりも大きいバージョンのものが落ちてくる。
インストール完了後におそらくPCの再起動を促されるので、そのまま再起動しよう。
windows側にドライバがインストールできれば、WSL2側にCUDAドライバを入れる必要はない
WSL2 Linuxカーネルの更新
WSL2のカーネルもinsiderで最新なもの(4.19.121以降)じゃないと対応してない。
少し前まで手動で「WSL 2 Linux カーネルの更新」から最新カーネルをインストールする必要があったのだが
最近だと、WSL2のカーネルのアップデートが「更新プログラムのチェック」での実行対象になったため、
「設定」->「更新とセキュリティ」->「詳細オプション」->「Windows の更新時に他の Microsoft 製品の更新プログラムを受け取る」
をオンすることで最新のカーネルをインストールできるようになった。
「更新プログラムのチェック」からのインストール完了した後は
プロンプト上でwsl --update
を実行すれば最新カーネルをインストールできる。
のだが、自分の環境だと更新直後にGSoDに直行し起動後にwslコマンドが実行できない状態になった。。
再度、「WSL 2 Linux カーネルの更新」からインストーラを実行し直すことで事なきを得ました。。
参考元:
WSL2側
Ubuntu18.04
を起動しCUIで操作していく。
WSL2上にdockerをインストール
今回の最大ハマりポイント。
今回のようにWSL2上でGPUを使いたい場合はWSL2上に一からdocker 19.03
以降を導入する必要がある。
ここで注意する必要がある点としてdocker desktop on windows
のbackend を利用をしない ということである。
ハマった要因
自分が元々使っていた環境の場合だと、docker desktopと連携してWSL上でもdocker操作できるようにしていた。
公式の手順にもあるUse WSL 2 based engine
の項目をチェックして
docker desktop
のsettingの項目からResouce -> WSL integrate
の項目を有効にして使用する方法だ。
しかしながら、docker desktop
との連携を切っておかないと衝突して、docker desktop
が起動失敗->GSoD->windows強制再起動コンボが頻発する羽目になった。Insider Preview Build 20150
初期マイナーバージョンだとGSoD後の自動再起動すらしない状態に。。
Docker Desktop WSL 2 backendの無効化
docker desktop
の状態をWSL側と共有する必要が無い場合は、上記の公式の手順で有効にした項目を全て無効にし、WSL上でdockerに関するエイリアスなどを貼っているならこれも無効にする必要がある。
もしくはdocker desktop
のswitch to Windows Containeres...
をクリックしてWSL側との連携を切ることもできる。
インストール
docker desktop
との連携が切れていることを確認できれば最新のdockerをWSL2にインストールする。
基本的にはdocker公式の手順通り。
sudo apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu\
$(lsb_release -cs) \
stable"
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
sudo usermod -aG docker $USER
sudo mkdir /sys/fs/cgroup/systemd
sudo mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd
dockerをrestartさせても設定が反映されないことがある。
その場合はCUIを一度再起動してやる。
動作確認
無事インストールできたか下記コマンドで確認する。
sudo docker run hello-world
powershell
を立ち上げてdesktop docker
側にhello-world
イメージが存在していない事を確認できれば尚良し
wsl上のUbuntuに cuda toolkit を導入
win上にインストールしたCUDAを仮想的に使用するため、WSL2にはCUDAドライバをインストールする必要はないものの
WSL2上でもCUDAを使うためにcuda-toolkit
を導入する必要がある。
折角windows側に最新のCUDA11が入っているのでこれに合わせる事とする。
そのためにはWSL2側でcuda-toolkit
の最新版をインストールすればよい。
対話的な処理でもいいならrunファイルを実行し、cuda-toolkit
の項目だけ選択してインストールするのが多分一番簡単。
ただ、個人的になるべくスクリプトファイルを叩いた後は操作したくないためaptでインストールできるようにしていく。
nvidiaのCUDAダウンロードサイトのスクリプト利用してインストールする。
肝はcuda
やcuda-driver
じゃなくて cuda-toolkit-11-0
を指定すること
sudo apt-get --purge remove nvidia-*
sudo apt-get --purge remove cuda-*
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin
sudo mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600
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 -y
sudo apt-get upgrade -y
sudo apt-get install -y cuda-toolkit-11-0
あとは使用しているシェルにPATHを追記して適用すればOK
echo "set -x PATH /usr/local/cuda-11.0/bin \$PATH" >> .config/fish/config.fish
echo "set -x LD_LIBRARY_PATH /usr/local/cuda-11.0/lib64 \$LD_LIBRARY_PATH" >> .config/fish/config.fish
source .config/fish/config.fish
動作確認
インストールが完了すれば/usr/local/cuda/
にSample含め展開される。
下記のサンプルを実行してやれば、GPUデバイスが認識できるかどうかが確認できる。
cd /usr/local/cuda/samples/4_Finance/BlackScholes
sudo make
./BlackScholes
nvidia-container-toolkit のインストール
nvidia dockerを動かすためにnvidia-container-toolkitを導入していく。
'Docker Desktop WSL 2 backend'経由だとGPUサポートされていないため、WSL2のlinux上でnvidia-container-toolkit
かnvidia-docker2
を使用して使う必要がある。
将来的にnvidia-docker2が廃止される予定みたいなので今回はnvidia-container-toolkit
をインストールする。
Nvidia-containerのQuickstartを元にしながら入れていく。
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-container-toolkit
sudo service docker restart
WSL2ではそのままだとsystemdが使えないためsystemctlが使えない。Quickstartの最後の行はserviceコマンドに置き換えた。
参考元:
nvidiaのフォーラム
【WSL2】systemctlが動かない問題をきちんと解決する
動作確認
これで漸く、nvidia-dockerがWSL2でも実行できるようになったはずだ。
下記コマンドを実行して確認する
docker run --gpus all nvcr.io/nvidia/k8s/cuda-sample:nbody nbody -gpu -benchmark
...
> Windowed mode
> Simulation data stored in video memory
> Single precision floating point simulation > 1 Devices used for simulation
MapSMtoCores for SM 7.5 is undefined. Default to use 64 Cores/SM
GPU Device 0: "GeForce RTX 2060 SUPER" with compute capability 7.5
> Compute 7.5 CUDA device: [GeForce RTX 2060 SUPER]
34816 bodies, total time for 10 iterations: 56.069 ms
= 216.188 billion interactions per second
= 4323.764 single-precision GFLOP/s at 20 flops per interaction
GPUが認識できたようだ。これでやっと機械学習ができる環境が整った訳である。
(Compute 7.5 CUDA device
ってなんだ?と調べたところハードウェア側のバージョンを表示しているようだ。GeForce RTX 2060 SUPERはTuringアーキテクチャを採用しているので7.5となる。ソフトウェアのCUDAのバージョンかと思い焦ったのは内緒)
https://docs.nvidia.com/deploy/cuda-compatibility/index.html#support-title
docker実行時にエラーが出た場合
もし、上記コマンドを実行した際にエラーが出てdockerイメージを実行できない場合は
-
docker desktop
にイメージが作られていないか確認- 作られていれば連携している状態にあるので解除
- WSL2からGPUが認識できているか確認
- cudaサンプルコードを再実行してみる
- 認識できなければ再インストール
- 認識できている場合は
docker desktop
を使おうとしてないか確認
- docker のオプションとして
--gpu
が利用可能か確認する- dockerバージョンを確認する(19.03以前にはこのコマンドは存在しない)
-
/usr/bin/nvidia-container-toolkit
が存在する確認
以上を確認する。
docker・nvidia-dockerのバージョンが古い
docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused
"process_linux.go:402: container init caused \"process_linux.go:385: running prestart hook 1 caused
...
...
エラーをざっくり解釈すると、指定したコマンドが間違っていたりした時に出るエラーのようで、
--gpus
オプションが使えない、dockerバージョン(19.03以前)だったりnvidia-docker
を使って実行しようとした時に出る模様。
各々のバージョンをアップグレードしよう。
Upgrading with nvidia-docker2 (Deprecated)
GPUが認識できていない場合
docker: Error response from daemon: linux runtime spec devices: could not select device driver "" with capabilities: [[gpu]].
docker実行時のコマンド自体は合っているが、GPUが見つからず落ちる場合。
サンプルを実行し直して認識できていなければ再インストールしよう。
ちなみに、nvidia-dockerがサポートされていないwindowsで直接実行しても似たようなエラーが得られる。
docker: Error response from daemon: could not select device driver "" with capabilities: [[gpu]]
docker desktop
をbackendとして使用している場合もこのエラーが出るため中々原因に気付けなかった。。
docker desktop
との連携が有効になっていないか確認しよう。
参考元:
NVIDIA Docker って今どうなってるの? (19.11版)
nvidia-dockerのwiki
今回の内容をgitでまとめました -> https://github.com/naka345/wsl2_gpu
やることが...やることが多い...!!