2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Windows Subsystem for Linux(WSL)を利用してリッチなストレージを備えたUbuntu22.04 × CUDA × Dockerの開発環境を構築する

Last updated at Posted at 2025-01-09

最近、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 を実行し、スペックを確認します
    • 皆様がインストールされる際の目安としてご参照ください

NVIDIA GPUドライバを最新版へと更新する

事前に、WindowsにインストールされているNVIDIAのGeForceドライバーを最新のものにアップデートします。GeForceドライバーより 「ドライバーの自動更新」-「今すぐダウンロード」 をクリックし最新の状態に更新してください。

スクリーンショット 2025-01-03 015010.png

参考:今回利用したWSL2向けWindowsの構成

今回WSL2をセットアップするためにベースとするWindowsのスペックは以下の通りです。本環境はIntel Core i5-12600K × RAM 64GBのWindows 11 Pro上で動作しています。また、 仮想マシンを格納するためのストレージとして、PCI-express接続のNVMe SSD 1TBをEドライブに接続しました。後から移動もできますが、開発したい内容にあった適当な容量のストレージを予めご準備ください。

{D90DB5ED-7E21-4066-BDDF-8C4A69D0E40B}.png

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 により有効化します。これには再起動を求められることがありますので、確認の上、再起動しましょう。

{14EDEAAB-463D-4290-891F-E7E30A164C90}.png

# 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を最新の状態に更新します。

スクリーンショット 2025-01-03 021036.png

### 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」 をインストールしてみます。

{6DABB762-DD3C-477B-9892-B2069A7FEF33}.png

$ 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

{A45D72DC-B907-4BD6-AC01-042ABB70AB95}.png

Ubuntuの初期設定を行う

パッケージを最新の状態へと更新し、開発ツールをインストールする

以降はUbuntu上での作業となりますので wsl -d Ubuntu-22.04 で予めUbuntuの環境にログインしてください。ログイン後、sudo apt updatesudo 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

{603C417F-7789-4F78-BA54-1E256D963A9D}.png

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
# ...

{31059872-EBA1-4670-A9F4-0375BCC2A1ED}.png

CUDAをインストールする

WSL上のUbuntuにCUDA Toolkitをインストールする方法は、CUDAの配布サイトより 「Distribution:WSL-Ubuntu」「Version:2.0」「Installer Type:deb (local)」 の手順をご参照ください。

※別のLinuxディストリビューションである「Debian」もUbuntuの派生元であるLinuxディストリビューションのため、ある程度の互換性は保たれており、本手順で動作します。ただ特別な理由がなければ機械学習の開発を主とされる方はLinuxディストリビューションとして「Ubuntu」を選択した方が良さそうです。

image.png

$ 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できていますね!問題なさそうです!

{788E47AB-B844-4EE0-9A2F-4143CA603B0D}.png

cuDNNをインストールする

続いて、cuDNNをインストールします。cuDNNは、NVIDIA CUDAを活用できるディープニューラルネットワークライブラリです。ニューラルネットワーク用の プリミティブなGPUアクセラレーションライブラリ として機能します。cuDNNのインストール方法はベアメタルのLinuxと同じです。

image.png

######
### 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コマンドを利用したインストール方法 を利用します。

{98DC7356-B21B-450F-BCDB-274EB5324787}.png

######
### 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にアタッチしてください。

{C3AF2F5B-9B4E-4513-BDD8-D63C585D0115}.png

###
# 別の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

{690D2A85-1A1E-4616-91DC-6C0019201037}.png

利用後は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

{C4FA9A53-E175-4D7B-8533-CB9CD9BDAF01}.png


以上で、機械学習の実行や、Yocto ProjectによりLinuxディストリビューションをビルドするために必要な リッチなストレージを備え、GPUリソースも活用できるWindows上のLinux環境の構築は完了 となります。私の環境は、空き時間にゲームをするWindows PCにLinux環境を準備したので、CPUコアがたくさん使えます。とても便利ですね。本環境を使った開発手順についても、追って記事にしたいと思います。

{F508E788-988E-40D9-9058-FF6A5A4553DE}.png

手始めに下記の記事の手順でYocto Projectを使ったLinuxディストリビューションのビルドを試してみましたが、CPUコアとメモリを余すことなく利用できることから、とても快適に開発することができました。

image.png


皆様の開発に是非ご活用ください!!


2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?