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

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

AI開発や機械学習の環境構築において、Dockerコンテナ内でGPU(特にNVIDIA GPU)を利用しようとすると、以下のようなエラーに遭遇することがあります。

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

あるいは、nvidia-smiコマンドをコンテナ内で実行しても、以下のようにGPUが認識されない状況です。

# コンテナ内で実行
$ nvidia-smi
Failed to initialize NVML: Unknown Error

また、NVIDIA Container Toolkitのインストールや再起動時に、以下のカーネルモジュール関連の致命的なエラーが表示されることもあります。

ERROR: Could not load UVM kernel module. # または
ERROR: Unable to load the 'nvidia' kernel module.

これらの問題は、ホストマシンのGPUリソースをDockerコンテナに透過的に渡す「GPUパススルー」設定が正しく完了していないことを示しています。本記事では、この一連の設定手順と発生するエラーの解決方法を詳しく解説します。

原因の解説:NVIDIA Container Toolkitとランタイムの関係

DockerコンテナがホストのNVIDIA GPUを利用するためには、以下の3つの主要コンポーネントが正しく連携する必要があります。

  1. NVIDIA GPUドライバ: ホストOSがGPUを認識・制御するための基盤ソフトウェア。
  2. NVIDIA Container Toolkit (旧称: nvidia-docker2): DockerエンジンとNVIDIAドライバを仲介し、コンテナランタイムを提供するツールキット。
  3. Dockerエンジン: コンテナを実行する基盤。

「Could not load UVM kernel module」エラーは、主にNVIDIA GPUドライバのインストールに失敗している、またはカーネルバージョンとドライバの互換性がない場合に発生します。UVM(Unified Virtual Memory)はGPUメモリ管理に必要なカーネルモジュールです。このモジュールがロードされないと、Container Toolkitは正常に機能しません。

また、Dockerデーモンの設定ファイル(/etc/docker/daemon.json)にNVIDIAをデフォルトのランタイムとして指定し忘れていることも、一般的な原因の一つです。

解決方法:ステップバイステップでの完全セットアップ

ここからは、Ubuntu 20.04/22.04 LTSを例に、ゼロから確実に環境を構築する手順を説明します。既存の環境でエラーが発生している場合も、この手順に従って再セットアップすることで解決できる可能性が高いです。

ステップ1: 前提条件の確認とNVIDIAドライバのインストール

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

# 現在使用中のGPUとドライバ状態を確認
$ nvidia-smi
# エラーが出力される、またはコマンドが見つからない場合はドライバ未インストール

ドライバが未インストールの場合は、以下の手順でインストールします。推奨は公式の`ubuntu-drivers`ツールを使う方法です。

# 利用可能なドライバを確認
$ ubuntu-drivers devices
# 推奨ドライバを自動インストール(再起動が必要)
$ sudo ubuntu-drivers autoinstall
$ sudo reboot

再起動後、nvidia-smiが正常に実行され、GPU情報が表示されることを確認してください。

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

ドライバが正常なら、次に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 Container Toolkitをランタイムとして使用するように設定します。

# nvidia-container-runtimeをDockerの設定に登録
$ sudo nvidia-ctk runtime configure --runtime=docker
# 上記コマンドは /etc/docker/daemon.json を自動編集します

手動で設定ファイルを確認・編集する場合は、/etc/docker/daemon.jsonが以下のようになっているか確認します。

{
    "runtimes": {
        "nvidia": {
            "path": "/usr/bin/nvidia-container-runtime",
            "runtimeArgs": []
        }
    },
    "default-runtime": "nvidia" // この行が重要!
}

重要: "default-runtime": "nvidia"の行がないと、明示的に--runtime=nvidiaオプションを付けない限りGPUが使えません。この行を追加することを強く推奨します。

ステップ4: Dockerデーモンの再起動と動作確認

設定を反映させるためにDockerデーモンを再起動し、テストコンテナを実行します。

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

# テスト実行(公式CUDAコンテナを使用)
$ docker run --rm --gpus all nvidia/cuda:12.1.1-base-ubuntu22.04 nvidia-smi

このコマンドで、ホストと同じGPU情報がコンテナ内から表示されれば成功です。

コード例・コマンド例:トラブルシューティング集

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

このエラーは、ドライバインストールが不完全な場合や、セキュアブートが有効な場合に発生します。

# 1. 現在ロードされているカーネルモジュールを確認
$ lsmod | grep nvidia
# nvidia_uvm, nvidia_drm, nvidia_modeset, nvidia などのモジュールが表示されない

# 2. ドライバを完全に削除して再インストール(根本解決)
$ sudo apt-get purge nvidia-* # または sudo apt-get purge '*nvidia*'
$ sudo apt-get autoremove
$ sudo ubuntu-drivers autoinstall
$ sudo reboot

# 3. セキュアブートが原因の場合(特にクラウドVMや特定のハードウェア)
$ sudo mokutil --sb-state # セキュアブート状態確認
# セキュアブートが有効な場合は、BIOS/UEFI設定から無効化するか、
# NVIDIAドライバ用にキーを登録する必要があります。

エラー2: コンテナ内で「Failed to initialize NVML」が発生

ホストではnvidia-smiが動くのに、コンテナ内では動かない場合。

# 1. Dockerランタイム設定の確認
$ cat /etc/docker/daemon.json
# "default-runtime": "nvidia" があるか確認

# 2. 明示的にランタイムを指定して実行
$ docker run --rm --runtime=nvidia nvidia/cuda:12.1.1-base-ubuntu22.04 nvidia-smi

# 3. 特定のGPUのみを割り当ててみる
$ docker run --rm --gpus device=0 nvidia/cuda:12.1.1-base-ubuntu22.04 nvidia-smi

Docker ComposeでGPUを使用する設定例

docker-compose.ymlでは以下のように記述します。

version: '3.8'
services:
  ai-training:
    image: pytorch/pytorch:2.0.1-cuda11.7-cudnn8-runtime
    deploy: # Docker Compose v2.4以降(推奨)
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]
    # または、環境変数で設定(レガシーな方法)
    # runtime: nvidia
    # environment:
    #   - NVIDIA_VISIBLE_DEVICES=all
    volumes:
      - ./src:/workspace
    command: python train.py

まとめ・補足情報

NVIDIA Container Toolkitを用いたDocker環境でのGPUパススルー設定は、AI開発における基盤技術の一つです。設定の要点をまとめると以下のようになります。

  • 根本はホストのドライバ: すべてのトラブルの8割は、ホストのNVIDIAドライバのインストール不備や互換性問題に起因します。nvidia-smiがホストで正常に動作することを最初に確認してください。
  • 設定ファイルの確認: /etc/docker/daemon.json"default-runtime": "nvidia"が設定されているかは、特に初心者が見落としがちな重要ポイントです。
  • セキュアブートの影響: 近年のシステムではセキュアブートが有効になっていることが多く、これがカーネルモジュールのロードを阻害します。開発用マシンでは無効化することを検討してください。
  • バージョンの互換性: 使用するCUDAコンテナイメージのバージョンと、ホストにインストールされたNVIDIAドライバのバージョンには互換性があります。NVIDIAの公式ドキュメントで確認する習慣をつけましょう。

一度正しく設定が完了すれば、異なるCUDAバージョンやフレームワーク(PyTorch, TensorFlowなど)がインストールされた様々なコンテナイメージを、GPUリソースを最大限活用して実行できるようになります。これにより、開発環境の再現性と移植性が飛躍的に向上し、AI開発の生産性を高めることができます。

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