只要容器是以 GPU 方式启动的(挂载了 NVIDIA 驱动),容器内就能直接看到并监控 GPU 状态,因为容器本身运行在宿主机的内核驱动之上,nvidia-smi 等工具读的就是同一块物理 GPU。
先验证容器是否有 GPU 权限
bash
docker exec -it <容器名> nvidia-smi
- 有输出:容器已正确挂载 GPU,可以直接监控。
- 报错 "command not found":镜像里没装 nvidia-smi,可尝试
ls /usr/bin/nvidia-smi或看/proc/driver/nvidia/version。 - 报错 "couldn't communicate with the NVIDIA driver":容器启动时没挂 GPU,需要在宿主机用
docker run --gpus all ...(或NVIDIA_VISIBLE_DEVICES环境变量,配合宿主机的 nvidia-container-toolkit)重新启动,这一点在容器内无法补救。
容器内常用的监控方式
1. nvidia-smi(最常用,无需额外安装)
bash
nvidia-smi # 一次性快照:利用率、显存、温度、功耗、进程
watch -n 1 nvidia-smi # 每秒刷新
nvidia-smi dmon # 精简的实时指标流(SM利用率、显存带宽、温度、功耗)
nvidia-smi pmon # 按进程监控每个进程的 GPU/显存占用
nvidia-smi --query-gpu=timestamp,utilization.gpu,memory.used,temperature.gpu \
--format=csv -l 5 # 每5秒输出CSV,方便重定向到日志文件
2. DCGM(数据中心级监控,适合长时间运行/多卡) 如果镜像是 NVIDIA 官方 CUDA 镜像,可能已带 dcgmi。生产环境更常见的做法是在宿主机另跑一个 dcgm-exporter 容器,把指标暴露给 Prometheus + Grafana 做面板。
3. 程序化读取(NVML) 在训练脚本里可以直接用 Python 获取指标,便于记录或上报:
python
import pynvml
pynvml.nvmlInit()
h = pynvml.nvmlDeviceGetHandleByIndex(0)
print(pynvml.nvmlDeviceGetUtilizationRates(h).gpu) # GPU利用率%
print(pynvml.nvmlDeviceGetMemoryInfo(h).used // 2**20) # 已用显存 MiB
几个注意事项
- 可见范围受限 :如果启动时只分配了部分卡(如
--gpus '"device=0,1"'或设置了CUDA_VISIBLE_DEVICES),容器内只能看到这几张卡;宿主机上的其他 GPU 不可见。 - MIG 场景:如果 GPU 开启了 MIG 切分,容器内只能看到分配给它的 MIG 实例。
- 只能读不能改:监控没有问题,但修改主机级设置(如 persistence mode、ECC、功耗上限)需要特权,普通容器会报 "Insufficient Permissions"。
- 进程号差异 :容器内
nvidia-smi看到的是容器自己的进程,宿主机上其他用户的进程对它不可见(这也算一种隔离,通常反而是想要的效果)。
简单说:先用 docker exec <容器名> nvidia-smi 试一下,能出表格就说明一切就绪;日常用 nvidia-smi dmon 或 watch 看实时状态,长期监控再考虑 DCGM + Prometheus 那套。