GPU 软件
使用 NVIDIA Container Toolkit 运行 Docker GPU 容器
我们的 Ubuntu 镜像已预装 Docker 和 NVIDIA Container Toolkit。下面介绍如何为每个容器分配它所需的 GPU,并且只分配这些 GPU。
本页内容
借助 NVIDIA Container Toolkit 运行 Docker GPU 工作负载只需一个参数,但实际部署还需要多做几步:为每个容器选择 GPU、在 Docker Compose 中预留 GPU、选择与驱动匹配的基础镜像,以及为 PyTorch 提供足够的共享内存。我们的 Ubuntu 镜像已预装 Docker 和该工具包。AMD 服务器则改用设备参数,文末附近会介绍。
检查 Docker 和 Container Toolkit
docker --version
nvidia-ctk --version
docker info | grep -i runtimes
docker run --rm --gpus all ubuntu nvidia-smi
最后一条命令应输出与主机上相同的 GPU 表格。Container Toolkit 会把主机的驱动挂载到容器中,因此镜像中从不包含驱动,只需包含应用程序所用的 CUDA 库。以非 root 用户身份操作时,请在 docker 前加上 sudo,或者加入 docker 组(该组的权限等同于 root)。
为容器分配全部或部分 GPU
# all GPUs
docker run --rm --gpus all ubuntu nvidia-smi -L
# GPUs 0 and 1 (the inner quotes are required because of the comma)
docker run --rm --gpus '"device=0,1"' ubuntu nvidia-smi -L
# one GPU by UUID, as printed by nvidia-smi -L on the host
docker run --rm --gpus device=GPU-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
ubuntu nvidia-smi -L
在容器内,选中的 GPU 从 0 开始编号,因此主机上的 2 号和 3 号 GPU 会显示为 0 号和 1 号。要把某项服务固定到特定的 GPU 上,使用 UUID 最为稳妥。要在 8 卡服务器上运行 8 个相互独立的任务,请用 为每张 GPU 各启动一个容器。
对于使用 NVIDIA 运行时的容器,Container Toolkit 还会读取 NVIDIA_VISIBLE_DEVICES 变量:
docker run --rm --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=0,1 \
ubuntu nvidia-smi -L
如果 /etc/docker/daemon.json 中的默认运行时是 nvidia,那么设置了该变量的镜像(NVIDIA 的 CUDA 镜像就是如此)即使不加 也会获得所有 GPU;因此,需要限制 GPU 时,请显式设置该变量。CUDA_VISIBLE_DEVICES 则不同:它在容器内部,从已挂载的 GPU 中进行筛选。
在 Docker Compose 中预留 GPU
services:
trainer:
image: ubuntu:24.04
command: nvidia-smi -L
ipc: host
deploy:
resources:
reservations:
devices:
- driver: nvidia
device_ids: ["0", "1"]
capabilities: [gpu]
用 docker compose up 运行,输出中应列出两张 GPU。如果要按数量而不是按 ID 分配 GPU,请将 device_ids 替换为 count: all 或 count: 2;这两个键不能同时使用,并且必须设置 capabilities: [gpu]。如果 docker compose version 运行失败,请安装 Compose 插件:Docker 来自 Docker 官方软件源时安装 ,来自 Ubuntu 软件源时安装 。
即使 ufw 拒绝该端口,像 这样发布的端口仍可从互联网访问,因为 Docker 会写入自己的防火墙规则。请以 的形式发布服务(在 Compose 中写作 "127.0.0.1:8000:8000"),并在前面放置反向代理,具体做法见防火墙指南。
选择 CUDA 或 NGC 基础镜像
- nvidia/cuda 镜像发布在 Docker Hub 上,分为三种类型:
base(最精简的 CUDA 运行时)、runtime(增加 CUDA 库)和devel(再增加编译器和头文件),部分镜像还包含 cuDNN。标签格式为,例如VERSION-FLAVOR-OS 。12.8.1-runtime-ubuntu24.04 - NGC 镜像(例如
nvcr.io/nvidia/pytorch)集成了经过调优的框架栈,按月发布标签,格式为。其发行说明列出了每个标签所需的驱动。YY.MM-py3
请选择 CUDA 版本不高于主机上 所显示“CUDA Version”的标签;对于 Blackwell GPU,还需选择 CUDA 12.8 或更高版本。如果镜像所需的驱动比主机上的更新,容器会拒绝启动,并报出 unsatisfied condition: cuda>= 错误。驱动与 CUDA 版本一文解释了这条规则。
为 PyTorch 提供足够的共享内存
Docker 默认将 /dev/shm 限制为 64 MB。PyTorch DataLoader 的 worker 进程和 NCCL 都依赖共享内存,因此训练会失败,并报出“bus error”或“insufficient shared memory (shm)”消息。请共享主机的 IPC 命名空间,或者提高该限制(将 YY.MM 替换为当前的标签):
# share the host IPC namespace, as NVIDIA recommends for its PyTorch images
docker run --rm -it --gpus all --ipc=host \
--ulimit memlock=-1 --ulimit stack=67108864 \
-v /data:/data nvcr.io/nvidia/pytorch:YY.MM-py3
# or keep IPC isolated with a larger /dev/shm
docker run --rm -it --gpus all --shm-size=16g \
-v /data:/data nvcr.io/nvidia/pytorch:YY.MM-py3
在容器内,df 会显示可用空间。在 Compose 中,请使用 ipc: host 或 shm_size: "16gb"。vLLM 镜像也需要同样的处理,参见用 vLLM 提供大语言模型(LLM)推理服务。
AMD GPU:ROCm 中的对应做法
docker run --rm --device=/dev/kfd --device=/dev/dri \
--group-add video --ipc=host \
rocm/pytorch:latest \
python3 -c "import torch; print(torch.cuda.device_count())"
在 MI355X 服务器上,这条命令会输出 8。运行 ROCm 容器的标准方式是传入设备文件,而不是使用 :/dev/kfd 是计算接口,/dev/dri 中则是 GPU 设备节点。要让容器只使用部分 GPU,请添加 。其余内容请参阅 ROCm 配置。
故障排查
- could not select device driver "" with capabilities: [[gpu]] 或 unknown or invalid runtime name: nvidia。Docker 尚未配置 NVIDIA 运行时。请运行
sudo,然后运行nvidia-ctk runtime configure--runtime=docker sudo systemctl restart docker。 - unsatisfied condition: cuda>=X.Y. 该镜像需要更新的驱动。请改用较旧的镜像标签,或在控制台提交工单咨询驱动问题。
- 连接 Docker 守护进程套接字时出现 permission denied。请使用
sudo,或者将您的用户加入docker组,然后重新登录。
问题仍未解决?
请在控制台提交工单,写明服务器、您运行了什么以及错误输出(如有)。工程师 7×24 小时答复。