Windows Server 2025にて正式サポート
Windows Server 2025にて、GPU-Pは正式にサポートされるようになるようです。
こちらで紹介している有効化手順は正式サポート以前のものになります。
正式な手順は異なる可能性があります。
正式な手順は公式のドキュメントを確認してください。
ただし、こちらの手順では、公式的にはサポートされないハードウェア構成でも使用可能かもしれません。
はじめに
この記事のWindows版はここです。
Hyper-Vを利用するWSL2では、GPU-PV(Para Virtualization)と呼ばれる技術を利用することで、Windows 10 (21H1)以降Nvidia製GPUを用いるCUDAプログラミングが、WSL2上やそれをバックエンドとして利用するDockerで可能になりました。
また、最近では、Azure Stack HCIでも、サポートされているGPUは限られますが、Linux上でのGPU-PVが利用可能なようです(この記事の手順を利用すれば非対応GPUでも利用可能な可能性があります)。
既に利用されているということは、Windowsに実装されているということです。
実際に、PowershellでHyper-Vに関するコマンドを調べると、下記のようなコマンドで、
Get-Command -module Hyper-V
下記のような結果が得られます。
CommandType Name Version Source
----------- ---- ------- ------
(前略)
Cmdlet Add-VMGpuPartitionAdapter 2.0.0.0 Hyper-V
(中略)
Cmdlet Get-VMGpuPartitionAdapter 2.0.0.0 Hyper-V
(中略)
Cmdlet Remove-VMGpuPartitionAdapter 2.0.0.0 Hyper-V
(中略)
Cmdlet Set-VMGpuPartitionAdapter 2.0.0.0 Hyper-V
(後略)
上記のように既に実装されています。
Get-Helpコマンドで調べると構文は出てきますが、説明はまだ公式サポートされていないので、出てきません(Powershell 7以降で実行すると更に詳しい構文が出てきます)。
この技術が、通常のWindows(サーバー含む)では、サポートされていませんが、Windows仮想マシンでは利用可能であることは、既に記事にした通りです。
WSL2において、既に利用されているということは、公開されているWSL2専用にカスタムしたカーネルをベースにHyper-Vでも利用できるように変更すれば、Hyper-V上のLinuxでも利用可能であるということです。
今回は、Hyper-VのLinuxでもGPU-PVを利用可能にするカスタムカーネルのUbuntu向けパッケージを公開されている方が居たので、このカーネルを利用して、Hyper-V上のKubuntu 22.04 LTSで、GPU-PVを利用します。
カスタムカーネルは、Ubuntu 20.04及びUbuntu 22.04でテストされているようですが、他のUbuntuのバージョンやUbuntuベースのディストリビューション、Debianベースのディストリビューションでも動作する可能性があります。
この記事では、Kubuntu 22.04 LTS環境で、仮想GPUの割り当てから、GPUドライバーの適用を行う手順を紹介します。
仮想GPUの割り当て、親マシン上にあるGPUドライバーの保存場所の確認については、Windows版の記事と同様です。
目次
Windows Server 2025にて正式サポート- はじめに
- 目次
- 動作確認環境
-
仮想マシンで、仮想
GPUを利用できるようにする - (
Nvidia製GPU限定)nvidia-smiコマンドによる仮想GPUの確認 -
(
Nvidia製GPU限定) Dockerで仮想GPUを利用する - GPU Partition Adapterの削除
動作確認環境
- 親マシン
OS: Windows 11
Version: 22H2
CPU: Intel Core i9 13900K(24C32T)
MEM: DDR5 128GB(4800MHz 32GB ×4)
GPU: Nvidia Geforce RTX 3080
- 子マシン
OS: Kubuntu 22.04.1 LTS
vCPU: 8C
MEM: 16GB
子マシンについては、カスタムカーネルを動作させるために、セキュアブートを無効化する必要があります。
Ubuntuは、Hyper-Vのセキュアブートテンプレートで、Microsoft UEFI証明機関を選択している場合、利用可能ですが、カスタムカーネルを利用している場合は、完全に無効にする必要があります。
クイック作成ギャラリー等で作成した仮想マシンの場合は、意図せずに有効化されている可能性があるので、特に無効になっていることを確認して下さい。
仮想マシンで、仮想GPUを利用できるようにする
注意
この機能は、公式にサポートされていない方法です。なにか問題が起きても自己責任です。
チェックポイントの無効化
まず、チェックポイントを適用・削除する必要があります。
これは、GPU-PVではチェックポイントがサポートされておらず、有効化するためにはチェックポイントを無効化する必要があるためです。
そのため、自動チェックポイントを使っている場合は無効に、チェックポイントが既に存在する場合は、チェックポイントの削除または適用を、チェックポイントを利用しないことが必要です。
仮想GPUの割り当て方法
この項目での設定は、シングルGPU環境の場合、このbatファイルにより一括実行可能です。
このbatファイルはダブルクリックで、実行するとUACで管理者権限に昇格し、仮想マシン名を聞いてくるので、設定したい仮想マシンの名前をシングルクォート(')で囲み指定すると、一括で実行されます。
GPU Partition Adapterの割り当て
まずは、先程のGPU Partitioning関連のコマンドを利用して仮想マシンにGPU Partition Adapterを仮想マシンに割り当て、リソースの設定などを行います。
Powershellを管理者権限で実行して、下記コマンドを実行します。
まずは、仮想マシンにGPU Partition Adapterを割り当てます。
下記コマンドでは、親マシンのタスクマネージャー等で、GPU 0として認識されているGPUが仮想GPUとして割り当てられます。
マルチGPU環境で指定したいGPUがある場合は、下記のコマンドは実行せずに以降で紹介するコマンドを実行して下さい。
Add-VMGpuPartitionAdapter -VMName "仮想マシン名"
マルチGPU環境での割り当てについて
マルチGPU環境でGPU 0として、認識されるGPU以外を割り当てたい場合、-InstancePathオプションで、親マシンのWindowsで認識されるデバイスファイルパス名を指定することでGPUを明示的に指定することが可能になります。
このオプションはWindows 10のあるいはそのバージョンによっては利用できない可能性があります。
もし、利用できなかった場合は、利用したいGPUが、タスクマネージャー上で、GPU 0として認識するように、他のGPUを無効化する等して下さい。
マルチGPU環境で、割り当てたいデバイスファイルパス名を確認する方法は下記の通りです。
Get-VMHostPartitionableGpu | Format-Table Name
下記のような結果が、返ってきます(マルチGPU環境の場合、複数返ってきます)。
Name
----
デバイスファイルパス名
ここで、帰ってきた値を用いて、先程のコマンドを実行します。
Add-VMGpuPartitionAdapter -VMName "仮想マシン名" -InstancePath "デバイスファイルパス名"
仮想GPUのリソース設定
仮想GPUのリソースを設定します。
物理GPUの全てのリソースを割り当てる場合は、以下のようなコマンドを実行します。
Set-VMGpuPartitionAdapter -VMName "仮想マシン名" -Passthru
もし、リソースを調整したい場合は、下記のようにすると明示的にパラメーターを指定できます。
Set-VMGpuPartitionAdapter -VMName "仮想マシン名" -MinPartitionVRAM 80000000 -MaxPartitionVRAM 100000000 -OptimalPartitionVRAM 100000000 -MinPartitionEncode 80000000 -MaxPartitionEncode 100000000 -OptimalPartitionEncode 100000000 -MinPartitionDecode 80000000 -MaxPartitionDecode 100000000 -OptimalPartitionDecode 100000000 -MinPartitionCompute 80000000 -MaxPartitionCompute 100000000 -OptimalPartitionCompute 100000000
その他リソースを仮想マシンに設定します。
Set-VM -GuestControlledCacheTypes $true -VMName "仮想マシン名"
Set-VM -LowMemoryMappedIoSpace 1GB -VMName "仮想マシン名"
Set-VM –HighMemoryMappedIoSpace 32GB –VMName "仮想マシン名"
仮想マシンに準仮想GPUのドライバーを追加する方法
上記の設定で既に、仮想マシンから仮想GPUはPCIデバイスの3D controller: Microsoft Corporation Deviceとして見えていますが、この時点でまだ動作はしていません。
仮想マシンに、ドライバーを追加する必要があります。
この時、物理マシンにGPUドライバーをインストールする場合と同じように、仮想マシンにドライバーをインストールしようとしてもできません。
このGPUは、通常のGPUとは異なる準仮想化GPUです。
GPUの一部のステータスを確認することができません。
また、カスタムカーネルのインストールの様に、準仮想化GPUであるため、OS側がこのデバイスを受け入れる様に修正する必要もあります。
そのため、ドライバーをインストールするためには、親マシンからドライバーをコピーする必要があります。
この仮想マシンにドライバーを追加する手順は、親マシンのGPUドライバーを更新する度に行う必要があります。
親マシン上にあるGPUドライバーの保存場所の確認
Powershellで、下記コマンドを実行します。
Get-CimInstance -ClassName Win32_VideoController -Property * | Format-Table InstalledDisplayDrivers
以下のような結果が、返ってきます。
InstalledDisplayDrivers
-----------------------
C:\Windows\System32\DriverStore\FileRepository\nv_dispi.inf_amd64_50916785244854f2\nvldumdx.dll,C:\Windows\System32\DriverStore\FileRepository\…
この環境での利用しているGPUドライバーを保存しているフォルダは、C:\Windows\System32\DriverStore\FileRepository\nv_dispi.inf_amd64_50916785244854f2\であることがわかります。
仮想マシンへのドライバーコピー
これより上の手順は、Windows版と共通でしたが、ここからの手順は異なります。
Windows上で、wslフォルダを作成して下さい。
作成した、wslフォルダ内に、driversフォルダを作成して下さい。
driversフォルダには、先程確認したドライバーのフォルダ(今回の場合、nv_dispi.inf_amd64_50916785244854f2)をコピーします。
次にwslフォルダ内(driversフォルダと同じ階層)に、C:\Windows\System32\lxssにあるlibフォルダをコピーします。
これは、WSL2の/usr/lib/wslと同じディレクトリ構造になります。
以下のWSL2を利用している場合コマンドを、実行したときの出力が、
ls /usr/lib/wsl
以下となり同じことが確認できます。
drivers lib
今回の場合、コピーしてできたフォルダは、以下のような構成のディレクトリ構造になります。
wsl/
├ lib/
└ drivers/
└ nv_dispi.inf_amd64_50916785244854f2/
仮想マシン上のUbuntuでも、このwslフォルダが同じパス、同じディレクトリ構造になるようにコピーします。
コピーの方法は、Linux仮想マシンではサポートされなくなったの拡張セッションやRDPによるコピペ(権限の問題で一旦デスクトップ等にコピーする必要やディレクトリ単位でコピーできないのでZIP等への圧縮が必要になります)、カスタムカーネルを公開している方の手順と同じようにSSH Serverを有効にしてのscpコマンドやsftpコマンドによるコピー、仮想マシンの仮想ハードディスクを親マシンのWSL2にマウントしてWSL2経由でコピーする等々様々な方法がありますが、好きな方法でコピーして下さい。
コピーした後は、ドライバーディレクトリの所有権や権限の設定を変更する必要があります。
仮想マシンで、以下のようなコマンドを実行します。
sudo chown -R root:root /usr/lib/wsl
sudo chmod 555 /usr/lib/wsl/lib/*
ドライバーのライブラリを読み込むための設定を行います。
ドライバーのライブラリファイルがあるパスである/usr/lib/wsl/libが内容のファイルld.wsl.confを/etc/ld.so.conf.d/に作成します。
これをコマンドで行う場合、以下の様になります。
echo "/usr/lib/wsl/lib" | sudo tee /etc/ld.so.conf.d/ld.wsl.conf
ライブラリを読み込む様にします。
sudo ldconfig
プロファイルにパスを通します。
ドライバーのライブラリファイルがあるパスである/usr/lib/wsl/libをパスに追加する内容export PATH=$PATH:/usr/lib/wsl/libであるファイルwsl.shを/etc/profile.d/に作成します。
これをコマンドで行う場合、以下の様になります。
echo "export PATH=$PATH:/usr/lib/wsl/lib" | sudo tee /etc/profile.d/wsl.sh
作成したスクリプトに権限を与えます。
sudo chmod +x /etc/profile.d/wsl.sh
カスタムカーネルのインストール
まずは、カーネルヘッダとカーネルイメージのパッケージをダウンロードする必要があります。
最新のパッケージのURLは、カスタムカーネルを公開している方のリリースページで確認できます。
linux-headersから始まるファイルがカーネルヘッダで、linux-imageから始まるファイルがカーネルイメージです。
それぞれのパッケージファイルのURLをファイルに対して、右クリック->リンクのコピー等で入手して下さい。
このパッケージへのURLを使い、以下のようなコマンドでダウンロードできます。
wget パッケージURL
現時点での最新版のURLは、カーネルヘッダがhttps://github.com/brokeDude2901/dxgkrnl_ubuntu/releases/download/main/linux-headers-5.10.102.1-dxgrknl_5.10.102.1-dxgrknl-10.00.Custom_amd64.deb、イメージがhttps://github.com/brokeDude2901/dxgkrnl_ubuntu/releases/download/main/linux-image-5.10.102.1-dxgrknl_5.10.102.1-dxgrknl-10.00.Custom_amd64.debです。
この場合は、以下のようになります。
wget https://github.com/brokeDude2901/dxgkrnl_ubuntu/releases/download/main/linux-headers-5.10.102.1-dxgrknl_5.10.102.1-dxgrknl-10.00.Custom_amd64.deb
wget https://github.com/brokeDude2901/dxgkrnl_ubuntu/releases/download/main/linux-image-5.10.102.1-dxgrknl_5.10.102.1-dxgrknl-10.00.Custom_amd64.deb
ダウンロードしたパッケージをインストールします。
sudo apt install -y ./ダウンロードしたパッケージ名
今回の場合は、以下の様になります。
sudo apt install -y ./linux-headers-5.10.102.1-dxgrknl_5.10.102.1-dxgrknl-10.00.Custom_amd64.deb
sudo apt install -y ./linux-image-5.10.102.1-dxgrknl_5.10.102.1-dxgrknl-10.00.Custom_amd64.deb
Grubメニューからカスタムカーネルを選択できるようにする
Grubメニューを仮想マシン起動時に表示して、カスタムカーネルを手動で選択できる様にします。
以下のようなコマンドで表示できる様にすることが可能です。
sudo sed -i "s/GRUB_DEFAULT=0/GRUB_DEFAULT=saved/g" /etc/default/grub
sudo sed -i "s/GRUB_TIMEOUT_STYLE=hidden/GRUB_TIMEOUT_STYLE=menu/g" /etc/default/grub
sudo sed -i "s/GRUB_TIMEOUT=0/GRUB_TIMEOUT=30/g" /etc/default/grub
sudo grep -q -F "GRUB_SAVEDEFAULT=true" /etc/default/grub || echo "GRUB_SAVEDEFAULT=true" | sudo tee -a /etc/default/grub
修正したGrubの設定を適用します。
sudo update-grub
ここまでの設定が完了したら、仮想マシンをシャットダウンして下さい。
カスタムカーネルを選択して起動
カスタムカーネルを選択して起動します。
まず、仮想マシンを起動する前に、仮想マシンのセキュアブートが無効になっていることを確認して下さい。
確認が終わったら起動します。
起動すると、Grubメニューが表示されるので、Advanced options for Ubuntuを選択して下さい。
次に、インストールしたカスタムカーネルを選択します。
カスタムカーネルは、末尾に-dxgrknlとあるものです。
今回は、Ubuntu, with Linux 5.10.102.1-dxgrknlを選択して起動します。
セキュアブートが有効な場合は、ここで失敗します。
無効であることを確認して下さい。
(Nvidia製GPU限定) nvidia-smiコマンドによる仮想GPUの確認
これで、GPUを認識し、利用できるようになりました。
以下のコマンドの出力は、
lspci
以下の様になっていると思われますが、
なんとか 3D controller: Microsoft Corporation Device 008e
Nvidia製GPUの場合は、以下のようなコマンドで確認できます。
nvidia-smi
上記コマンドを実行すると、WSL2上で、このコマンドを実行した時と同じ様に一部項目は表示できませんが、コマンドの結果が正常に返ってきます(Windowsっぽい画面に見えますが、Windows風にカスタムしたKubuntu 22.04LTSです)。
(Nvidia製GPU限定) Dockerで仮想GPUを利用する
Dockerのインストール
まずは、仮想マシンをアップグレードします。
sudo apt update
sudo apt -y upgrade
sudo apt autoremove
sudo apt autoclean
Dockerをインストールします。
公式手順に従います。
インストール手順に必要な依存パッケージをインストールします。
sudo apt install -y ca-certificates curl gnupg
DockerのGPG鍵をaptキーリングに追加します。
sudo mkdir -m 0755 -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
リポジトリを追加します。
echo "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
リポジトリを更新します。
sudo apt update
Dockerをインストールします。
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Dockerデーモンの自動起動を有効化し、動作させます。
sudo systemctl enable --now docker
sudoなしで、Dockerコマンドを利用できる様に、ユーザーをdockerグループに追加します。
sudo usermod -aG docker ユーザー名
NVIDIA Container Toolkitのインストール
公式手順に従います。
GPG鍵をaptキーリングに追加し、リポジトリを追加します。
Ubuntu 22.04の場合、Ubuntu 18.04のものが追加されます。
distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
&& curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
&& curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | \
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
リポジトリを更新します。
sudo apt update
NVIDIA Container Toolkitのインストールを行います。
sudo apt install -y nvidia-container-toolkit
Dockerデーモンが、NVIDIA Container Toolkitを認識するように構成します。
sudo nvidia-ctk runtime configure --runtime=docker
仮想マシンを再起動します。
sudo reboot
Dockerコンテナ内でnvidia-smiを実行
再起動後、仮想マシン内で、以下のコマンドを実行し、コンテナ内で、nvidia-smiを実行します。
nvidia-smiを実行するコンテナイメージをダウンロードします。
docker pull ubuntu:22.04
以下のコマンドで、コンテナ内で、nvidia-smiを実行します。
WSL2上で、nvidia-smiを実行する時等とは異なり、バインドマウントして実行する必要があります。
docker run -it --rm --gpus all -v /usr/lib/wsl/lib/nvidia-smi:/usr/lib/nvidia-smi ubuntu:22.04 nvidia-smi
実行すると、以下の様になります。
コンテナ内でも、GPUを利用できることがわかります。
Hyper-V仮想マシン上のUbuntu上のDockerでStable Diffusion WebUI(AUTOMATIC1111)を動かす
こちらのComposeファイルを利用します。
WSL2やネイティブLinux上のDockerで実行するのと同じ手順です。
まずは、Gitがインストールされていない場合は、インストールします。
sudo apt install -y git
リポジトリをクローンします。
git clone https://github.com/AbdBarho/stable-diffusion-webui-docker.git
クローンしたディレクトリに移動します。
cd stable-diffusion-webui-docker
モデル等のダウンロードを行います。
容量があるので、しばらく待ちます。
ダウンロードが終了すると、コンテナは停止します。
docker compose --profile download up --build
停止したコンテナを終了します。
docker compose --profile download down
GPUが必要なStable Diffusion WebUIを実行します。
docker compose --profile auto up --build
Running on local URL: http://0.0.0.0:7860という内容が表示された後に、http://localhost:7860にブラウザでアクセスします。
そして、プロンプトに適当な入力を与えて画像を生成します。
以下の様になっています。
親マシンのタスクマネージャーやHWMonitor等で確認すると、しっかりGPUを利用していることがわかります。
親マシンのブラウザからhttp://仮想マシンのIPアドレス:7860等で、WebUIにアクセスしても、Stable Diffusionを実行できることがわかります。
検証環境では、mDNSが有効なため、仮想マシンのホスト名で、アクセスして実行しています。
GPU Partition Adapterの削除
管理者権限のPowershellで、以下のコマンドを実行します。
Remove-VMGpuPartitionAdapter -VMName "仮想マシン名"
削除すると、チェックポイントも再び使用可能になります。
GPUドライバーの削除等は、別途手動で行って下さい。





