【Docker/環境】NVIDIA Container ToolkitインストールとGPUパススルー設定の完全ガイドとトラブルシューティング

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

Dockerを使用してPyTorchやTensorFlowなどのAI/機械学習フレームワークを実行する際、ホストマシンにはNVIDIA GPUが搭載されているにもかかわらず、コンテナ内からGPUが認識されず、以下のようなエラーが発生することがあります。

# PyTorchでの典型的なエラー例
RuntimeError: No CUDA GPUs are available

# TensorFlowでの典型的なエラー例
tensorflow.python.framework.errors_impl.NotFoundError: Could not find device with id 0

# nvidia-smiコマンド実行時のエラー例
docker exec -it my_container nvidia-smi
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.

この問題は、DockerコンテナがデフォルトではホストのGPUリソースにアクセスできないために発生します。NVIDIA Container Toolkitを正しくインストール・設定することで、コンテナにGPUを「パススルー」し、ネイティブに近いパフォーマンスでGPUアクセスを可能にする必要があります。

原因の解説

従来のDocker環境では、コンテナはホストのハードウェアリソースを直接利用することができません。GPUを利用するためには、以下のコンポーネントと設定が適切に連携する必要があります。

根本的な原因

1. ドライバとランタイムの分離: ホストにインストールされたNVIDIAドライバは、コンテナ内のCUDAライブラリと直接通信できません。

2. デバイスファイルのマウント不足: GPUデバイスファイル(/dev/nvidia*)や関連するライブラリがコンテナ内に存在しません。

3. 互換性の問題: ホストのドライババージョン、CUDAツールキットバージョン、コンテナ内のCUDAバージョンに互換性がない場合があります。

NVIDIA Container Toolkitは、nvidia-container-runtimeという特別なランタイムを提供し、コンテナ起動時に必要なGPUリソースとライブラリを自動的にマウント・設定することでこの問題を解決します。

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

ここでは、Ubuntu 20.04/22.04を例に、NVIDIA Container Toolkitのインストールから動作確認までの全手順を説明します。

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

まず、ホストシステムにNVIDIAドライバとDockerが正しくインストールされていることを確認します。

# NVIDIAドライバの確認
nvidia-smi
# 出力例:
# +-----------------------------------------------------------------------------+
# | NVIDIA-SMI 525.125.06   Driver Version: 525.125.06   CUDA Version: 12.0    |
# |-------------------------------+----------------------+----------------------+

# Dockerの確認
docker --version
# Docker Engineがインストールされていることを確認
sudo systemctl status docker

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

パッケージリポジトリを設定し、必要なパッケージをインストールします。

# ディストリビューションとアーキテクチャを設定
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
echo "Distribution: $distribution"

# NVIDIAのGPGキーとリポジトリを追加
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の設定(nvidiaをデフォルトランタイムとして設定)

インストール後、Dockerデーモンの設定を変更してnvidiaランタイムを使用するようにします。

# nvidia-container-runtimeをDockerの設定に登録
sudo nvidia-ctk runtime configure --runtime=docker

# Dockerデーモンの再起動
sudo systemctl restart docker

# 設定の確認
sudo docker info | grep -i runtime
# 出力に「nvidia」が含まれていることを確認

ステップ4: 動作確認

公式のCUDAコンテナを実行して、GPUが正しく認識されるかテストします。

# 基本的なテスト(nvidia-smiの実行)
sudo docker run --rm --runtime=nvidia --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi

# すべてのGPUをマウントする代わりに、特定のGPUのみを指定する例
sudo docker run --rm --runtime=nvidia --gpus '"device=0"' nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi

上記コマンドでホストと同じGPU情報が表示されれば成功です。また、--runtime=nvidiaの代わりに、環境変数NVIDIA_VISIBLE_DEVICESを使用する方法もあります。

sudo docker run --rm --gpus all -e NVIDIA_VISIBLE_DEVICES=all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi

コード例・コマンド例

実践例1:PyTorchコンテナの実行

実際のAI開発でよく使われるPyTorch公式イメージを使用する例です。

# PyTorchコンテナの実行とGPU確認
docker run -it --rm --gpus all pytorch/pytorch:2.0.1-cuda11.7-cudnn8-runtime python3 -c "import torch; print(f'PyTorch version: {torch.__version__}'); print(f'CUDA available: {torch.cuda.is_available()}'); print(f'GPU count: {torch.cuda.device_count()}'); print(f'GPU name: {torch.cuda.get_device_name(0)}')"

# Jupyter NotebookをGPU付きで起動する例(ポート8888でアクセス)
docker run -it --rm --gpus all -p 8888:8888 -v $(pwd):/workspace pytorch/pytorch:2.0.1-cuda11.7-cudnn8-runtime jupyter notebook --ip=0.0.0.0 --allow-root --NotebookApp.token=''

実践例2:Docker Composeでの設定

複数のサービスを管理する場合は、docker-compose.ymlで以下のように設定します。

version: '3.8'

services:
  ai-training:
    image: pytorch/pytorch:2.0.1-cuda11.7-cudnn8-runtime
    runtime: nvidia
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]
    environment:
      - NVIDIA_VISIBLE_DEVICES=all
    volumes:
      - ./src:/workspace/src
      - ./data:/workspace/data
    command: python /workspace/src/train.py

まとめ・補足情報

NVIDIA Container Toolkitは、Dockerコンテナ内でGPUをシームレスに利用するための必須ツールです。正しくインストール・設定することで、ホスト環境とほぼ同等のGPUパフォーマンスをコンテナ内で発揮できます。

よくあるトラブルと対処法

エラー1: 「Failed to initialize NVML: Driver/library version mismatch」
ホストのNVIDIAドライバとコンテナ内のライブラリに互換性がない場合に発生します。ホストのドライバを再起動するか、コンテナのCUDAバージョンをホストドライバがサポートするバージョンに合わせます。

# ホストのドライバを再ロード
sudo rmmod nvidia_uvm
sudo rmmod nvidia
sudo modprobe nvidia
sudo modprobe nvidia_uvm

エラー2: 「nvidia-container-cli: initialization error: nvml error: driver not loaded」
NVIDIAドライバが正しくロードされていません。ホストでnvidia-smiが実行できることをまず確認し、できない場合はドライバを再インストールします。

エラー3: Dockerコマンドで「Unknown runtime specified nvidia」
Dockerのランタイム設定が正しく行われていません。ステップ3の設定が完了しているか、/etc/docker/daemon.jsonファイルにnvidiaランタイムが登録されているかを確認します。

パフォーマンス最適化のヒント

1. 永続的なGPUメモリ割り当て: 頻繁にモデルをロードする場合、--gpus allに加え、環境変数NVIDIA_DRIVER_CAPABILITIES=compute,utilityを設定すると効率的です。

2. バージョン管理: ホストのドライババージョン、コンテナのCUDAバージョン、フレームワークのバージョンの互換性マトリックスを常に確認しましょう。NVIDIAの公式ドキュメントが参考になります。

3. マルチGPU環境: 複数GPUを個別に割り当てたい場合は、--gpus '"device=0,1"'のように指定します。特定のプロセスに特定のGPUを割り当てることで、リソース競合を防げます。

本ガイドで紹介した手順に従うことで、Dockerコンテナ内でのGPU活用におけるほとんどの問題を解決し、再現性の高いAI開発環境を構築できるでしょう。環境構築後は、docker buildを用いて自身のGPU環境をパッケージ化し、チーム間や本番環境へのデプロイを効率化することが次のステップとなります。

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