問題の発生
モデルのトレーニングのために Docker コンテナを起動した際、スクリプトが即座にクラッシュすることがあります。期待されるトレーニングログの代わりに、以下のような特定のエラーメッセージが表示されます。
ImportError: libcuda.so.1: cannot open shared object file: No such file or directory
これは、PyTorch や TensorFlow などの Python ライブラリが GPU と通信しようとして失敗したときに発生します。ホストマシンには最新の NVIDIA ドライバがインストールされているかもしれませんが、Docker コンテナは設計上、隔離されています。明示的に橋渡しをしない限り、コンテナはホストの GPU ハードウェアやドライバファイルを参照できません。
原因
libcuda.so.1 ファイルは、NVIDIA ドライバのコアインターフェースです。Docker イメージに組み込むことができる CUDA ライブラリ(libcudnn など)とは異なり、ドライバライブラリはホスト OS 上に存在し続ける必要があります。Docker に対してこれらのホストドライバをコンテナ内にマッピングするように指示しないと、AI アプリケーションはハードウェアを「認識」できません。
ステップバイステップの修正方法
ステップ 1: ホストドライバの確認
まず、ホストマシンが GPU を認識していることを確認します。メインのターミナルで以下のコマンドを実行してください。
nvidia-smi
GPU のモデル(例:RTX 4090 や A100)とドライバのバージョン(例:535.129.03)が表示されたテーブルが表示されるはずです。このコマンドが失敗する場合は、Docker の設定に進む前にホストに NVIDIA ドライバをインストールする必要があります。
ステップ 2: NVIDIA Container Toolkit のインストール
標準の Docker インストールでは GPU をサポートしていません。コンテナがホストの libcuda.so.1 ファイルにアクセスできるようにするには、NVIDIA Container Toolkit が必要です。Ubuntu または Debian の場合は、以下の手順に従ってください。
# パッケージリポジトリを追加
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/stable/deb/nvidia-container-toolkit.list | \
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
sudo tee /etc/stderr/apt/sources.list.d/nvidia-container-toolkit.list
# ツールキットをインストール
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
# 新しいランタイムを適用するために Docker デーモンを再起動
sudo systemctl restart docker
ステップ 3: GPU アクセスを有効にして Docker を起動
ツールキットをインストールするだけでは不十分です。コンテナを起動する際にそれを有効にする必要があります。ドライバをパススルーするには、--gpus all フラグを使用します。以下のテストコマンドを試してください。
docker run --rm --gpus all nvidia/cuda:12.0-base-ubuntu22.04 nvidia-smi
docker-compose を使用する場合は、yaml ファイルに deploy セクションが含まれていることを確認してください。これは Docker Compose バージョン 1.28.0 以降で必要です。
services:
ai-app:
image: pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
ステップ 4: ケイパビリティ変数の設定
一部の特殊なケースでは、コンテナが依然としてドライバライブラリを「認識」しないことがあります。その場合は、Dockerfile または実行コマンドに以下の環境変数を追加することで、強制的にマッピングできます。
NVIDIA_VISIBLE_DEVICES=allNVIDIA_DRIVER_CAPABILITIES=compute,utility
修正の確認
ライブラリが正しくマッピングされているか確実に確認するために、コンテナ環境内で簡単な Python チェックを実行します。
docker run --rm --gpus all python:3.10-slim python3 -c "import ctypes; print(ctypes.util.find_library('cuda'))"
出力が libcuda.so.1 であれば、設定は正解です。None が返される場合は、ドライバがまだ正しくパススルーされていません。
PyTorch ユーザーにとって、これが最終的なテストになります。
python3 -c "import torch; print(torch.cuda.is_available())"
結果が True であれば、ImportError は正式に解消されました。
ベストプラクティス
異なるサーバー間でドライバのバージョンを管理するのは煩雑になりがちです。本番環境用に特定のドライババイナリやセットアップスクリプトをダウンロードする際、私は ToolCraft の Hash Generator を使用して SHA-256 の整合性を検証しています。これにより、デプロイ中のダウンロード破損やファイルの不一致によるトラブルを防ぐことができます。
最後に一つアドバイスです。バージョンの互換性に注意してください。ホストのドライババージョンは、コンテナが要求する CUDA バージョン以上である必要があります。例えば、ホストのドライバが 510(CUDA 11.6)で、コンテナが CUDA 12.0 を要求している場合、再び libcuda.so.1 エラーが発生する可能性が高いです。

