WSL2でNVIDIA GPUのVulkanが使えない問題を解決する
はじめに
WSL2 (Ubuntu 24.04) 上で nvidia-smi ではGPUが見えているのに、vulkaninfo ではCPU (llvmpipe) にフォールバックしてしまう問題にハマったので、原因と解決方法をまとめます。
環境
| 項目 | バージョン |
|---|---|
| OS (ホスト) | Windows 11 |
| WSL2 ディストリビューション | Ubuntu 24.04.4 LTS |
| GPU | NVIDIA GeForce RTX 4090 |
| NVIDIA ドライバー (Windows側) | 591.74 |
| WSL カーネル | 6.6.87.2-microsoft-standard-WSL2 |
症状
nvidia-smi ではGPUがちゃんと認識されている。
$ nvidia-smi
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 590.52.01 Driver Version: 591.74 CUDA Version: 13.1 |
| 0 NVIDIA GeForce RTX 4090 On | 00000000:01:00.0 On | Off |
+-----------------------------------------------------------------------------------------+
しかし vulkaninfo --summary を見ると、GPUではなくCPUエミュレーション (llvmpipe) にフォールバックしている。
$ vulkaninfo --summary
...
Devices:
========
GPU0:
deviceType = PHYSICAL_DEVICE_TYPE_CPU
deviceName = llvmpipe (LLVM 20.1.2, 256 bits)
driverID = DRIVER_ID_MESA_LLVMPIPE
原因
WSL2ではGPUアクセスの仕組みがネイティブLinuxとは根本的に異なることが原因です。
ネイティブLinux vs WSL2 のGPUアクセス
【ネイティブLinux】
アプリ → Vulkan ICD (libnvidia-glcore.so) → /dev/nvidia* → NVIDIA カーネルドライバー → GPU
【WSL2】
アプリ → ??? → D3D12 → /dev/dxg → Windows側NVIDIAドライバー → GPU
ポイントは以下の3つです。
1. WSL2には /dev/nvidia* が存在しない
WSL2ではGPUへのアクセスに /dev/dxg (DirectX Graphics) デバイスを使用します。ネイティブLinux用のNVIDIA Vulkan ICDライブラリ (libGLX_nvidia.so.0) は /dev/nvidia* を前提としているため、WSL2では動作しません。
$ ls /dev/dri/ # 何も出ない
$ ls /dev/dxg # これだけが存在
crw-rw-rw- 1 root root 10, 125 ... /dev/dxg
2. Ubuntu の mesa-vulkan-drivers に dozen ドライバーが含まれていない
WSL2でVulkanを使うには、Mesa の dozen (dzn) ドライバーが必要です。dozenは Vulkan 呼び出しを D3D12 に変換し、/dev/dxg 経由でGPUにアクセスします。
アプリ → Vulkan → dozen (Vulkan→D3D12変換) → /dev/dxg → GPU
しかし、Ubuntu 24.04 の公式パッケージでは dozen がビルドされていません。Mesa のビルドオプション -Dvulkan-drivers=microsoft-experimental が有効になっていないためです。
$ dpkg -L mesa-vulkan-drivers | grep dzn
(何も出ない)
3. libnvidia-gl パッケージのVulkan ICDも動かない
libnvidia-gl-590 をインストールすると nvidia_icd.json が配置されますが、これも /dev/nvidia* 前提なのでWSL2では無意味です。
$ VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/nvidia_icd.json vulkaninfo --summary 2>&1
ERROR: setup_loader_term_phys_devs: Failed to detect any valid GPUs in the current config
解決方法
Step 1: kisak-mesa PPA を追加して dozen ドライバーを入手する
kisak-mesa PPA は Mesa の最新安定版を提供しており、dozen ドライバーを含んでいます。
sudo add-apt-repository -y ppa:kisak/kisak-mesa
sudo apt update
sudo apt upgrade -y
dozen ドライバーがインストールされたことを確認します。
$ dpkg -L mesa-vulkan-drivers | grep dzn
/usr/lib/x86_64-linux-gnu/libvulkan_dzn.so
/usr/share/vulkan/icd.d/dzn_icd.json
Step 2: 環境変数を設定する
~/.bashrc に以下を追加します。
# WSL2 Vulkan: use Mesa dozen (D3D12) driver for GPU-accelerated Vulkan
export MESA_D3D12_DEFAULT_ADAPTER_NAME=NVIDIA
export VK_DRIVER_FILES=/usr/share/vulkan/icd.d/dzn_icd.json
| 変数名 | 役割 |
|---|---|
MESA_D3D12_DEFAULT_ADAPTER_NAME |
D3D12 バックエンドで使用するGPUアダプターを指定 |
VK_DRIVER_FILES |
Vulkan ローダーが読み込む ICD を限定する(不要なドライバーの読み込みを防ぐ) |
設定を反映します。
source ~/.bashrc
Step 3: 動作確認
$ vulkaninfo --summary
...
Devices:
========
GPU0:
apiVersion = 1.2.328
driverVersion = 25.3.5
vendorID = 0x10de
deviceID = 0x2684
deviceType = PHYSICAL_DEVICE_TYPE_DISCRETE_GPU
deviceName = Microsoft Direct3D12 (NVIDIA GeForce RTX 4090)
driverID = DRIVER_ID_MESA_DOZEN
driverName = Dozen
PHYSICAL_DEVICE_TYPE_DISCRETE_GPU として RTX 4090 が認識されていれば成功です。
注意事項
dozen ドライバーの制限
dozen は現時点では Vulkan 1.2 対応で、Vulkan conformance test を通過していません。起動時に以下の警告が出ますが、多くのアプリケーションでは問題なく動作します。
WARNING: dzn is not a conformant Vulkan implementation, testing use only.
PPA の削除方法
問題が発生した場合は、ppa-purge で元に戻せます。
sudo apt install ppa-purge
sudo ppa-purge ppa:kisak/kisak-mesa
WSL2 に NVIDIA Linux ドライバーをインストールしてはいけない
WSL2 では GPU ドライバーは Windows ホスト側から提供されます。nvidia-driver-* パッケージをWSL2内にインストールすると競合が発生する可能性があります。CUDAを使いたい場合は、NVIDIA公式の CUDA on WSL の手順に従ってください。
まとめ
| 問題 | WSL2 には /dev/nvidia* がなく、NVIDIA の Vulkan ICD が動かない |
|---|---|
| 原因 | Ubuntu の Mesa パッケージに dozen (D3D12 Vulkan) ドライバーが含まれていない |
| 解決 | kisak-mesa PPA から dozen ドライバーを入手し、環境変数を設定する |
WSL2 での Vulkan は アプリ → dozen → D3D12 → /dev/dxg → GPU という経路で実現されます。ネイティブ Linux とはアーキテクチャが異なるため、「nvidia-smi で見えるのに Vulkan で使えない」という直感に反する状態になりがちです。