Windows 11+WSL 2でPyTorchからRTX 5070 Tiを使う:CUDA確認からCPU/GPU実測まで

実験日: 2026-08-24 / 実験機: Core i7-14700F、RTX 5070 Ti 16 GB、RAM 32 GB
環境: Windows 11、WSL 2、Ubuntu 26.04 LTS、Python 3.14.4、PyTorch 2.13.0+cu130

PyTorchをインストールしてサンプルが動いても、GPUを使えているとは限りません。本記事では、Windows 11上のWSL 2へPyTorchのCUDA版を導入し、torch.cuda.is_available()だけでなく、実際の行列積、GPU名、VRAM、CPUとの速度差まで確認します。

Trueが出るとひとまず安心ですが、実際の計算をGPUへ投げるまでは確認の途中です。

「コマンドを写したら動いた」で終わらず、なぜその確認が必要なのか、どの条件で測ったのか、結果から何が言えて何が言えないのかまで追います。

WSL2からGPUを使えた

このPCでは、WSL 2上のPyTorchからRTX 5070 Tiを認識し、CUDA行列積を実行できました。

  • torch.cuda.is_available()True
  • GPU:NVIDIA GeForce RTX 5070 Ti
  • PyTorch:2.13.0+cu130
  • PyTorch同梱CUDA runtime:13.0
  • GPUメモリ:15.92 GiB(PyTorchから取得)
  • 4096×4096 FP32行列積:CPU 177.845 ms、GPU 4.262 ms
  • 同条件FP32の計算部分:GPUがCPUの約41.7倍

ただし41.7倍は、行列を作る時間とCPUからGPUへ送る時間を除いた、大きな行列積だけの比較です。小さな処理やデータ転送の多いプログラムまで41.7倍になるわけではありません。

PyTorchでCPUとRTX 5070 Tiの行列積時間を比較したグラフ
PyTorchでCPUとRTX 5070 Tiの行列積時間を比較したグラフ

まず理解したい5層の関係

CUDA周りで混乱しやすい理由は、「CUDA」という語が複数の層に現れるからです。この実験では次の順に処理がつながります。

Pythonコード
  ↓
PyTorch(torch)
  ↓
PyTorch wheelに含まれるCUDA runtime / cuDNNなど
  ↓
WSL 2がWindows側GPUドライバへ橋渡し
  ↓
RTX 5070 Ti

重要なのは、WSLのUbuntuへ通常のLinux用NVIDIAドライバを重ねて入れる構成ではないことです。Windows側へWSL対応GPUドライバを入れ、WSLからその機能を利用します。Microsoftも、対応Windows、GPUドライバ、WSL、対応Linuxディストリビューションを前提として案内しています。

また、torch.version.cuda == "13.0"は「PyTorchが使うCUDA runtimeの版」です。nvidia-smiに出るドライバ版595.71とは役割も番号体系も違います。数字が一致していないこと自体は異常ではありません。

必要なもの

  • Windows 11、またはWSL GPU computeの要件を満たすWindows 10
  • NVIDIA GPUと、WSL CUDA対応のWindows側ドライバ
  • WSL 2とUbuntuなどのglibcベースLinux
  • 空き容量20 GB程度(CUDA版PyTorchと依存パッケージは大きい)
  • PowerShellを実行できること

WSLをまだ導入していない場合は、管理者PowerShellで次を実行し、必要なら再起動します。

wsl --install -d Ubuntu

本実験ではWSL 2.7.12、Linux kernel 6.18.33.2、Ubuntu 26.04 LTSを使用しました。

手順1:Windows側ドライバがWSLから見えるか確認する

PyTorchを入れる前に、GPUまでの下半分が動いているか切り分けます。PowerShellから次を実行しました。

wsl.exe -d Ubuntu -u root -- /usr/lib/wsl/lib/nvidia-smi `
  --query-gpu=name,driver_version,memory.total,compute_cap `
  --format=csv,noheader

実際の出力は次でした。

NVIDIA GeForce RTX 5070 Ti, 595.71, 16303 MiB, 12.0

ここでGPU名が出なければ、PyTorchの入れ直しへ進む前に、Windows側ドライバ、WSLの版、WSLカーネルを確認します。

手順2:記事ごとに壊れないPython仮想環境を作る

