GPU推論基盤の実行環境を選ぶ観点
社内のGPU推論基盤では、CUDAとドライバの互換性、環境の再現性、運用時の管理範囲を踏まえて実行環境を選ぶ必要があります。
CUDA環境をDockerで構築する際の注意点と、ベアメタル・Docker・VMの構造的な違いを整理します。DigitalBaseが社内AI基盤の構築支援で蓄積した知見をもとに、規模・用途に応じた構成を選ぶための判断材料を示します。
DockerでCUDAを利用する際のホスト依存
GPUを使うDockerコンテナでは、コンテナ内のCUDAランタイムがホストOSのNVIDIAドライバに依存します。アプリケーションの依存関係をイメージにまとめても、GPUの実行環境はホスト側の構成に依存します。
通常の Docker: コンテナ内に全依存関係 → どの環境でも動く GPU Docker: コンテナ内の CUDA ← ホストの NVIDIA ドライバに依存 → 環境ごとに動作が変わる
ホスト側のドライバとコンテナ内のCUDAバージョンの互換性を管理する必要があります。
CUDA × Docker の運用上の注意点
1. nvidia-container-toolkit の設定
DockerコンテナからGPUにアクセスするには、nvidia-container-toolkit(旧 nvidia-docker2)が必要です。Dockerに加えて、このツールを導入・管理する必要があります。
// daemon.json に runtime を登録する { "runtimes": { "nvidia": { "path": "/usr/bin/nvidia-container-runtime", "runtimeArgs": [] } } }
この設定を忘れると could not select device driver エラーが発生します。GPU Dockerの導入初期に最も多く遭遇するトラブルの一つです。
2. CUDA バージョンとドライバの互換性
NVIDIAドライバには「Forward Compatibility」という仕組みがありますが、すべての組み合わせで動作するわけではありません。
| ホストドライバ | 対応 CUDA | よくあるトラブル |
|---|---|---|
| 535.x | CUDA 12.2 まで | CUDA 12.3 以降のイメージが動かない |
| 550.x | CUDA 12.4 まで | 新しい PyTorch イメージでエラー |
| 560.x+ | CUDA 12.6+ | 比較的安定 |
ドライバをアップデートすれば解決する場合が多いものの、カーネルモジュールの再ビルドを伴うことがあり、本番環境では更新計画が必要です。
3. 権限とセキュリティ
コンテナからGPUデバイス(/dev/nvidia*)にアクセスするには、適切な権限設定が必要です。--privileged フラグを使えば動作しますが、コンテナのセキュリティ分離が事実上無効化されてしまいます。
# 動作するが、セキュリティ的に避けるべき docker run --privileged nvidia/cuda:12.4-base nvidia-smi # 推奨される方法 docker run --gpus all nvidia/cuda:12.4-base nvidia-smi
4. パフォーマンスオーバーヘッド
Docker自体のオーバーヘッドは通常小さいものの、GPUパススルーの場合はデバイスマッピングのレイヤーが加わります。特に次のケースで影響が出やすくなります。
- メモリ管理: コンテナのmemory limitとGPUメモリの管理が別系統になる
- I/O: モデルファイルの読み込みで、ボリュームマウント経由のレイテンシが加わる
- マルチGPU: 複数GPUの割り当てとスケジューリングが複雑化する
ベアメタル・Docker・VM の構造比較
3つの実行環境がどのようにGPUへアクセスするのか、構造的な違いを整理します。
ベアメタル(物理サーバーでの直接実行)
┌─────────────────────┐ │ アプリケーション │ │ (CUDA / PyTorch) │ ├─────────────────────┤ │ CUDA Toolkit │ ├─────────────────────┤ │ NVIDIA ドライバ │ ├─────────────────────┤ │ OS (Linux) │ ├─────────────────────┤ │ GPU ハードウェア │ └─────────────────────┘
特徴:
- GPUへのアクセスが最短経路で、追加のオーバーヘッドが発生しない
- CUDAとドライバの組み合わせをホストで一度設定すれば安定して稼働する
- 環境の再現性は構成管理ツール(Ansible等)で担保する
Docker(コンテナ実行)
┌─────────────────────┐ │ アプリケーション │ │ (CUDA / PyTorch) │ ├─────────────────────┤ │ CUDA Toolkit │ ← コンテナ内 │ (コンテナイメージ) │ ├─────────────────────┤ │ nvidia-container- │ ← 橋渡しレイヤー │ toolkit │ ├─────────────────────┤ │ Docker Engine │ ├─────────────────────┤ │ NVIDIA ドライバ │ ← ホスト側に依存 ├─────────────────────┤ │ OS (Linux) │ ├─────────────────────┤ │ GPU ハードウェア │ └─────────────────────┘
特徴:
- nvidia-container-toolkitという追加レイヤーが必須となる
- コンテナ内のCUDAとホストのドライバの互換性を継続的に管理する必要がある
- 複数のCUDAバージョンを共存させたい場合には有効
VM(仮想マシン)
┌─────────────────────┐ │ アプリケーション │ │ (CUDA / PyTorch) │ ├─────────────────────┤ │ CUDA Toolkit │ ├─────────────────────┤ │ NVIDIA ドライバ │ ← ゲスト OS 用ドライバ ├─────────────────────┤ │ ゲスト OS │ ├─────────────────────┤ │ ハイパーバイザー │ ← 仮想化レイヤー │ (GPU パススルー │ │ / vGPU) │ ├─────────────────────┤ │ ホスト OS │ ├─────────────────────┤ │ GPU ハードウェア │ └─────────────────────┘
特徴:
- GPUパススルー(SR-IOV / vGPU)の設定が複雑になる
- ハイパーバイザーによるオーバーヘッドが最も大きい
- マルチテナントでGPUを分割共有する場合に採用される(クラウド事業者向け)
ユースケース別の最適解
単一 GPU × 1台のマシン → ベアメタルを推奨
単一GPUのマシンでLLM推論を動かす場合について、性能、セットアップ、障害調査、運用コストの観点で比較します。
| 観点 | ベアメタル | Docker |
|---|---|---|
| GPU 性能 | 100%(オーバーヘッドなし) | 95〜99%(デバイスマッピング経由) |
| セットアップ | CUDA インストールのみ | CUDA + Docker + nvidia-container-toolkit |
| トラブル時 | 原因の特定箇所が1つ | ホスト/コンテナの切り分けが必要 |
| 運用コスト | OS のアップデートのみ | Docker + toolkit のバージョン管理も必要 |
複数バージョンの CUDA を使い分けたい → Docker が有効
研究開発でPyTorchの異なるバージョン(CUDA 11.8 / 12.1 / 12.4 など)を切り替えたい場合は、Dockerに明確な価値があります。
# CUDA 11.8 環境 docker run --gpus all pytorch/pytorch:2.0.1-cuda11.8-cudnn8-runtime # CUDA 12.4 環境 docker run --gpus all pytorch/pytorch:2.5.0-cuda12.4-cudnn9-runtime
ただしこれは開発・検証環境に限った話であり、本番の推論サーバーでは単一のCUDAバージョンに固定するのが一般的です。
複数ノードでスケールアウト → Kubernetes(K8s)
GPUサーバーが複数台あり、ワークロードを動的に振り分けたい場合は、Kubernetes + NVIDIA GPU Operator が事実上の標準です。
# GPU リソースのリクエスト例 resources: limits: nvidia.com/gpu: 1
ただし、K8sの運用には相応のインフラ運用体制が前提となります。
| 規模 | 最適解 | 必要なスキル |
|---|---|---|
| GPU 1台 | ベアメタル | Linux 基礎 |
| GPU 数台(同一用途) | ベアメタル + Ansible | Linux + 構成管理 |
| GPU 数台〜数十台(混在ワークロード) | K8s + GPU Operator | K8s + MLOps |
| 大規模クラスタ(100台以上) | Slurm / Ray | HPC 専門知識 |
Ollama と vLLM の使い分け
| 観点 | Ollama | vLLM |
|---|---|---|
| セットアップ | ワンライナー | uv + 数コマンド |
| 対応モデル | Ollama ライブラリから選択 | Hugging Face 上の幅広いモデル |
| API 互換性 | 独自 + OpenAI 互換 | OpenAI 完全互換 |
| スループット | 単一リクエスト向き | 高並列処理(Continuous Batching) |
| メモリ効率 | 標準 | PagedAttention で最適化 |
| 適性 | 個人〜小規模チーム | 高負荷の本番推論サーバー |
小規模かつ手軽に始める場合はOllama、高スループットが求められる本番環境ではvLLMという使い分けが現実的です。
まとめ
| 判断基準 | ベアメタル | Docker | K8s |
|---|---|---|---|
| GPU 1台で推論 | ◎ | △ | ✕(過剰) |
| CUDA バージョン切替 | △ | ◎ | ◎ |
| 本番推論サーバー | ◎ | ○ | ○ |
| マルチノード管理 | △ | ○ | ◎ |
| 非エンジニアの運用 | ◎ | ✕ | ✕ |
| トラブル時の切り分け | 容易 | 中程度 | 複雑 |
単一マシンでLLM推論を動かす場合は、構成がシンプルなベアメタルを推奨します。複数のCUDAバージョンを切り替える開発環境ではDocker、ワークロードを複数ノードへ動的に振り分ける場合はK8sが選択肢になります。GPUの台数や用途に加え、構成管理や障害調査を担う運用体制を踏まえて選定してください。
