Help us understand the problem. What is going on with this article?

待ってました CUDA on WSL2

※ 2020/07/27 WSL2 への CUDA Toolkit インストール時の注意点を追記しました。

エヌビディアの佐々木です。

2020 年 5 月の BUILD カンファレンスで発表されたとおり、WSL2 で CUDA が使えるようになったので、早速試してみました。手順は簡単で、私がこんな駄文にまとめる意味もないくらいですが、マイクロソフトとエヌビディア双方にドキュメントが分散していますので、かつてはマイクロソフトで Services for UNIX (SFU) / Subsystem for UNIX-based Applications (SUA) を、今はエヌビディアで GPU を売っている私が何か書いてみるのは一つの役割と言えましょう。え、そうでもない?

CUDA on WSL2 の環境構築 (Windows 側)

では、さっさと環境を作ってしまいましょう。手順の概略は CUDA on WSL User Guide に載っています。私が試した下記の内容もこのガイドに沿っています。

Windows 10 Insider Preview Build 20150 (以降) のインストール

良く訓練された Windows ユーザーなら、Insider Preview の Fast Ring (改め、Dev Channel) に参加しているはずなので、今朝 (日本では 2020 年 6月 18 日) 目が覚めたらもう Build 20150.1000 が降ってきていたはずです。インストールしましょう。

Insider Preview に参加していないユーザーにとっては、これに参加してインストールするまでが一番時間のかかるプロセスかもしれません。下図のように、Windows 10の「設定」から Windows Insider Preview の「ファスト」に参加してください。

ダウンロードとインストールにはそこそこ長い時間がかかります。どうにかそれが終わったら、コマンドプロンプトで ver コマンドを実行し、確かに 20150 (以降) がインストールされていることを確認しましょう。

C:\WINDOWS\system32>ver

Microsoft Windows [Version 10.0.20150.1000]

NVIDIA Drivers for CUDA on WSL のインストール

ホスト側 Windows の準備ができたら、次に NVIDIA ドライバをインストールします。このドライバ、WSL2 の Linux カーネル側 ではなく、ホストの Windows にインストールします。 CUDA on Windows Subsystem for Linux (WSL) - Public Preview のページから Get CUDA Driver を辿ってドライバのダウンロードページアクセスし、GeForce Driver か Quadro Driver のいずれかを自分の環境に合わせてダウンロードしてください。

「NVIDIA Developer Program Membership Required」と表示されたら「Login」してください。

え、アカウントをお持ちでない?!「Join now」お願いします。

インストール作業自体は、Windows へ NVIDIA ドライバをインストールするいつもの手順と変わりませんので、詳細は割愛します。私は全てデフォルトの選択肢で次へ次へと進みました。

インストール完了後は、Windows の再起動が必要です。

WSL2 のインストール

「仮想マシン プラットフォーム」の有効化

WSL2 を使うためには「仮想マシン プラットフォーム」という Windows の機能が必要です。これは「Windows の機能の有効化または無効化」画面でポチポチしても良いのですが、管理者権限で起動したコマンドプロンプトで、次のコマンドを実行すれば簡単です。
※ コマンドプロンプトを管理者権限で起動するには Win+R で「ファイル名を指定して実行」に cmd と入力し、[CTRL]+[SHIFT]+[ENTER] を押してください。

dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

この後、次のコマンドを実行して、この後インストールする Linux ディストリビューションが WSL2 で実行されるようにします。

wsl --set-default-version 2

Linux ディストリビューションのインストール

Windows 10 の Microsoft Store アプリから、お好みの WSL 用 Linux ディストリビューションをインストールします。私は Ubuntu-18.04 にしました。

Windows 側での作業は以上です。これで、WSL2 が使えるようになりました。Windows のスタートメニューから、先ほどインストールした Linux ディストリビューションのアイコンをクリックするなどして、シェルを起動すればそこはおなじみの Linux 環境です。

あとは通常の Linux 環境と(おおむね)同様に GPU を使えるのですが、下記のうちどちらの方法を使うかで必要な準備が変わってきますので、簡単に説明します。

  • WSL2 上で直接 CUDA プログラムを実行する。
  • WSL2 上で Docker と NVIDIA Container Toolkit を使って Docker コンテナで GPU を使う。

CUDA Toolkit のインストール