UbuntuへPythonの仮想環境とビルド用の基本パッケージを入れます。

sudo apt-get update
sudo apt-get install -y python3-venv python3-pip build-essential

次に、AI実験専用の仮想環境を作ります。

sudo python3 -m venv /opt/ai-lab/venv
sudo /opt/ai-lab/venv/bin/python -m pip install --upgrade pip setuptools wheel

仮想環境を使う理由は、OSのPythonと実験用パッケージを分離するためです。研究室で複数テーマを扱うと、「ある実験のためにNumPyを更新したら、別の実験が動かなくなった」が起きます。環境を分け、最後にpip freezeを残すと追試しやすくなります。

手順3:CUDA版PyTorchを明示して入れる

本実験ではPyTorch公式indexでPython 3.14用wheelの存在を確認し、CUDA 13.0版を固定して導入しました。

sudo /opt/ai-lab/venv/bin/python -m pip install \
  torch==2.13.0+cu130 torchvision==0.28.0+cu130 \
  --index-url https://download.pytorch.org/whl/cu130

--index-urlを省くと、意図と違うビルドを取る可能性があります。研究の再現性を重視するなら、記事を読んだ時点の最新版へ無条件に追従するより、実験で使った版を記録します。一方、将来その組み合わせが古くなった場合は、PyTorch公式の「Start Locally」でOS、package、language、compute platformを選び直してください。

手順4:importではなくCUDAまで確認する

次をverify_cuda.pyとして実行するか、Pythonへ貼り付けます。

import torch
import torchvision

print("torch", torch.__version__)
print("torchvision", torchvision.__version__)
print("cuda_available", torch.cuda.is_available())
print("cuda_runtime", torch.version.cuda)
print("device", torch.cuda.get_device_name(0))
print("capability", torch.cuda.get_device_capability(0))

a = torch.randn(2048, 2048, device="cuda")
b = torch.randn(2048, 2048, device="cuda")
torch.cuda.synchronize()
c = a @ b
torch.cuda.synchronize()

print("matmul_mean", float(c.mean()))
print("allocated_MiB", round(torch.cuda.memory_allocated() / 1024**2, 1))

実機出力です。

torch 2.13.0+cu130
torchvision 0.28.0+cu130
cuda_available True
cuda_runtime 13.0
device NVIDIA GeForce RTX 5070 Ti
capability (12, 0)
matmul_mean -0.006466319784522057
allocated_MiB 80.0

ここでは4段階で確認しています。

  1. importできる:Pythonパッケージが壊れていない
  2. is_available()True:PyTorchからCUDAを利用可能
  3. GPU名が正しい:意図したGPUが選ばれている
  4. device="cuda"の行列積が完了:実際の演算をGPUへ投入できる

Trueだけをスクリーンショットにして終えるより、実演算まで通す方が強い確認になります。

実験:CPUとGPUの行列積を公平に近づけて比べる

仮説

4096×4096のように計算量が大きい行列積では、RTX 5070 TiがCore i7-14700Fより短時間で計算する。ただしGPU起動・転送のオーバーヘッドを含む小規模処理には、その倍率をそのまま適用できない。

条件

項目 設定
行列サイズ 4096×4096を2個
演算 left @ right
乱数seed 42
CPUデータ型 FP32
GPUデータ型 FP32 / FP16 / BF16
ウォームアップ CPU 1回、GPU 3回
本計測 各7回
代表値 中央値
計測外 配列生成、CPU↔GPU転送

GPU処理は非同期で進むため、単純にtime.perf_counter()で囲むだけでは、処理が終わる前に時計を止める可能性があります。そこで各GPU計測の終了前にtorch.cuda.synchronize()を呼び、GPU完了を待ちました。この点はPyTorch公式のCUDA semanticsにも明記されています。

実測結果

実行先 データ型 中央値 推定演算性能 ピークPyTorch割当
CPU FP32 177.845 ms 0.773 TFLOPS
GPU FP32 4.262 ms 32.244 TFLOPS 288.0 MiB
GPU FP16 1.455 ms 94.466 TFLOPS 160.0 MiB
GPU BF16 1.491 ms 92.165 TFLOPS 160.0 MiB

