問題の概要:Dockerコンテナ内でGPUが認識されない
AI開発、特に深層学習のモデルトレーニングや推論をDocker環境で行う際、コンテナ内からホストマシンのNVIDIA GPUを利用できるようにする設定は必須です。しかし、NVIDIA Container Toolkit(旧称:nvidia-docker2)のインストールや設定を誤ると、以下のようなエラーに遭遇することが頻繁にあります。
代表的なエラーメッセージ
# Dockerコンテナ内で `nvidia-smi` を実行した場合
docker: Error response from daemon: could not select device driver "" with capabilities: [[gpu]].
# または、PyTorch/TensorFlowを使用時
RuntimeError: No CUDA GPUs are available
# `nvidia-smi` コマンド自体が見つからない
bash: nvidia-smi: command not found
これらのエラーは、DockerデーモンがNVIDIA GPUを認識するためのランタイム設定が正しく行われていない、あるいはドライバやツールキットのインストールに問題があることを示しています。
原因の解説
従来のDockerは、CPUやメモリ、ストレージなどのリソースを仮想化しますが、GPUのような特殊なハードウェアデバイスをそのままコンテナに「パススルー」する機能は標準では備えていません。NVIDIA Container Toolkitは、このギャップを埋めるためのソフトウェアスタックです。主な原因は以下の3つに分類されます。
1. 必須コンポーネントの欠落
NVIDIA Container Toolkitが正常に機能するためには、以下の全てのレイヤーが正しくインストール・設定されている必要があります。
- ホスト側NVIDIAドライバ: 物理GPUをOSが認識するための基盤。
- NVIDIA Container Toolkit: DockerとGPUを仲介するミドルウェア。
- Dockerデーモンの設定: `nvidia` をデフォルトまたは使用可能なランタイムとして登録。
このいずれかが欠けている、またはバージョンが互換性がない場合にエラーが発生します。
2. Dockerデーモンの設定不備
NVIDIA Container Toolkitをインストールしても、Dockerの設定ファイル(`/etc/docker/daemon.json`)に `nvidia` ランタイムが追加されていないと、DockerはGPUを使用する方法を知りません。
3. 権限の問題
Dockerデーモンやコンテナを実行するユーザーに適切な権限がない場合、デバイスへのアクセスが拒否されることがあります。
解決方法:ステップバイステップ設定ガイド
以下に、Ubuntu 20.04/22.04を例に、確実に設定を行う手順を説明します。他のディストリビューションでも概念は同じです。
ステップ1: 前提条件の確認
まず、ホストマシンにNVIDIA GPUドライバが正しくインストールされ、`nvidia-smi` コマンドが動作することを確認します。
# NVIDIAドライバとCUDAドライバの確認
nvidia-smi
# 期待する出力例(バージョン番号は環境により異なります)
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 525.105.17 Driver Version: 525.105.17 CUDA Version: 12.0 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 NVIDIA GeForce ... On | 00000000:01:00.0 Off | N/A |
| N/A 45C P8 N/A / N/A | 0MiB / 6144MiB | 0% Default |
+-------------------------------+----------------------+----------------------+
`nvidia-smi` がコマンドが見つからない、またはエラーを出す場合は、先にNVIDIA公式サイトからドライバをインストールしてください。
ステップ2: NVIDIA Container Toolkitのインストール
パッケージリポジトリを設定し、ツールキットをインストールします。
# パッケージリポジトリとGPGキーの設定
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-get update
sudo apt-get install -y nvidia-container-toolkit
ステップ3: Dockerデーモンの設定
インストール後、DockerがNVIDIAランタイムを使用するように設定します。
# nvidia-ctkコマンドでDocker設定を自動更新(推奨)
sudo nvidia-ctk runtime configure --runtime=docker
# または、手動で `/etc/docker/daemon.json` を編集
# 以下の内容が追加されていることを確認します。
sudo cat /etc/docker/daemon.json
# 期待する出力例:
{
"runtimes": {
"nvidia": {
"path": "/usr/bin/nvidia-container-runtime",
"runtimeArgs": []
}
}
}
重要: 既存の `daemon.json` ファイルがある場合、`nvidia-ctk` コマンドは既存の設定とマージしようとしますが、手動で編集する場合はバックアップを取り、JSONの構文エラー(カンマの抜けなど)に注意してください。
ステップ4: Dockerデーモンの再起動と設定確認
# Dockerデーモンの再起動
sudo systemctl restart docker
# 設定の確認(nvidiaランタイムが登録されているか)
docker info | grep -i runtime
# 出力例:
Runtimes: nvidia runc io.containerd.runc.v2
Default Runtime: runc
ステップ5: 動作テスト
公式のCUDAコンテナイメージを使用して、GPUがコンテナ内から見えるかテストします。
# 最もシンプルなテスト
sudo docker run --rm --runtime=nvidia --gpus all nvidia/cuda:12.0.1-base-ubuntu22.04 nvidia-smi
# より実践的なテスト (すべてのGPUを利用)
sudo docker run --rm --gpus all nvidia/cuda:12.0.1-base-ubuntu22.04 nvidia-smi
# 特定のGPUのみを指定(複数GPU環境の場合)
sudo docker run --rm --gpus '"device=0,1"' nvidia/cuda:12.0.1-base-ubuntu22.04 nvidia-smi
ここでホストと同じ `nvidia-smi` の出力が得られれば、設定は成功です。
トラブルシューティングとコード例
エラー1: “could not select device driver…”
原因: Dockerランタイム設定が不完全。
解決策:
# 1. nvidia-container-runtime のパスを確認
ls -la /usr/bin/nvidia-container-runtime
# 2. daemon.json のパス設定が正しいか確認
# パスが異なる場合(例: /usr/bin/nvidia-container-runtime.bin)、daemon.jsonを修正
sudo vi /etc/docker/daemon.json
# "path": "/usr/bin/nvidia-container-runtime.bin" に変更
# 3. Docker再起動
sudo systemctl restart docker
エラー2: “docker: Error response from daemon: unknown or invalid runtime name: nvidia”
原因: `daemon.json` の変更が適用されていない。
解決策:
# Dockerデーモンの再読み込みと再起動
sudo systemctl daemon-reload
sudo systemctl restart docker
# もしくは、Dockerソケットを直接リスタート
sudo systemctl restart docker.socket
sudo systemctl restart docker
エラー3: コンテナ内でCUDAが利用できない(PyTorch/TensorFlow)
原因: ベースイメージにCUDAライブラリが含まれていない、またはバージョン不一致。
解決策: 適切なCUDAバージョンが含まれる公式イメージを使用します。
# Dockerfileの例 (PyTorch)
FROM pytorch/pytorch:2.0.1-cuda11.7-cudnn8-runtime
# ビルドと実行
# docker build -t my-gpu-app .
# docker run --rm --gpus all my-gpu-app python -c "import torch; print(torch.cuda.is_available())"
まとめ・補足情報
NVIDIA Container Toolkitの設定は、AI開発環境をDockerで構築する上での基盤技術です。本ガイドで紹介した手順に従うことで、ほとんどの「GPUがコンテナ内で認識されない」問題は解決できるはずです。設定後は、`–gpus all` オプションを付けるだけで、コンテナ内のアプリケーションがホストのGPUリソースをフルに活用できるようになります。
最後の確認ポイント:
- ホストドライバ: `nvidia-smi` がホストで動作するか。
- ツールキットインストール: `apt list –installed | grep nvidia-container-toolkit`。
- Docker設定: `/etc/docker/daemon.json` に `nvidia` ランタイムが定義されているか。
- ランタイム登録: `docker info` で `Runtimes` に `nvidia` が含まれるか。
Docker Composeを使用する場合は、`docker-compose.yml` のサービス定義に `deploy.resources.reservations.devices` セクションを追加するか、`runtime: nvidia` を指定する必要があります。Kubernetesを利用する場合は、さらにNVIDIA Device Pluginのデプロイが必要となるので、別途公式ドキュメントを参照してください。