最近、Yocto ProjectでLinuxディストリビューションをビルドすることが多くなったことと、最近多くの方が開発に導入しているWindows Subsystem for Linux 2(WSL2)も未体験だったことから、今回は新たなマシンリソース獲得に向けて WSL2をインストールし、Ubuntu22.04ベースのLinuxアプリケーション開発環境を、Windows 11 Pro上に構築 してみました。Yocto ProjectによるLinuxディストリビューションビルド環境などもWSL2上で実行できるようなので、 ストレージを湯水のように消費できる仮想ディスクの設定 にもチャレンジしてみました。また、Windows上で機械学習のワークロードを実行されている方も多そうでしたので NVIDIA RTX3060Tiを搭載しCUDA/cuDNN/NVIDIA Container Toolkit/Dockerの環境 も構築します。
WSL2(Windows Subsystem for Linux 2)をインストールする前の事前準備
Windows Subsystem for Linux 2のインストールに際して、以下を事前準備します。
- GPUドライバを最新のものに更新する
- NVIDIA CUDA/cuDNNを利用したいため
- 今回はGPUとして「NVIDIA GeForce RTX3060Ti」を搭載しました
- Windowsのシステム状態を確認する
- Windows Power Shell上で
systeminfo
を実行し、スペックを確認します - 皆様がインストールされる際の目安としてご参照ください
- Windows Power Shell上で
NVIDIA GPUドライバを最新版へと更新する
事前に、WindowsにインストールされているNVIDIAのGeForceドライバーを最新のものにアップデートします。GeForceドライバーより 「ドライバーの自動更新」-「今すぐダウンロード」 をクリックし最新の状態に更新してください。
参考:今回利用したWSL2向けWindowsの構成
今回WSL2をセットアップするためにベースとするWindowsのスペックは以下の通りです。本環境はIntel Core i5-12600K × RAM 64GBのWindows 11 Pro上で動作しています。また、 仮想マシンを格納するためのストレージとして、PCI-express接続のNVMe SSD 1TBをEドライブに接続しました。後から移動もできますが、開発したい内容にあった適当な容量のストレージを予めご準備ください。
WSL2(Windows Subsystem for Linux 2)によるLinux実行環境のインストール
それでは早速、Windows Subsystem for Linux 2をWindows11上にセットアップし、Linuxディストリビューションを利用できる環境を構築してみましょう。
WSL2をWindows Power Shellからインストールする
まずWSL2をインストールするには、タスクバーの 「WIndowsスタートメニュー」のアイコンを右クリック し「ターミナル(管理者)」をクリックし 「Windows Power Shell」 を起動します。
Windowsの仮想化機能「Hyper-V-All」を有効化する
まずWindowsのHyper-V対応機能である 「Microsoft-Hyper-V-All」を有効化 します。Get-WindowsOptionalFeature
で有効/無効を確認し、無効(Disabled)になっている場合は Enable-WindowsOptionalFeature
により有効化します。これには再起動を求められることがありますので、確認の上、再起動しましょう。
# Hyper-V-Allの有効/無効を確認する
$ Get-WindowsOptionalFeature -Online | ? FeatureName -Match "Hyper-V-All"
# FeatureName : Microsoft-Hyper-V-All
# State : Disabled
# Hyper-V-Allを有効化する
$ Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-All
# この操作を完了するために、今すぐコンピューターを再起動しますか?
# [Y] Yes [N] No [?] ヘルプ (既定値は "Y"):
######
# Windowsを再起動してください
######
# Hyper-V-Allが有効になっていることを確認する
### 有効になっていない場合BIOS/UEFI上で
### Intel Virtualization Technology(INtel VT-x)が無効になっている可能性があります
$ Get-WindowsOptionalFeature -Online | ? FeatureName -Match "Hyper-V-All"
# FeatureName : Microsoft-Hyper-V-All
# State : Enabled
WSLをインストールする
Windows Power Shell上で wsl --install
から始まる以下の手順を実行し、WSL2をインストールします。その後、WSLのバージョン、WSLにより実行できるLinuxディストリビューションのリストを確認し、最後に wsl --update
によりWSLを最新の状態に更新します。
### WSLをインストールする
$ wsl --install
# インストール中: 仮想マシン プラットフォーム
# 仮想マシン プラットフォーム はインストールされました。
# インストール中: Linux 用 Windows サブシステム
# Linux 用 Windows サブシステム はインストールされました。
# インストール中: Ubuntu
# Ubuntu はインストールされました。
# 要求された操作は正常に終了しました。変更を有効にするには、システムを再起動する必要があります。
######
# Windowsを再起動してください
######
### WSLのバージョンを確認する
$ wsl --version
# WSL バージョン: 2.3.26.0
# カーネル バージョン: 5.15.167.4-1
# WSLg バージョン: 1.0.65
# MSRDC バージョン: 1.2.5620
# Direct3D バージョン: 1.611.1-81528511
# DXCore バージョン: 10.0.26100.1-240331-1435.ge-release
# Windows バージョン: 10.0.22631.4602
### インストールできるLinuxディストリビューションを確認する
$ wsl --list --online
# インストールできる有効なディストリビューションの一覧を次に示します。
# 'wsl.exe --install <Distro>' を使用してインストールします。
#
# NAME FRIENDLY NAME
# Ubuntu Ubuntu
# Debian Debian GNU/Linux
# kali-linux Kali Linux Rolling
# Ubuntu-18.04 Ubuntu 18.04 LTS
# Ubuntu-20.04 Ubuntu 20.04 LTS
# Ubuntu-22.04 Ubuntu 22.04 LTS
# Ubuntu-24.04 Ubuntu 24.04 LTS
# OracleLinux_7_9 Oracle Linux 7.9
# OracleLinux_8_7 Oracle Linux 8.7
# OracleLinux_9_1 Oracle Linux 9.1
# openSUSE-Leap-15.6 openSUSE Leap 15.6
# SUSE-Linux-Enterprise-15-SP5 SUSE Linux Enterprise 15 SP5
# SUSE-Linux-Enterprise-15-SP6 SUSE Linux Enterprise 15 SP6
# openSUSE-Tumbleweed openSUSE Tumbleweed
### インストールされているLinuxディストリビューションを表示する
$ wsl --list --verbose
# NAME STATE VERSION
# * Ubuntu Stopped 2
### 一旦Linuxディストリビューションをすべて削除し、空の状態にする
$ wsl --unregister Ubuntu
# 登録解除。
# この操作を正しく終了しました。
$ wsl --list --verbose
# Linux 用 Windows サブシステムにインストールされているディストリビューションはありません。
# ...
### WSLを最新の状態へと更新する
$ wsl --update
# 更新プログラムを確認しています。
# Linux 用 Windows サブシステムの最新バージョンは既にインストールされています。
### WSLをシャットダウンする
$ wsl --shutdown
WSL2を利用してWindows上にLinuxディストリビューションをインストールする
WSLにインストール可能なLinuxディストリビューションは前手順の wsl --list --online
で確認できます。ここから選択するわけですが、Yocto ProjectのビルドにUbuntuが向いていることと、後に利用するNVIDIAのツールがUbuntu対応であることから、今回は 「Ubuntu-22.04」 をインストールしてみます。
$ wsl -l -v
# Linux 用 Windows サブシステムにインストールされているディストリビューションはありません。
$ wsl --install Ubuntu-22.04
# インストール中: Ubuntu 22.04 LTS
# [ 0.0% ]
# Ubuntu 22.04 LTS がインストールされました。
# Ubuntu 22.04 LTS を起動しています...
# Installing, this may take a few minutes...
# Please create a default UNIX user account. The username does not need to match your Windows username.
# For more information visit: https://aka.ms/wslusers
### 管理者権限を持つユーザーと、そのパスワードを設定する
# Enter new UNIX username: shino
# New password:
# Retype new password:
# passwd: password updated successfully
# Installation successful!
### Ubuntuにログインできる
shino@SHINO-MAIN:~$ ls /
bin dev home lib lib64 lost+found mnt proc run snap sys usr
boot etc init lib32 libx32 media opt root sbin srv tmp var
shino@SHINO-MAIN:~$ ls /mnt
c d e wsl wslg
shino@SHINO-MAIN:~$ uname -a
Linux SHINO-MAIN 5.15.167.4-microsoft-standard-WSL2 #1 SMP Tue Nov 5 00:21:55 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
shino@SHINO-MAIN:~$ exit
### Windows Power Shellに戻る
$ wsl -l -v
NAME STATE VERSION
* Ubuntu-22.04 Running 2
インストールしたUbuntuをCドライブ以外へ移動する
WSL2上で動作するLinuxディストリビューションは、デフォルトでCドライブにインストールされます。ですが、WindowsのCドライブは割とゲーム等をインストールして容量がひっ迫しがちになるため、 別のドライブ(本例ではEドライブ)にLinuxディストリビューションを移動 します。
# Linuxディストリビューションを停止する
$ wsl --shutdown
# 作業ディレクトリを移動する
$ cd E:
$ ls
# Mode LastWriteTime Length Name
# ---- ------------- ------ ----
# d-r--- 2024/12/03 20:26 Dropbox
# WSL2のディストリビューションを格納するディレクトリを作成する
$ New-Item -Path 'E:\wsl2\distro\Ubuntu2204' -ItemType Directory
# 作業ディレクトリへ移動する
$ cd E:\wsl2\distro
# Ubuntuをexportする
$ wsl --export Ubuntu-22.04 distro-ubuntu2204.tar
# エクスポートが進行中です。これには数分かかる場合があります。
# この操作を正しく終了しました。
# Ubuntu-22.04を削除する
$ wsl --unregister Ubuntu-22.04
# 登録解除。
# この操作を正しく終了しました。
# 削除できていることを確認する
$ wsl -l -v
# Linux 用 Windows サブシステムにインストールされているディストリビューションはありません。
# Ubuntuをフォルダを指定してWSL2に再登録する
$ wsl --import Ubuntu-22.04 'E:\wsl2\distro\Ubuntu2204\' '.\distro-ubuntu2204.tar'
$ wsl -l -v
# NAME STATE VERSION
# * Ubuntu-22.04 Stopped 2
管理ユーザーでログインする:rootでログインしない
デフォルトではWSL2上のLinuxディストリビューションにログインすると root
となってしまいますが、rootのままの作業は危険ですので(重要な作業はsudoを挟むべきなので)、 Ubuntuにログインする際は管理ユーザーが自動的に選択されるよう設定 します。
# Ubuntu-22.04にログインする
# -d でLinuxディストリビューションを指定可能
$ wsl -d Ubuntu-22.04
# rootから管理ユーザーに切り替える
(Ubuntu-root) $ ls /home/shino/
(Ubuntu-root) $ su shino
(Ubuntu-shino) $ cd ~
(Ubuntu-shino) $
# テキストエディタをインストールする
(Ubuntu-shino) $ sudo apt install vim
# Linuxディストリビューションの起動周りを管理する
# -->> /etc/wsl.conf にデフォルトのユーザー名を指定する
(Ubuntu-shino) $ sudo vim /etc/wsl.conf
## 以下を /etc/wsl.conf に追記する
# -->> systemdを有効化する
# -->> デフォルトのユーザーを管理ユーザーにする
[boot]
systemd=true
[user]
default=shino
# <<-- ここまで
# Ubuntuからログアウトする
(Ubuntu-shino) $ exit
(Ubuntu-root) $ exit
# WSL2をシャットダウンして再起動する
$ wsl --shutdown
# 再度Ubuntuにログインする
$ wsl -d Ubuntu-22.04
(Ubuntu-shino) $ whoami
# shino
######
### 管理ユーザーでログインできていればOK
######
WSL2上で大容量のデータを扱うために必要な追加の作業用仮想ディスクを作成し、Ubuntuに自動マウントの設定を付与する
続いて、Linuxディストリビューション上で大容量のファイルを格納できるよう、Linuxディストリビューションに追加の仮想ディスクを割り当てます。WSL2ではWindowsのパーティションをLinuxへ直接マウントすることもできるのですが、Windowsのパーティションを使ってしまうとファイルシステムのフォーマットタイプがWindows向けとなるため不便です。そこで今回は仮想ディスクを利用することとしました。
仮想ディスクを作成する
まず、Windows Power Shell上で diskpart
コマンドを利用して仮想ディスクを作成する。今回は仮想ディスクを E:\wsl2\storage\
以下に extra_ubuntu_work.vhdx
作成します。
# 仮想ディスクを格納するディレクトリを作成する
$ New-Item -Path 'E:\wsl2\storage' -ItemType Directory
$ cd E:\wsl2\storage\
# Windows Power Shell上で
# diskpartを起動する
$ diskpart
# 容量2TBの可変サイズの仮想ディスクを指定したディレクトリに作成します
DISKPART> create vdisk file="E:\wsl2\storage\extra_ubuntu_work.vhdx" maximum=2000000 type=expandable
DISKPART> exit
######
### 続いて仮想ディスクを利用できるようにします
######
仮想ディスク上にファイルシステムを構築し、Linuxにマウントする
続いて、仮想ディスクをWSL2に接続し、Ubuntu上で仮想ディスクをext4形式でフォーマットします。フォーマット後 wsl --unmount
して、再度 wsl --mount
することにより、 Ubuntuから仮想ディスクにより作成したパーティションを認識できることを確認 します。
# 仮想ディスクをWSLに接続する
$ pwd
# E:\wsl2\storage
$ wsl --mount --vhd 'E:\wsl2\storage\extra_ubuntu_work.vhdx' --bare
# Ubuntuへ移動します
$ wsl -d Ubuntu-22.04
######
### Ubuntu上で仮想ディスクを認識できていることを確認する
######
# -->> 2TBの仮想ディスクがsdcとして接続されていることを確認できます
(Ubuntu) $ lsblk
# NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
# sda 8:0 0 388.4M 1 disk
# sdb 8:16 0 8G 0 disk [SWAP]
# sdc 8:32 0 1.9T 0 disk
# sdd 8:48 0 1T 0 disk /mnt/wslg/distro
# /
######
### 仮想ディスク(/dev/sdc)をext4で初期化する
######
(Ubuntu) $ sudo mkfs.ext4 /dev/sdc
# [sudo] password for shino:
# mke2fs 1.46.5 (30-Dec-2021)
# Discarding device blocks: done
# Creating filesystem with 512000000 4k blocks and 128000000 inodes
# Filesystem UUID: a910d601-ea8b-4378-85f6-7806bd235e11
# Superblock backups stored on blocks:
# 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
# 4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
# 102400000, 214990848
#
# Allocating group tables: done
# Writing inode tables: done
# Creating journal (262144 blocks): done
# Writing superblocks and filesystem accounting information: done
(Ubuntu) $ exit
######
### 仮想ディスクをunmountする
######
$ pwd
# E:\wsl2\storage
$ ls
# Mode LastWriteTime Length Name
# ---- ------------- ------ ----
# -a---- 2025/01/03 13:26 33491517440 extra_ubuntu_work.vhdx
$ wsl --unmount \\?\E:\wsl2\storage\extra_ubuntu_work.vhdx
######
### ext4のパーティションをmountする
######
$ wsl --mount --vhd 'E:\wsl2\storage\extra_ubuntu_work.vhdx' --name work
# ディスクは '/mnt/wsl/work' として正常にマウントされました。
# 注: /etc/wsl.conf で automount.root 設定を変更した場合、場所は異なります。
# 'wsl.exe --unmount \\?\E:\wsl2\storage\extra_ubuntu_work.vhdx' を実行してください。
######
### Ubuntuにmountされていることを確認する
######
$ wsl -d Ubuntu-22.04
# dfコマンドで /dev/sdc がマウントされていることを確認する
(Ubuntu) $ df
# Filesystem 1K-blocks Used Available Use% Mounted on
# ...
# /dev/sdc 2014729904 28 1912313492 1% /mnt/wsl/work
# ...
# C:\ 975433368 368943840 606489528 38% /mnt/c
# D:\ 488384508 113392 488271116 1% /mnt/d
# E:\ 976760828 69439352 907321476 8% /mnt/e
# ...
仮想ディスクを自動的にマウントするための設定を追加する
前手順の場合、毎回Windows起動時に wsl.exe --mount
を実行しなければならず、不便です。そこで /etc/wsl.conf
の [boot]
セクションの command
へ起動時に実行するスクリプトファイルを指定し、 そのスクリプトファイルの中で wsl.exe --mount
を実行するよう設定し、Windows起動直後から仮想ディスクをWSL2から使えるようにします。
$ wsl -d Ubuntu-22.04
# 仮想ディスクをマウントするスクリプトを作成する
# -->> 以下の内容を /root/boot.sh に記入して保存
# -->> wsl.exe の拡張子は省略禁止
(Ubuntu) $ sudo vim /root/boot.sh
# ================
#!/bin/sh
exec >/root/boot$$.log 2>&1
echo "$PATH" | grep -q /mnt/c || export PATH="$PATH:/mnt/c/Windows/System32"
echo "PATH: $PATH"
set -x
wsl.exe --list -v
wsl.exe --mount --vhd 'E:\wsl2\storage\extra_ubuntu_work.vhdx' --name work
# ================
# スクリプトに実行権限を付与する
(Ubuntu) $ sudo chmod +x /root/boot.sh
(Ubuntu) $ sudo ls -l /root/boot.sh
-rwxr-xr-x 1 root root 227 Jan 3 14:17 /root/boot.sh
# スクリプトが起動時に実行されるよう wsl.conf に指定する
(Ubuntu) $ sudo vim /etc/wsl.conf
# ================
[boot]
systemd=true
command=/root/boot.sh
[user]
default=shino
# ================
######
### wslを停止し、Windowsを再起動する
######
(Ubuntu) $ exit
$ wsl --shutdown
# <<-- Windowsの再起動
######
### 再起動後にマウントできていることを確認する
######
$ wsl -d Ubuntu-22.04
(Ubuntu) $ df
# Filesystem 1K-blocks Used Available Use% Mounted on
# ...
# C:\ 975433368 368855396 606577972 38% /mnt/c
# D:\ 488384508 113392 488271116 1% /mnt/d
# E:\ 976760828 69460860 907299968 8% /mnt/e
# /dev/sdd 2014729904 28 1912313492 1% /mnt/wsl/work
Ubuntuの初期設定を行う
パッケージを最新の状態へと更新し、開発ツールをインストールする
以降はUbuntu上での作業となりますので wsl -d Ubuntu-22.04
で予めUbuntuの環境にログインしてください。ログイン後、sudo apt update
と sudo apt upgrade
を実行し、Ubuntuを構成するパッケージを最新の状態へと更新します。その後、 開発に広く利用されているパッケージをインストール します。
# -->> wsl -d Ubuntu-22.04 でログインする
######
### パッケージを最新の状態へと更新する
######
$ sudo apt update
$ sudo apt upgrade
# Ubuntuのバージョンを確認
$ lsb_release -a
# No LSB modules are available.
# Distributor ID: Ubuntu
# Description: Ubuntu 22.04.5 LTS
# Release: 22.04
# Codename: jammy
######
### 開発に広く利用されているパッケージをインストールする
######
$ sudo apt install -y curl git wget cmake
Dockerをインストールする
次に、 Ubuntu上にDockerをインストール します。ここまで来ると"WSL2で何かしている"というよりは、純粋にCLIベースでUbuntuを利用している感覚とほぼ同じですね。Dockerの公式サイト内にある「Ubuntu向けのインストール手順」を参考に環境を構築します。
# 作業ディレクトリへ移動する
$ cd ~
######
### 古いDockerのパッケージが含まれていれば削除する
######
$ for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
######
### Dockerをインストールするための前準備をする
### -->> Docker公式のUbuntu向けインストール手順をそのまま実行
######
$ sudo apt-get update
$ sudo apt-get install ca-certificates curl
$ sudo install -m 0755 -d /etc/apt/keyrings
$ sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
$ sudo chmod a+r /etc/apt/keyrings/docker.asc
$ echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] 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-get update
######
### Dockerをインストールする
######
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
######
### sudoなしでDockerを実行できるようにグループを設定する
######
$ sudo groupadd docker
$ sudo gpasswd -a $USER docker
$ sudo systemctl restart docker
$ exit
######
# (Windows Power Shell に戻るので wsl -d Ubuntu-22.04 で再度ログイン)
######
######
### Dockerが動作することを確認する
######
$ docker run hello-world
# Unable to find image 'hello-world:latest' locally
# latest: Pulling from library/hello-world
# c1ec31eb5944: Pull complete
# Digest: sha256:5b3cc85e16e3058003c13b7821318369dad01dac3dbb877aac3c28182255c724
# Status: Downloaded newer image for hello-world:latest
#
# Hello from Docker!
# This message shows that your installation appears to be working correctly.
# ...
# 利用し終えたコンテナを確認する
$ docker container ls -a
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 0d781e24e5e9 hello-world "/hello" 37 seconds ago Exited (0) 35 seconds ago ecstatic_swanson
# 利用し終えたコンテナを削除する
$ docker container rm 0d781e24e5e9
NVIDIAのGPUリソースを活用するための環境を構築する
NVIDIA GPUドライバ
Windows Subsystem for Linux 2の環境では、GPUに対応したドライバが「Windows」にインストールされていればUbuntuから nvidia-smi
でGPUリソースへアクセスすることが可能です。そのため、 ベアメタルで動作するUbuntuでは必要とされていたLinux向けのGPUドライバをインストールする作業は不要 です。
# Linux向けのドライバをインストールすることなく
# WSL上のUbuntuからnvidia-smiでGPUリソースを確認できる
$ nvidia-smi
# ...
CUDAをインストールする
WSL上のUbuntuにCUDA Toolkitをインストールする方法は、CUDAの配布サイトより 「Distribution:WSL-Ubuntu」「Version:2.0」「Installer Type:deb (local)」 の手順をご参照ください。
※別のLinuxディストリビューションである「Debian」もUbuntuの派生元であるLinuxディストリビューションのため、ある程度の互換性は保たれており、本手順で動作します。ただ特別な理由がなければ機械学習の開発を主とされる方はLinuxディストリビューションとして「Ubuntu」を選択した方が良さそうです。
$ cd ~
######
### WSL向けのインストール手順を利用します
######
# インストールに必要なpinファイルをダウンロードします
$ wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-wsl-ubuntu.pin
# pinファイルをレポジトリ情報内へ格納します
$ sudo mv cuda-wsl-ubuntu.pin /etc/apt/preferences.d/cuda-repository-pin-600
# インストーラをダウンロードします
$ wget https://developer.download.nvidia.com/compute/cuda/12.6.3/local_installers/cuda-repo-wsl-ubuntu-12-6-local_12.6.3-1_amd64.deb
# インストーラを展開します
$ sudo dpkg -i cuda-repo-wsl-ubuntu-12-6-local_12.6.3-1_amd64.deb
# CUDAをインストールするためのリポジトリ情報をインストールします
$ sudo cp /var/cuda-repo-wsl-ubuntu-12-6-local/cuda-*-keyring.gpg /usr/share/keyrings/
# リポジトリ情報を最新にします
$ sudo apt-get update
# CUDA Toolkitをインストールします
$ sudo apt-get -y install cuda-toolkit-12-6
インストール後に念のため、 正しくインストールできているかを確認しておきましょう。githubで公開されているcuda-samplesを利用 し、CUDAのインタフェースを叩いてみます。
$ cd ~
######
### CUDAのサンプルアプリケーションを取得する
######
$ git clone https://github.com/NVIDIA/cuda-samples.git
######
### 作業ディレクトリへ移動
######
$ cd cuda-samples
$ cd Samples/1_Utilities/bandwidthTest
$ pwd
# /home/shino/cuda-samples/Samples/1_Utilities/bandwidthTest
######
### サンプルプログラムをビルドする
######
$ make
# /usr/local/cuda/bin/nvcc -ccbin g++ -I../../../Common -m64 --threads 0 --std=c++11 -gencode arch=compute_50,code=sm_50 -gencode arch=compute_52,code=sm_52 -gencode arch=compute_60,code=sm_60 -gencode arch=compute_61,code=sm_61 -gencode arch=compute_70,code=sm_70 -gencode arch=compute_75,code=sm_75 -gencode arch=compute_80,code=sm_80 -gencode arch=compute_86,code=sm_86 -gencode arch=compute_89,code=sm_89 -gencode arch=compute_90,code=sm_90 -gencode arch=compute_90,code=compute_90 -o bandwidthTest.o -c bandwidthTest.cu
# /usr/local/cuda/bin/nvcc -ccbin g++ -m64 -gencode arch=compute_50,code=sm_50 -gencode arch=compute_52,code=sm_52 -gencode arch=compute_60,code=sm_60 -gencode arch=compute_61,code=sm_61 -gencode arch=compute_70,code=sm_70 -gencode arch=compute_75,code=sm_75 -gencode arch=compute_80,code=sm_80 -gencode arch=compute_86,code=sm_86 -gencode arch=compute_89,code=sm_89 -gencode arch=compute_90,code=sm_90 -gencode arch=compute_90,code=compute_90 -o bandwidthTest bandwidthTest.o
# mkdir -p ../../../bin/x86_64/linux/release
# cp bandwidthTest ../../../bin/x86_64/linux/release
######
### サンプルプログラムを実行する
### -->> PASSすればCUDAは機能している
######
$ ./bandwidthTest
# [CUDA Bandwidth Test] - Starting...
# Running on...
#
# Device 0: NVIDIA GeForce RTX 3060 Ti
# Quick Mode
#
# Host to Device Bandwidth, 1 Device(s)
# PINNED Memory Transfers
# Transfer Size (Bytes) Bandwidth(GB/s)
# 32000000 24.2
#
# Device to Host Bandwidth, 1 Device(s)
# PINNED Memory Transfers
# Transfer Size (Bytes) Bandwidth(GB/s)
# 32000000 26.3
#
# Device to Device Bandwidth, 1 Device(s)
# PINNED Memory Transfers
# Transfer Size (Bytes) Bandwidth(GB/s)
# 32000000 387.9
#
# Result = PASS
#
# NOTE: The CUDA Samples are not meant for performance measurements. Results may vary when GPU Boost is enabled.
PASSできていますね!問題なさそうです!
cuDNNをインストールする
続いて、cuDNNをインストールします。cuDNNは、NVIDIA CUDAを活用できるディープニューラルネットワークライブラリです。ニューラルネットワーク用の プリミティブなGPUアクセラレーションライブラリ として機能します。cuDNNのインストール方法はベアメタルのLinuxと同じです。
######
### Ubuntu22.04向けのインストール手順を利用します
######
$ cd ~
# インストーラをダウンロードします
$ wget https://developer.download.nvidia.com/compute/cudnn/9.6.0/local_installers/cudnn-local-repo-ubuntu2204-9.6.0_1.0-1_amd64.deb
# インストーラを展開します
$ sudo dpkg -i cudnn-local-repo-ubuntu2204-9.6.0_1.0-1_amd64.deb
# リポジトリへのアクセスに必要なGPG鍵をインストールします
$ sudo cp /var/cudnn-local-repo-ubuntu2204-9.6.0/cudnn-*-keyring.gpg /usr/share/keyrings/
# リポジトリの情報を最新にします
$ sudo apt-get update
# cuDNNをインストールします
$ sudo apt-get -y install cudnn
# cuDNNとCUDA12.xを連携させるためのライブラリをインストールします
$ sudo apt-get -y install cudnn-cuda-12
NVIDIA Container Toolkitをインストールする
最後に、Dockerのコンテナ上からGPUリソースへアクセスできるようにするNVIDIA Container Toolkitをインストールします。こちらも ベアメタルのLinuxと同じインストール手順で問題ありません。今回利用しているLinuxディストリビューションはUbuntuであるため、ここではaptコマンドを利用したインストール方法 を利用します。
######
### NVIDIA Container Toolkitをインストールする
######
# リポジトリを設定します
$ 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/stable/deb/nvidia-container-toolkit.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-get update
# NVIDIA Container Toolkitをインストールします
$ sudo apt-get install -y nvidia-container-toolkit
######
### DockerとNVIDIA Container Toolkitを連携させる
######
# コンテナランタイムとしてDockerを選択します
$ sudo nvidia-ctk runtime configure --runtime=docker
# Dockerサービスを再起動します
$ sudo systemctl restart docker
最後に、以下のコンテナイメージを利用してコンテナ上からGPUリソースにアクセスできるかを確認します。
######
### Dockerコンテナ内からGPUにアクセスできることを確認する
######
$ docker run --rm --gpus all nvidia/cuda:12.6.3-cudnn-runtime-ubuntu24.04 nvidia-smi
# ==========
# == CUDA ==
# ==========
#
# CUDA Version 12.6.3
#
# Container image Copyright (c) 2016-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# This container image and its contents are governed by the NVIDIA Deep Learning Container License.
# By pulling and using the container, you accept the terms and conditions of this license:
# https://developer.nvidia.com/ngc/nvidia-deep-learning-container-license
#
# A copy of this license is made available in this container at /NGC-DL-CONTAINER-LICENSE for your convenience.
#
# Fri Jan 3 08:17:27 2025
# +-----------------------------------------------------------------------------------------+
# | NVIDIA-SMI 560.35.02 Driver Version: 560.94 CUDA Version: 12.6 |
# |-----------------------------------------+------------------------+----------------------+
# | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
# | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
# | | | MIG M. |
# |=========================================+========================+======================|
# | 0 NVIDIA GeForce RTX 3060 Ti On | 00000000:01:00.0 On | N/A |
# | 36% 33C P8 21W / 200W | 1185MiB / 8192MiB | 5% Default |
# | | | N/A |
# +-----------------------------------------+------------------------+----------------------+
#
# +-----------------------------------------------------------------------------------------+
# | Processes: |
# | GPU GI CI PID Type Process name GPU Memory |
# | ID ID Usage |
# |=========================================================================================|
# | No running processes found |
# +-----------------------------------------------------------------------------------------+
UbuntuからWindows上のWebカメラにアクセスする
機械学習の作業をしているとWebカメラをUbuntuから使いたくなることもあるかと思います。そうした場合に備えて、以下の手順を参考にUbuntuからWebカメラを使えるようにします。
まず、Power Shell上でアプリケーションをインストールします。インストール後、必ずWindowsを再起動してください(再起動後 usbipdコマンドが有効になります)
$ winget install usbipd
# 'msstore' ソースでは、使用する前に次の契約を表示する必要があります。
# Terms of Transaction: https://aka.ms/microsoft-store-terms-of-transaction
# ソースが正常に機能するには、現在のマシンの 2 文字の地理的リージョンをバックエンド サービスに送信する必要があります (例: "US")。
#
# すべてのソース契約条件に同意しますか?
# [Y] はい [N] いいえ: Y
# インストールが完了しました
次にUbuntu上に必要なツールをインストールし、Webカメラに対応したLinuxカーネルをビルドします。
# <<-- wsl -d Ubuntu-22.04 でUbuntuへログインする
# 必要な開発ツールをインストールする
sudo apt install linux-tools-generic hwdata
# -->> https://github.com/PINTO0309/wsl2_linux_kernel_usbcam_enable_conf
# の手順に従ってLinuxカーネルを入れ替えます
# まずLinuxのバージョンを確認します
$ uname -r -v
5.15.167.4-microsoft-standard-WSL2 #1 SMP Tue Nov 5 00:21:55 UTC 2024
######
# 5.15.167.4の部分を以降の手順で使います
######
# Webカメラを制御するツールとLinuxカーネルのビルドに必要なツールをインストールします
$ sudo apt install -y \
build-essential flex bison \
libgtk-3-dev libelf-dev libncurses-dev autoconf \
libudev-dev libtool zip unzip v4l-utils libssl-dev \
python3-pip cmake git iputils-ping net-tools dwarves \
guvcview python-is-python3 bc
# ビルドディレクトリへ移動し、Linuxカーネルのバージョンと
# Windowsのユーザー名を環境変数に設定します(C:\Usersに表示されているユーザー名)
$ cd /usr/src
$ TAGVERNUM=5.15.167.4 \
&& TAGVER=linux-msft-wsl-${TAGVERNUM} \
&& WINUSERNAME=ixiv2
# Linuxカーネルのソースコードを取得します
$ sudo git clone --depth 1 -b ${TAGVER} \
https://github.com/microsoft/WSL2-Linux-Kernel.git \
${TAGVERNUM}-microsoft-standard \
&& cd ${TAGVERNUM}-microsoft-standard
# Linuxのビルドに必要なコンフィグファイルのうち
# 最もバージョンの近いバージョンのものを入手します
$ sudo wget -O .config https://raw.githubusercontent.com/PINTO0309/wsl2_linux_kernel_usbcam_enable_conf/refs/heads/main/linux-msft-wsl-5.15.90.1/config-Ubuntu-22.04 \
&& sudo chmod 777 .config \
&& sudo make clean
# Linuxカーネルをビルドします
# .configの差分でいくつか確認されますが基本はデフォルトのままで良いでしょう
$ sudo make -j$(nproc) KCONFIG_CONFIG=.config \
&& sudo make modules_install -j$(nproc) \
&& sudo make install -j$(nproc)
# Mitigations for CPU vulnerabilities (CPU_MITIGATIONS) [Y/n/?] (NEW) <Enter>
# Remove the kernel mapping in user mode (PAGE_TABLE_ISOLATION) [Y/n/?] y
# Avoid speculative indirect branches in kernel (RETPOLINE) [Y/n/?] y
# Enable return-thunks (RETHUNK) [Y/n/?] y
# Enable UNRET on kernel entry (CPU_UNRET_ENTRY) [Y/n/?] y
# Enable IBPB on kernel entry (CPU_IBPB_ENTRY) [Y/n/?] y
# Enable IBRS on kernel entry (CPU_IBRS_ENTRY) [Y/n/?] y
# Mitigate speculative RAS overflow on AMD (CPU_SRSO) [Y/n/?] (NEW) <Enter>
# Force GDS Mitigation (GDS_FORCE_MITIGATION) [N/y/?] (NEW) <enter>
# RFDS Mitigation (MITIGATION_RFDS) [Y/n/?] (NEW) <enter>
# Mitigate Spectre-BHB (Branch History Injection) (MITIGATION_SPECTRE_BHI) [Y/n/?] (NEW) <enter>
# ...
# Supply flow table statistics in procfs (NF_FLOW_TABLE_PROCFS) [Y/n/?] (NEW) <enter>
# ...
# NFS server support for NFS version 2 (DEPRECATED) (NFSD_V2) [N/y/?] (NEW) <enter>
# Compile the kernel with debug info (DEBUG_INFO) [Y/n/?] y
# Reduce debugging information (DEBUG_INFO_REDUCED) [N/y/?] n
# Compressed debugging information (DEBUG_INFO_COMPRESSED) [N/y/?] n
# Produce split debuginfo in .dwo files (DEBUG_INFO_SPLIT) [N/y/?] n
# DWARF version
# > 1. Rely on the toolchain's implicit default DWARF version (DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT)
# 2. Generate DWARF Version 4 debuginfo (DEBUG_INFO_DWARF4)
# 3. Generate DWARF Version 5 debuginfo (DEBUG_INFO_DWARF5) (NEW)
# choice[1-3?]: 1
# ...
# <Linuxカーネルのビルドが走ります>
# ...
# ビルドしたLinuxカーネルをWindows上に配置します
$ sudo rm /mnt/c/Users/${WINUSERNAME}/vmlinux
$ sudo cp /usr/src/${TAGVERNUM}-microsoft-standard/vmlinux /mnt/c/Users/${WINUSERNAME}/
# Windowsのカーネルコンフィグを変更します
# ユーザー名はお使いのPCのものを指定してください
$ sudo vim /mnt/c/Users/${WINUSERNAME}/.wslconfig
# ====== ここから
[wsl2]
kernel=C:\\Users\\ixiv2\\vmlinux
# ====== ここまで
# Power Shellに戻ります
$ exit
ビルドしたLinuxカーネルを使ってUbuntuを起動します。
# Power ShellからLinuxを停止し、再起動します
$ wsl --shutdown
# ログインします
$ wsl -d Ubuntu-22.04
# カーネルのバージョンを確認します
# バージョン末尾に(+)がついていれば成功です
(Ubuntu) $ uname -r -v
5.15.167.4-microsoft-standard-WSL2+ #1 SMP Fri Jan 10 04:59:23 JST 2025
それではWebカメラをUbuntuに接続してみましょう。Power Shellから以下の手順を実施することで、WebカメラをUbuntuへアタッチして使うことができます。usbipdコマンドがエラーになる場合はWindowsを再起動してください。
###
# Windowsに接続されているUSBデバイスのリストを表示します
# -->> 以下の例ではUSBカメラが8-3として認識されています
###
$ usbipd list
# Connected:
# BUSID VID:PID DEVICE STATE
# 1-4 eba4:7588 USB3.0 HD Audio Capture, USB3.0 HD Video Capture Not shared
# 1-13 26ce:01a2 USB 入力デバイス Not shared
# 6-1 31aa:1100 CIR125 ICC Not shared
# 7-4 058f:6362 USB 大容量記憶装置 Not shared
# 8-1 0d8c:0171 REIYIN Audio, USB 入力デバイス Not shared
# 8-3 328f:006d HD Webcam eMeet C960 Not shared
# 8-4 046d:c08b G502 HERO, USB 入力デバイス, 仮想 HID フレームワーク (VHF... Not shared
###
# Ubuntu-22.04をRunning状態に切り替えます
###
$ wsl -d Ubuntu-22.04
Ubuntu-22.04を実行した状態で、別のPower Shellウィンドウから以下の操作を実行 し、WebカメラをLinuxにアタッチしてください。
###
# 別のPowerShellのウィンドウ開いてUbuntuが実行中であることを確認します
###
$ wsl -l -v
# NAME STATE VERSION
# * Ubuntu-22.04 Running 2
###
# USBカメラをUbuntu-22.04に接続します
###
# Webカメラ(ここでは8-3)をUbuntuへアタッチします
$ usbipd bind --busid 8-3
$ usbipd attach --wsl Ubuntu-22.04 --busid 8-3
# 接続できていることを確認します
$ usbipd list
# Connected:
# BUSID VID:PID DEVICE STATE
# 1-4 eba4:7588 USB3.0 HD Audio Capture, USB3.0 HD Video Capture Not shared
# 1-13 26ce:01a2 USB 入力デバイス Not shared
# 6-1 31aa:1100 CIR125 ICC Not shared
# 7-4 058f:6362 USB 大容量記憶装置 Not shared
# 8-1 0d8c:0171 REIYIN Audio, USB 入力デバイス Not shared
# 8-3 328f:006d HD Webcam eMeet C960 Attached
# 8-4 046d:c08b G502 HERO, USB 入力デバイス, 仮想 HID フレームワーク (VHF... Not shared
Ubuntu-22.04からUSB Webカメラが見えることを確認します。
###
# Ubuntu上でlsusbを実行し、USBデバイスが見えることを確認します
###
$ lsusb
# Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
# Bus 001 Device 002: ID 328f:006d EMEET HD Webcam eMeet C960
# Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
# /dev/video* デバイスが作られていることを確認します
$ ls /dev/video*
# video0 video1
# ユーザーから利用できるようにします
$ sudo chmod 0777 /dev/video0
USBカメラをUbuntuから利用できることを確認する
USBカメラのテストプログラムを実行して、UbuntuからUSBカメラを利用できることを確認します。テストプログラムは以下の記事のものを参考とさせていただきました。私の環境では、[ WARN:0@10.310] global /io/opencv/modules/videoio/src/cap_v4l.cpp (1000) tryIoctl VIDEOIO(V4L2:/dev/video0): select() timeout.
が発生したためcap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'))
の行が必要でした
# 作業ディレクトリへ移動する
$ cd ~
# PythonからWebカメラを利用できるようopencv-pythonをインストールする
$ pip3 install opencv-python opencv-contrib-python
# テストプログラムを作成する
$ vim usbcam_test.py
## ====== ここから
import cv2
W=640
H=480
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, W)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, H)
cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'))
while True:
ret, frame = cap.read()
if not ret:
continue
cv2.imshow('usb cam test', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
## ====== ここまで
$ python3 usbcam_test.py
利用後はPower Shellから以下の手順でWebカメラをデタッチしてください。
# UbuntuからUSBデバイスを除去する
$ usbipd detach --busid 8-3
# 抜去できたことを確認する
$ usbipd list
# Connected:
# BUSID VID:PID DEVICE STATE
# 1-4 eba4:7588 USB3.0 HD Audio Capture, USB3.0 HD Video Capture Not shared
# 1-13 26ce:01a2 USB 入力デバイス Not shared
# 6-1 31aa:1100 CIR125 ICC Not shared
# 7-4 058f:6362 USB 大容量記憶装置 Not shared
# 8-1 0d8c:0171 REIYIN Audio, USB 入力デバイス Not shared
# 8-3 328f:006d HD Webcam eMeet C960 Shared
# 8-4 046d:c08b G502 HERO, USB 入力デバイス, 仮想 HID フレームワーク (VHF... Not shared
# 共有を解除する
$ usbipd unbind --busid 8-3
# 解除できていることを確認する
$ usbipd list
# Connected:
# BUSID VID:PID DEVICE STATE
# 1-4 eba4:7588 USB3.0 HD Audio Capture, USB3.0 HD Video Capture Not shared
# 1-13 26ce:01a2 USB 入力デバイス Not shared
# 6-1 31aa:1100 CIR125 ICC Not shared
# 7-4 058f:6362 USB 大容量記憶装置 Not shared
# 8-1 0d8c:0171 REIYIN Audio, USB 入力デバイス Not shared
# 8-3 328f:006d HD Webcam eMeet C960 Not shared
# 8-4 046d:c08b G502 HERO, USB 入力デバイス, 仮想 HID フレームワーク (VHF... Not shared
以上で、機械学習の実行や、Yocto ProjectによりLinuxディストリビューションをビルドするために必要な リッチなストレージを備え、GPUリソースも活用できるWindows上のLinux環境の構築は完了 となります。私の環境は、空き時間にゲームをするWindows PCにLinux環境を準備したので、CPUコアがたくさん使えます。とても便利ですね。本環境を使った開発手順についても、追って記事にしたいと思います。
手始めに下記の記事の手順でYocto Projectを使ったLinuxディストリビューションのビルドを試してみましたが、CPUコアとメモリを余すことなく利用できることから、とても快適に開発することができました。
皆様の開発に是非ご活用ください!!