FP32同士では、177.845 / 4.262 ≒ 41.7なので、計算部分はGPUが約41.7倍高速でした。FP16はGPU FP32より約2.93倍短時間ですが、表現できる数の精度や範囲が異なります。「速いから常にFP16へ変えてよい」ではありません。

推定TFLOPSは2 × N³ ÷ 秒で計算した、この行列積に対する値です。GPU製品仕様の理論ピークそのものではありません。

なぜ平均ではなく中央値にしたか

PC上の計測は、バックグラウンド処理、初回ライブラリロード、クロック変動などで外れ値が出ます。7回の中央値なら、1回だけ遅い値が混ざっても代表値が大きく引っ張られません。

ただし、7回で統計的に十分だと断言しているわけではありません。卒論の評価値に使うなら、反復数を増やし、平均・標準偏差・信頼区間、温度や消費電力も記録するのが次の段階です。

よくある失敗と復旧

torch.cuda.is_available()がFalse

最初に次の順で確認します。

/usr/lib/wsl/lib/nvidia-smi
/opt/ai-lab/venv/bin/python -c "import torch; print(torch.__version__, torch.version.cuda)"
/opt/ai-lab/venv/bin/python -c "import torch; print(torch.cuda.is_available())"
  • nvidia-smiも失敗:Windows側ドライバ、WSL更新、再起動を確認
  • torch.version.cudaNone:CPU版PyTorchを入れた可能性
  • GPUは見えるがPyTorchだけ失敗:wheelとPython版、ドライバ対応を確認

No module named venvまたはensurepip is not available

Ubuntuで仮想環境パッケージを入れます。

sudo apt-get update
sudo apt-get install -y python3-venv python3-pip

APT終了時のsystemd警告

本環境ではAPTのtriggerでTransport endpoint is not connectedという警告が一度出ました。ただしAPTの終了コードは0で、python3-venvなども導入済みでした。警告文字列だけで失敗と判断せず、終了コードと目的のコマンドが動くかを確認します。

速度が毎回大きく違う

  • 初回実行をそのまま採用していないか
  • GPU完了前に計測を止めていないか
  • 行列生成や転送を含めたり除いたりしていないか
  • 他のGPUアプリが動いていないか
  • 反復回数と代表値が同じか

「何秒だったか」だけでなく、どこからどこまでを測ったかが再現性の本体です。

この結果から言えること/言えないこと

言えること

  • このWindows/WSL/ドライバ/PyTorchの組み合わせでRTX 5070 Tiを利用できた
  • 4096角FP32行列積の計算部分では、同PCのCPUよりGPUが約41.7倍短時間だった
  • この条件ではFP16/BF16により、FP32より短時間かつ少ない割当メモリで計算できた

言えないこと

  • すべての機械学習モデルが41.7倍速く学習する
  • FP16/BF16でもFP32と同じ精度になる
  • 別GPU、別ドライバ、別PyTorch版でも同じ値になる
  • GPUへ移せば小さな処理も必ず速くなる

実モデルにはデータ読み込み、前処理、CPU-GPU転送、層ごとの演算、逆伝播、optimizer更新があります。今回の行列積はGPU環境の確認と、測定設計の練習です。

FashionMNISTで「実モデル」を比べる

同じ環境でFashionMNISTのCNNをCPUとGPUで学習し、epoch時間、精度、VRAM、DataLoader待ちを比較すると、実モデルでの差が見えます。行列積だけ速くても、入力待ちが長ければGPUは遊びます。この差を観察すると、機械学習実験をハードウェアのデータフローとして見る練習になります。

学習全体の順番は、既存記事「機械学習からディープラーニングまでをちゃんと理解して、FPGAに持ち込みたい」にもまとめています。本記事はそのPhase 3を、実機で再現可能にしたものです。

再現性メモ

  • 環境収集:work/ai_lab/collect_environment.py
  • ベンチマーク:work/ai_lab/benchmark_matmul.py
  • 環境JSON:work/ai_lab/results/environment.json
  • 生の計測JSON:work/ai_lab/results/matmul.json
  • 完全な依存関係:work/ai_lab/requirements-freeze.txt
  • グラフ生成:work/ai_lab/make_pytorch_setup_assets.py
  • 全スクリプトの乱数seed:42

参考:

関連記事