コンテナを使わずに、直接 CUDA プログラムを実行する場合は、WSL2 上の Linux に CUDA Toolkit をインストールすれば良いのですが、重要な注意点があります。

Linux 用の NVIDIA ドライバをインストールしてはいけません

つい、いつもの癖で sudo apt-get install cuda とやってしまいそうになりますが、 cuda-toolkit-<version> パッケージを指定してください。私が CUDA Toolkit version 11 をインストールするために、WSL2 上のシェルで実行したコマンドは次の通りです。

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-0

CUDA Toolkit のインストール完了後は、動作確認の意味で /usr/local/cuda/samples 配下にあるサンプル プログラムをビルド・実行してみるのも良いでしょう。下図は、私の PC で deviceQuery プログラムを実行してみたところです。

ちゃんと動いてますね!

コンテナー実行環境の構築

そもそも私が CUDA on WSL2 を待っていたのは、NGC のコンテナーイメージを Windows 上で手軽に実行したいからです。普段使っている PC は Windows 10 と Ubuntuのデュアルブートにしてあるのですが、コンテナーで GPU を使うために Ubuntu にブートし直すのは面倒だなぁ、ということが結構あるわけです。

というわけで WSL2 上に Docker と NVIDIA Container Toolkit をセットアップしてみます。
※ コンテナーから GPU を使う場合、ホスト (WSL2 上の Linux) に CUDA Toolkit をインストールする必要はありません。してもいいけど。

Docker のインストール

curl https://get.docker.com | sh

この時、

WSL DETECTED: We recommend using Docker Desktop for Windows.

なんて言われますが、無視してください。NVIDIA Container Toolkit は、まだ Docker Desktop WSL 2 backend をサポートしていません。

NVIDIA Container Toolkit のイントール

ユーザーガイドにあるコマンドを一つずつ打つのもダルいので、次のようなシェルスクリプトにして実行しました。

#!/bin/sh

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

最後に、Docker デーモンを再起動しておきましょう。

sudo service docker restart

以上で Linux 側の作業は終了です。ドライバーをインストールする作業がない分、通常の Linux で GPU 対応コンテナ環境をセットアップするよりも簡単なぐらいですね。

なお、ここでインストールした NVIDIA Container Toolkit は、かつて NVIDIA Docker と呼ばれていたもので、コンテナー内で GPU を利用するために必要なモジュールです。詳しくはこちらの記事をご覧ください。

NGC のコンテナーイメージを動かしてみる

早速 NGC のコンテナイメージを試してみましょう。私の PC には Turing アーキテクチャの GPU が載っていますので、その Tensor コアを活用すべく、以前「NGC のコンテナーイメージで AMP を試してみる」に書いた TensorFlow イメージを動かしてみました。

WSL2 の Ubuntu を起動し、次のコマンドを実行します。

docker run --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 --gpus all --rm -it nvcr.io/nvidia/tensorflow:20.03-tf2-py3

コンテナが起動したら、ResNet-50 をトレーニングベンチマークモード (学習データをその場で生成するモード) で実行します。AMP (Automatic Mixed Precision) を有効にするため、--precision=fp16 も付けてあります。

/workspace/nvidia-examples/cnn/resnet.py \
  --export_dir=/tmp \
  --display_every=10 \
  --num_iter=100 \
  --iter_unit=batch \
  --batch_size=160 \
  --precision=fp16

普通に動きましたねぇ。

※ なお、WSL は標準のコンソール以外にも様々なソフトウェアでアクセスできますが、この例で私が使っているのは MobaXterm です。WSL に対応しているだけでなく、X サーバーも内蔵されている便利なやつです。リモートもローカルもこれ一つでOK.

「生の Linux」とは違うところも

先ほどの例のように、CUDA のサンプルや NGC のコンテナーイメージを動かすだけならあまり違和感もなく、別の Linux マシンにログインして動かしているのと区別が付かないぐらいです。しかし、通常の Linux とは異なる不思議な点もいくつかあります。

例えば、

lspci しても GPU は見当たらず…

