【Docker/環境】NVIDIA Container ToolkitでGPUパススルー設定:インストール手順と「Could not load UVM kernel module」エラー解決法

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

AI開発、特に深層学習モデルのトレーニングや推論を行う際、Dockerコンテナ内からホストマシンのNVIDIA GPUを利用したい場面は多々あります。しかし、標準のDocker環境では、コンテナ内からGPUリソースを直接利用することはできません。この問題を解決するために必要なのが「NVIDIA Container Toolkit」(旧称:nvidia-docker2)です。本記事では、このツールキットのインストールから、よく遭遇するエラーのトラブルシューティングまでを詳細に解説します。

典型的な問題として、以下のようなエラーメッセージが表示されます。

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

または、コンテナ内で`nvidia-smi`コマンドを実行しても、GPUが認識されない状態です。

# コンテナ内で実行
nvidia-smi
# 出力: `command not found` または `No devices were found`

原因の解説:DockerとGPUドライバの隔離

この問題の根本原因は、Dockerのセキュリティと隔離の仕組みにあります。デフォルトでは、Dockerコンテナはホストのカーネルモジュールやデバイスドライバに直接アクセスできません。NVIDIA GPUを利用するには、GPUドライバ、CUDAライブラリ、そしてGPUデバイスファイル(`/dev/nvidia*`)へのアクセスが必要です。NVIDIA Container Toolkitは、コンテナの起動時にこれらのリソースを適切にマウントし、ランタイム環境を構成するブリッジの役割を果たします。

インストールや設定が不十分な場合、以下のようなエラーが発生します。

  • ドライバ不一致: ホストのNVIDIAドライババージョンと、コンテナ内で期待されるCUDAバージョンに互換性がない。
  • ランタイム設定の不備: DockerデーモンがNVIDIAコンテナランタイムを使用するように設定されていない。
  • カーネルモジュールの読み込み失敗: 特に「Could not load UVM kernel module」エラーは、NVIDIAのユニファイドメモリモジュールに問題があることを示します。

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

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

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

まず、ホストマシンに適切なNVIDIAドライバがインストールされ、GPUが認識されていることを確認します。

# NVIDIAドライバの確認
nvidia-smi
# 出力例:
# +-----------------------------------------------------------------------------+
# | NVIDIA-SMI 525.125.06   Driver Version: 525.125.06   CUDA Version: 12.0    |
# |-------------------------------+----------------------+----------------------+
# ドライバがインストールされていない場合は、`ubuntu-drivers devices`やNVIDIA公式サイトからインストールしてください。
# Docker Engineがインストールされていることも確認します。
docker --version

ステップ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ランタイムの設定をDockerに登録
sudo nvidia-ctk runtime configure --runtime=docker
# Dockerデーモンの再起動
sudo systemctl restart docker

このコマンドは、Dockerの設定ファイル(通常`/etc/docker/daemon.json`)を自動的に編集し、`nvidia`という名前のランタイムを追加します。

ステップ4: 動作確認

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

# `--gpus all` フラグがキーポイント
sudo docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi

成功すると、ホストで`nvidia-smi`を実行した時と同様のGPU情報がコンテナ内から出力されます。

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

エラー1: 「Could not load UVM kernel module」

このエラーは、NVIDIAドライバのカーネルモジュール、特にUVM(Unified Video Memory)が正しく読み込まれていない場合に発生します。

docker: Error response from daemon: failed to start shim: failed to create task: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error running hook #0: error running hook: exit status 1, stdout: , stderr: nvidia-container-cli: initialization error: load library failed: libnvidia-uvm.so.525: cannot open shared object file: no such file or directory: unknown.

解決策: ホストでNVIDIA UVMモジュールを明示的にロードし、デバイスファイルのパーミッションを確認します。

# 1. UVMモジュールをロード
sudo modprobe nvidia-uvm
# 2. デバイスファイルが存在するか確認
ls -la /dev/nvidia-uvm
# 存在しない場合は、モジュールロード後に自動生成されるので、再度確認。
# 3. 主要なNVIDIAデバイスファイルのパーミッションを確認(通常は root:root 666)
ls -la /dev/nvidia*

エラー2: 「Dockerデーモンがnvidiaランタイムを見つけられない」

Dockerデーモンの再起動後に発生する場合、設定ファイルの記述ミスが考えられます。

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

解決策: `/etc/docker/daemon.json` ファイルを直接確認・編集します。

sudo cat /etc/docker/daemon.json
# 以下のような`runtimes`セクションが含まれていることを確認
# {
#     "runtimes": {
#         "nvidia": {
#             "path": "/usr/bin/nvidia-container-runtime",
#             "runtimeArgs": []
#         }
#     }
# }
# ファイルが壊れている(JSON形式でない)場合は修正し、Dockerを再起動。
sudo systemctl restart docker

エラー3: ドライバーバージョンの不一致

ホストのドライバーバージョンとコンテナイメージが要求するCUDAバージョンに互換性がない場合、動作しないことがあります。NVIDIAのCUDA互換性表を参照し、適切なベースイメージタグ(例: `nvidia/cuda:11.8.0-base`)を選択してください。

コード例・コマンド例:実践的な使用方法

実際の開発では、`Dockerfile`内でベースイメージとしてNVIDIA CUDAイメージを指定し、`–gpus`フラグでGPUを指定してビルド・実行します。

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

RUN apt-get update && apt-get install -y python3 python3-pip
RUN pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

WORKDIR /app
COPY . .
CMD ["python3", "your_ai_script.py"]
# ビルドと実行
docker build -t my-ai-app .
# すべてのGPUを使用
docker run --gpus all my-ai-app
# 特定のGPU(ID 0)のみを使用
docker run --gpus '"device=0"' my-ai-app
# リソース制限をかけて使用(メモリ制限など)
docker run --gpus all --memory="8g" my-ai-app

まとめ・補足情報

NVIDIA Container Toolkitは、Dockerコンテナ内でGPUリソースをシームレスに利用するための必須ツールです。インストール手順は、1) リポジトリ設定、2) パッケージインストール、3) Dockerランタイム設定、4) 動作確認の4ステップで完了します。最も多いエラーはUVMモジュール関連とランタイム設定の不備です。`nvidia-smi`のホストとの出力を比較することで、問題の切り分けが容易になります。

補足:

  • Docker Composeを使用する場合は、`docker-compose.yml`のサービス定義に`deploy.reservations.devices`セクションを追加する必要があります(Compose v2.4以降推奨)。
  • Kubernetes上で利用する場合は、さらにNVIDIA Device Pluginのデプロイが必要です。
  • 常にホストのNVIDIAドライバを最新の安定版に保つことが、互換性問題を避ける最善策です。

本ガイドに沿って設定を行うことで、開発環境と本番環境の間での一貫性を保ちながら、GPUのパワフルな計算資源をDockerコンテナ内で最大限に活用できるようになるでしょう。

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