【Docker/環境】NVIDIA Container ToolkitでDockerコンテナにGPUをパススルーする方法とトラブルシューティング

問題の概要:Dockerコンテナ内でGPUが認識されない・使用できない

AI開発、特に深層学習のモデルトレーニングや推論を行う際、Dockerコンテナ内でGPUリソースを活用することは一般的です。しかし、標準のDocker環境では、ホストマシンに搭載されたNVIDIA GPUをコンテナ内から直接利用することはできません。以下のようなエラーメッセージに遭遇したことはありませんか?

docker: Error response from daemon: could not select device driver "" with capabilities: [[gpu]].

あるいは、PyTorchやTensorFlowをコンテナ内で実行した際に、GPUが認識されずCPUで動作してしまうケースも頻発します。

# Pythonインタラクティブシェル内での例
import torch
print(torch.cuda.is_available())  # False と出力されてしまう

この問題は、DockerコンテナとホストのGPUリソースを橋渡しする「NVIDIA Container Toolkit」(旧称:nvidia-docker2)が正しくインストール・設定されていないために発生します。本記事では、このツールキットのインストールから、実際にGPUが使えるコンテナを実行するまでの全手順と、遭遇しがちなエラーへの対処法を詳しく解説します。

原因の解説:なぜ標準DockerではGPUが使えないのか?

Dockerの標準的な仕組みでは、コンテナはホストのカーネルを共有しますが、デバイスドライバやハードウェアリソースへの直接アクセスは強く制限されています。GPU(特にNVIDIA GPU)は独自のドライバスタック(カーネルモジュール、ユーザー空間ライブラリ、デバイスファイル)を必要とする複雑なデバイスです。

NVIDIA Container Toolkitは、この隔離を解決するための一連のソフトウェアコンポーネントです。主な役割は以下の通りです:

  1. ランタイムの提供: `nvidia-container-runtime` は、コンテナ起動時にホストのGPUドライバライブラリやデバイスファイルをコンテナ内にマウントするようDockerエンジンに指示します。
  2. CLIの拡張: `docker` コマンドに `–gpus` オプションを追加し、どのGPUをコンテナに割り当てるかを指定できるようにします。
  3. 互換性の維持: ホストのNVIDIAドライババージョンと、コンテナ内で必要なCUDAライブラリバージョンの互換性を管理します。

これらが正しく設定されていないと、コンテナは物理GPUの存在を検知できず、結果としてCPUモードで動作することになります。

解決方法:ステップバイステップでのインストールと設定

ここでは、Ubuntu 20.04/22.04 LTSをホストOSとする環境を想定して説明します。他のディストリビューションでも手順は類似しています。

ステップ1: 前提条件の確認

まず、ホストマシンにNVIDIA GPUドライバが正しくインストールされ、`nvidia-smi`コマンドが実行できることを確認します。

nvidia-smi

このコマンドでGPUの情報が表示されれば、ドライバは正常にインストールされています。表示されない場合は、先にドライバのインストールを行ってください。また、Docker Engineがインストールされていることも前提です。

ステップ2: NVIDIA Container Toolkitのインストール

公式のリポジトリを追加し、パッケージをインストールします。

# ディストリビューションとアーキテクチャを設定
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-container-runtimeをDockerの設定に登録
sudo nvidia-ctk runtime configure --runtime=docker

# Dockerデーモンを再起動して設定を反映
sudo systemctl restart docker

注意点: 古い資料では `nvidia-container-runtime` を直接 `/etc/docker/daemon.json` に記述する手順が紹介されていますが、上記の `nvidia-ctk` コマンドを使うことが現在の推奨方法です。

ステップ4: 動作確認

最も簡単な確認方法は、NVIDIAが提供するCUDAコンテナを実行することです。

# すべてのGPUをコンテナにアタッチ
sudo docker run --rm --gpus all nvidia/cuda:12.1.1-base-ubuntu22.04 nvidia-smi

# 特定のGPU(例えばGPU 0のみ)をアタッチ
sudo docker run --rm --gpus '"device=0"' nvidia/cuda:12.1.1-base-ubuntu22.04 nvidia-smi