# lspci
8375:00:00.0 SCSI storage controller: Red Hat, Inc. Virtio filesystem (rev 01)
86cb:00:00.0 SCSI storage controller: Red Hat, Inc. Virtio filesystem (rev 01)
a609:00:00.0 SCSI storage controller: Red Hat, Inc. Virtio filesystem (rev 01)
b246:00:00.0 SCSI storage controller: Red Hat, Inc. Virtio filesystem (rev 01)
b7b6:00:00.0 3D controller: Microsoft Corporation Device 008e
bd73:00:00.0 SCSI storage controller: Red Hat, Inc. Virtio filesystem (rev 01)

いつも存在するデバイスファイル等もありません。

# ls -l /dev/nvidia*
ls: cannot access '/dev/nvidia*': No such file or directory
# ls -l /proc/driver/nvidia
ls: cannot access '/proc/driver/nvidia': No such file or directory

そう、WSL2 の Linux には、PCI デバイスとしての GPU は直接見えていません。NVIDIA ドライバを Windows にだけインストールしたことからもわかるように、GPU は Windows のデバイスとして管理されており、WSL2 の Linux からは、それを /dev/dxg というデバイスを通じて利用します。この /dev/dxg は所謂準仮想化デバイスです。ホストの Windows と、WSL の軽量ユーティリティ VM は、VMBus という仮想バスで接続されており、Linux 側での /dev/dxg への操作は、 dxgkrnl という準仮想化ドライバによって VMBus 経由でホストの GPU へ伝わります。


Announcing CUDA on Windows Subsystem for Linux 2 より

この、[ゲストの準仮想化デバイス]-[VMBus]-[ホストのデバイス] という仕組みは、Windows のハイパーバイザである Hyper-V が当初から備えているもので、ディスクや NIC のようなデバイスを完全にエミュレーションするのではなく、仮想環境に最適化した準仮想化デバイスとして実装するために利用されているものです。それが今回は、Windows の GPU を WSL 側で使うために活用されているわけですね。

※ ここで登場した Linux カーネル内の dxgkrnl は、従来から存在する Windows の DirectX グラフィックスカーネルと同じ名称ではありますが、新たに Linux 用に実装されたものだそうです。
ソースコードはこちら: WSL2-Linux-Kernel/drivers/gpu/dxgkrnl/

下記のように「Windows のとは共通点は何もない」と強調されていますね。IP 汚染の懸念はないよ、ということでしょう。

Although they share a name, the version of dxgkrnl inside of the Linux kernel is a clean room implementation of a Linux GPU driver based on our GPU-PV protocol and doesn’t share anything else in common with its similarly named Windows counterpart.

出典: DirectX is coming to the Windows Subsystem for Linux

制限事項

さて、実際に試せるようになった CUDA on WSL2 ですが、

  • Windows Insider Preview の Dev Channel (Fast Ring) で提供
  • NVIDIA Driver もプレビュー版

という段階ですから、まだまだ荒削りな部分、未実装の部分があります。ユーザーガイドの制限事項からいくつか抜き出してみると、

  • パフォーマンスに関しては充分にチューニングされていない (実際、先ほど例示した resnet.py もネイティブ Linux より少し性能が落ちています)
  • NVIDIA Management Library (NVML) API は未実装
  • NVIDIA Container Toolkit では、docker run 時に --gpus all のみをサポート。複数の GPU がある場合に、一部に絞ってコンテナに使わせることができない。

などです。NVML が実装されていないということは、 nvidia-smi のようなお馴染みのコマンドも使えません。これはちょっと痛いのですが、 nvidia-smi は Windows 側で実行することもできますので、ある程度の情報は得られます。

まとめ

  • Windows 10 の WSL2 でついに CUDA が使えるようになりました。 (なり始めました)
  • NGC の TensorFlow コンテナイメージなどは既に普通に動きます。
  • Windows Insider Preview と、NVIDIA Developer Program へ是非登録をお願いします。
  • パフォーマンスや、管理面でいくつか制限事項もありますが、ぜひお試しの上フィードバックを。

お楽しみ CUDA さい!

関連情報

Announcing CUDA on Windows Subsystem for Linux 2
CUDA on WSL User Guide
NVIDIA Drivers for CUDA on WSL
Announcing Windows 10 Insider Preview Build 20150
The Windows Subsystem for Linux BUILD 2020 Summary
Windows Subsystem for Linux Documentation
Automatic Mixed Precision (AMP) でニューラルネットワークのトレーニングを高速化
NVIDIA Docker って今どうなってるの? (19.11版)

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした