关键是要确保每个容器能稳定、隔离、可复现地访问 gpu 资源,依赖 nvidia container toolkit 和 compose 的 devices 声明机制;需前置验证宿主机 gpu 环境、docker 版本、toolkit 生效,并在 docker-compose.yml 中正确配置 runtime: nvidia 与 devices。

要在 Linux 上用 Docker Compose 部署支持 GPU 加速的深度学习容器集群,关键不是堆砌服务数量,而是确保每个容器能稳定、隔离、可复现地访问 GPU 资源。核心依赖 NVIDIA Container Toolkit 和 Compose 的 devices 声明机制,而非旧式设备直通。
确认宿主机 GPU 环境已就绪
这是不可跳过的前置步骤。缺一环,后续全部失败:
- 运行
nvidia-smi,输出 GPU 列表和驱动版本(建议 ≥535.x) - 检查
docker --version≥ 24.0,docker compose version≥ v2.20.0 - 验证 NVIDIA Container Toolkit 是否生效:
docker run --rm --gpus all nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smi应正常显示 GPU 信息 - 若失败,请重装 toolkit 并执行
sudo nvidia-ctk runtime configure --runtime=docker,再sudo systemctl restart docker
编写支持 GPU 的 docker-compose.yml
推荐使用 Compose v2.19+ 原生 devices 语法,兼顾清晰性与兼容性。runtime 字段必须显式声明:
-
基础写法(单卡):
services:<br> trainer:<br> image: pytorch/pytorch:2.3.1-cuda12.1-cudnn8-runtime<br> runtime: nvidia<br> deploy:<br> resources:<br> reservations:<br> devices:<br> - driver: nvidia<br> count: 1<br> capabilities: [gpu, compute, utility]
-
多卡指定(如只用第 0 和第 2 卡):把
count: 1替换为device_ids: ["0", "2"] -
全卡可用但限制内存用量:在容器内通过
NVIDIA_VISIBLE_DEVICES=0,1或torch.cuda.set_per_process_memory_fraction(0.8)控制,而非在 Compose 中硬限显存
构建多服务协同集群(非简单复制)
真正实用的集群不是多个训练容器堆在一起,而是按职责解耦:
-
训练节点(trainer):挂载数据卷 + 指定 GPU,运行 DDP 启动脚本(如
python -m torch.distributed.run --nproc_per_node=2 train.py) -
推理服务(inference):使用
device_ids: ["1"]绑定独立 GPU,暴露 REST API 端口,避免与训练争抢资源 -
Jupyter 开发环境(dev):配
count: 1+ports: ["8888:8888"],镜像需含torch和cuda,启动时自动检测torch.cuda.is_available() -
监控服务(prometheus + node-exporter):不占 GPU,但采集
nvidia_smi指标,用于观察各容器 GPU 利用率、显存占用、温度
验证与调试常见问题
容器启动后,不要只看 nvidia-smi 是否能跑,要验证实际框架调用:
- 进入容器:
docker compose exec trainer bash - 检查 CUDA 可见性:
echo $CUDA_VISIBLE_DEVICES(应为 0 或空,非 unset) - Python 层验证:
python -c "import torch; print(torch.cuda.is_available(), torch.cuda.device_count())" - 若返回
False,大概率是漏了runtime: nvidia;若返回True, 0,说明 devices 声明未生效或驱动版本不匹配镜像 CUDA 版本 - 日志中出现
libcuda.so.1: cannot open shared object file?说明镜像 CUDA 版本高于宿主机驱动支持的最高 CUDA 版本(查 NVIDIA 官方兼容表)