コンテナ内で実行された `nvidia-smi` の出力が、ホストで実行したものと同様にGPU情報を表示すれば成功です。

コード例・コマンド例

DockerfileでのCUDA環境構築例

実際の開発では、ベースイメージとしてNVIDIAのCUDAイメージを使用するのが便利です。

# Dockerfileの例
FROM nvidia/cuda:12.1.1-cudnn8-runtime-ubuntu22.04

# システムパッケージの更新とPythonインストール
RUN apt-get update && apt-get install -y 
    python3-pip 
    && rm -rf /var/lib/apt/lists/*

# 必要なPythonパッケージのインストール
COPY requirements.txt .
RUN pip3 install --no-cache-dir -r requirements.txt

# アプリケーションコードのコピー
COPY . /app
WORKDIR /app

# エントリーポイントの設定
CMD ["python3", "train.py"]

docker-compose.ymlでのGPU指定例

docker-composeを使用する場合は、以下のように`deploy`リソースセクションでGPUを指定します。

# docker-compose.ymlの例
version: '3.8'
services:
  ai-training:
    build: .
    runtime: nvidia # ランタイムの指定
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]
    volumes:
      - ./data:/app/data

よくあるエラーとトラブルシューティング

エラー1: “Unknown runtime specified nvidia”

docker: Error response from daemon: Unknown runtime specified nvidia.

原因と解決策: Dockerの設定ファイル(`/etc/docker/daemon.json`)にNVIDIAランタイムが正しく登録されていません。ステップ3の `sudo nvidia-ctk runtime configure –runtime=docker` を実行した後、Dockerデーモンを再起動(`sudo systemctl restart docker`)したか確認してください。また、設定ファイルの内容を直接確認することも有効です。

cat /etc/docker/daemon.json
# "runtimes" セクションに "nvidia" が定義されているべき

エラー2: “could not select device driver “” with capabilities: [[gpu]]”

原因と解決策: コンテナ実行時に `–gpus` オプションを忘れている、または古い `nvidia-docker` コマンドを使用している可能性があります。必ず `docker run –gpus all …` という形式で実行してください。また、NVIDIA Container Toolkit自体のインストールが不完全な場合もこのエラーが出ます。インストール手順を最初からやり直してみてください。

エラー3: コンテナ内で`nvidia-smi`は動くが、PyTorch/TensorFlowがGPUを認識しない

原因と解決策: コンテナ内のCUDAツールキットのバージョンと、PyTorch/TensorFlowがビルドされたCUDAバージョンに互換性がない可能性が高いです。使用するベースイメージのCUDAバージョン(例: `nvidia/cuda:11.8.0-base`)と、`pip`でインストールするPyTorchのバージョンを一致させる必要があります。PyTorchの公式サイトで、`pip`インストール用の正しいコマンドを確認しましょう。

# CUDA 11.8用のPyTorchをインストールする例
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

まとめ・補足情報

NVIDIA Container Toolkitは、Dockerコンテナ内でGPUリソースをシームレスに利用するための必須コンポーネントです。インストールと設定は比較的シンプルですが、ホストのドライババージョン、ツールキットのバージョン、コンテナ内のCUDAライブラリバージョンの互換性チェックが安定運用の鍵となります。

さらに高度な設定として、`NVIDIA_VISIBLE_DEVICES`環境変数を使ってコンテナから見えるGPUを制限したり、MIG(Multi-Instance GPU)が有効なGPUの特定インスタンスのみを割り当てたりすることも可能です。

# 環境変数によるGPUの選択
docker run --rm --gpus all -e NVIDIA_VISIBLE_DEVICES=0,1 nvidia/cuda:12.1.1-base-ubuntu22.04 nvidia-smi

本記事の手順に従うことで、AI開発環境の再現性、移植性を高めつつ、貴重なGPUハードウェアリソースを最大限に活用できるようになるでしょう。問題が解決しない場合は、`docker info`の出力や`/var/log/syslog`のエラーログを確認し、NVIDIA Container ToolkitのGitHubリポジトリのIssueを検索することをお勧めします。

この記事は役に立ちましたか?