問題の概要:Dockerコンテナ内でGPUが認識されない
AI開発や機械学習の環境構築において、Dockerコンテナ内でGPUを利用しようとすると、以下のような問題に直面することがあります。
- PyTorchやTensorFlowをコンテナ内で実行しても、GPUが認識されずCPUで動作してしまう
nvidia-smiコマンドをコンテナ内で実行すると「コマンドが見つかりません」と表示される- Docker run時に
--gpus allオプションを指定してもエラーが発生する
具体的なエラーメッセージ例:
docker: Error response from daemon: could not select device driver "" with capabilities: [[gpu]].
RuntimeError: No CUDA GPUs are available
これらの問題は、ホストマシンにNVIDIA GPUドライバがインストールされていても、DockerコンテナとGPUを連携させるための「NVIDIA Container Toolkit」が正しく設定されていない場合に発生します。
原因の解説:DockerとGPUの連携メカニズム
従来のDockerは、コンテナ内からホストのハードウェアを直接利用する仕組みを持っていません。GPUのような特殊なデバイスをコンテナ内で使用するためには、以下のコンポーネントが必要です。
1. NVIDIA Container Toolkitの役割
NVIDIA Container Toolkitは、Dockerや他のコンテナランタイムがNVIDIA GPUにアクセスできるようにするためのソフトウェアスイートです。これにより、コンテナ内からホストのGPUドライバやCUDAライブラリを安全に利用できるようになります。
2. 必要なコンポーネント
- NVIDIA GPUドライバ: ホストOSにインストール済みであることが前提
- NVIDIA Container Toolkit: DockerとGPUを仲介するソフトウェア層
- nvidia-container-runtime: Dockerのランタイムとして機能
3. よくある設定ミス
- NVIDIA Container Toolkitのインストールが不完全
- Dockerデーモンの設定ファイル(daemon.json)の記述ミス
- ユーザーがdockerグループに属していない
- ホストのNVIDIAドライバとコンテナ内のCUDAバージョンの不一致
解決方法:ステップバイステップ設定ガイド
ステップ1: 前提条件の確認
まず、ホストマシンにNVIDIA GPUドライバが正しくインストールされていることを確認します。
# GPUとドライバの状態を確認
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. |
| | | MIG M. |
|===============================+======================+======================|
| 0 NVIDIA GeForce ... Off | 00000000:01:00.0 Off | N/A |
| 30% 34C P8 10W / 250W | 0MiB / 12288MiB | 0% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+
ステップ2: NVIDIA Container Toolkitのインストール
Ubuntu/Debian系ディストリビューションの場合のインストール手順です。
# リポジトリの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 Container Runtimeを使用するように設定します。
# nvidia-container-runtimeをDockerのランタイムとして設定
sudo nvidia-ctk runtime configure --runtime=docker
# 設定の適用
sudo systemctl restart docker
# 設定が正しく反映されたか確認
sudo cat /etc/docker/daemon.json
正しく設定されていれば、daemon.jsonに以下のような記述が追加されています。
{
"runtimes": {
"nvidia": {
"path": "/usr/bin/nvidia-container-runtime",
"runtimeArgs": []
}
}
}
ステップ4: 動作確認
簡単なテストコンテナを実行して、GPUが認識されることを確認します。
# テストコンテナの実行
sudo docker run --rm --gpus all nvidia/cuda:12.0.1-base-ubuntu22.04 nvidia-smi
# コンテナ内でPythonからGPUを確認
sudo docker run --rm --gpus all -it nvidia/cuda:12.0.1-base-ubuntu22.04 python3 -c "import torch; print(torch.cuda.is_available())"
コード例・コマンド例
1. 基本的なGPU付きコンテナの実行
# すべてのGPUを利用
docker run --gpus all -it pytorch/pytorch:latest
# 特定のGPUのみを利用(GPU ID 0のみ)
docker run --gpus '"device=0"' -it tensorflow/tensorflow:latest-gpu
# 複数の特定GPUを利用(GPU ID 0と1)
docker run --gpus '"device=0,1"' -it nvcr.io/nvidia/pytorch:23.05-py3
2. Docker ComposeでのGPU設定例
version: '3.8'
services:
ai-training:
image: pytorch/pytorch:latest
runtime: nvidia
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
volumes:
- ./data:/data
- ./models:/models
command: python train.py
3. トラブルシューティング用コマンド
# Dockerデーモンのログを確認
sudo journalctl -u docker.service -f
# NVIDIA Container Toolkitのバージョン確認
nvidia-ctk --version
# 利用可能なランタイムの確認
docker info | grep -i runtime
# コンテナ内のGPU情報を詳細に確認
docker run --rm --gpus all nvidia/cuda:12.0.1-base-ubuntu22.04 nvidia-smi --query-gpu=name,memory.total,driver_version --format=csv
よくあるエラーと解決策
エラー1: “could not select device driver”
原因: NVIDIA Container Toolkitが正しくインストールされていないか、Dockerデーモンの再起動が行われていない。
解決策:
# インストールの再確認とDockerの再起動
sudo apt-get install --reinstall nvidia-container-toolkit
sudo systemctl restart docker
エラー2: “Unknown runtime specified nvidia”
原因: daemon.jsonにnvidiaランタイムが正しく設定されていない。
解決策:
# daemon.jsonの手動修正
sudo tee /etc/docker/daemon.json <<EOF
{
"runtimes": {
"nvidia": {
"path": "/usr/bin/nvidia-container-runtime",
"runtimeArgs": []
}
},
"default-runtime": "nvidia"
}
EOF
sudo systemctl restart docker
エラー3: コンテナ内でCUDAバージョンエラー
原因: ホストのCUDAドライババージョンとコンテナイメージのCUDAバージョンが互換性がない。
解決策: コンテナイメージのCUDAバージョンをホストのドライババージョンに対応するものに変更。
# ホストのCUDAドライババージョンを確認
nvidia-smi | grep "CUDA Version"
# 互換性のあるCUDAバージョンのコンテナイメージを使用
# 例: CUDA 11.8に対応するイメージ
docker run --gpus all nvidia/cuda:11.8.0-base-ubuntu22.04
まとめ・補足情報
NVIDIA Container Toolkitを正しく設定することで、Dockerコンテナ内でGPUをシームレスに利用できるようになります。この設定は、AI開発環境の再現性確保、異なるCUDAバージョンの並行利用、チーム間での環境統一に非常に有効です。
パフォーマンス最適化のヒント
- 永続モードの有効化:
sudo nvidia-smi -pm 1でGPUの永続モードを有効にすると、起動時間が短縮されます。 - メモリ制限:
--gpus all --memory="8g"のようにメモリ制限を設定することで、ホストシステムの安定性を保ちます。 - ボリュームマウントの最適化: 学習データセットなど大きなファイルはボリュームマウントで共有し、コンテナイメージのサイズを小さく保ちます。
セキュリティに関する注意点
GPUパススルーを有効にすると、コンテナ内からホストのGPUリソースに直接アクセス可能になります。本番環境では以下の点に注意してください。
- 信頼できるコンテナイメージのみを使用する
- 必要最小限のGPU権限のみを付与する(
--gpus '"device=0"'のように特定GPUのみ) - 定期的にセキュリティアップデートを適用する
本ガイドで紹介した手順に従うことで、ほとんどの環境でDockerコンテナ内でのGPU利用が可能になります。問題が解決しない場合は、NVIDIAの公式ドキュメントやDockerのコミュニティフォーラムも参照してください。