在容器内使用 `rocm-smi` 监控 GPU 利用率
解读
国内互联网、金融、自动驾驶公司普遍把 AMD GPU(MI100/MI210 等)作为 CUDA 之外的第二选择,面试时考官想确认三件事:
- 你是否真正在容器里跑过 ROCm 栈,还是只在宿主机敲过命令;
- 能否把驱动、设备、权限、镜像、运行时五条线一次打通;
- 出现 “rocm-smi: command not found” 或 “Permission denied” 时,能否两分钟定位并给出修复方案。
回答必须体现“容器视角”——从镜像构建、引擎启动参数、到 cgroup 隔离,每一步都要让 GPU 可见且可监控,同时满足最小权限+可复现+可灰度的落地规范。
知识点
- ROCm 内核驱动版本与容器内用户态库版本必须大版本一致(如宿主机 5.7.x,镜像里 ROCm 5.7.x),否则 rocm-smi 读不到内核接口。
- 设备挂载:/dev/kfd + /dev/dri/ 下所有 renderD* 节点必须
--device显式透传,不能只挂 dri 目录。 - 用户组映射:宿主机 render 组 gid 需与容器内对齐,否则出现 “Permission denied”;国内大厂常用
--group-add=$(getent group render | cut -d: -f3)动态注入。 - 特权与 seccomp:ROCm 5.5+ 已无需
--privileged,但需关闭 seccomp 默认策略中对amdgpu_*ioctl 的屏蔽,推荐自定义 seccomp profile 而非直接--security-opt seccomp=unconfined。 - 镜像体积优化:rocm-smi 依赖 python3-amdsmi,多阶段构建时先
apt-get install rocm-smi再apt-get purge编译依赖,可把镜像从 3.8 GB 压到 1.1 GB。 - CI/CD 采集:在 GitLab-Runner 或 Jenkins k8s 插件里,把
rocm-smi --showuse --json输出写到$CI_PROJECT_DIR/gpu_util.json,后续 stage 用 jq 提取 GPU 利用率做质量门禁(>95 % 触发排队限流)。 - 故障排查三板斧:
dmesg | grep amdgpu看驱动是否加载;ls -l /dev/kfd确认 666 权限;rocminfo能否列出 Agent,若失败则基本可判定为驱动/设备问题而非容器问题。
答案
-
宿主机准备
以 Ubuntu 22.04 为例,安装官方 ROCm 5.7 驱动:sudo apt update && sudo apt install -y amdgpu-dkms rocm-dev sudo usermod -aG render,video $USER新开会话使组权限生效,执行
rocm-smi验证宿主机可见 GPU。 -
最小 Dockerfile
FROM ubuntu:22.04 ARG ROCM_VER=5.7 RUN apt-get update && \ apt-get install -y --no-install-recommends \ ca-certificates gnupg2 wget \ && wget -q -O - https://repo.radeon.com/rocm/rocm.gpg.key | apt-key add - \ && echo "deb [arch=amd64] https://repo.radeon.com/rocm/apt/${ROCM_VER} ubuntu main" > /etc/apt/sources.list.d/rocm.list \ && apt-get update \ && apt-get install -y rocm-smi-lib \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* ENV PATH=/opt/rocm/bin:$PATH ENTRYPOINT ["rocm-smi"] -
构建与运行
docker build -t rocm-smi:5.7 . docker run --rm \ --device=/dev/kfd \ --device=/dev/dri \ --group-add $(getent group render | cut -d: -f3) \ --security-opt seccomp=default-with-amdgpu.json \ rocm-smi:5.7 --showuse其中 default-with-amdgpu.json 在官方 seccomp 模板里增加
amdgpu_ioctl允许列表,符合国内安全基线。 -
持续监控脚本
在容器启动脚本里加入:while true; do rocm-smi --showuse --json > /tmp/gpu.json cat /tmp/gpu.json | jq '.[] | "\(.gpu) \(.gpu_use)%"' sleep 10 done &日志通过 stdout 输出,可被 Loki/ELK 直接采集。
-
常见错误与修复
- rocm-smi: command not found → 镜像未装 rocm-smi-lib,或 PATH 未包含 /opt/rocm/bin;
- hsa api call failure:0x1008 → 宿主机驱动与容器 ROCm 版本不一致,统一升级到 5.7;
- Permission denied on /dev/kfd → 未加 render 组,或宿主机 udev 规则把 kfd 设成 600,修复 udev 规则为 666。
拓展思考
- 多 GPU 隔离:国内训练集群常把 8 卡拆成 2×4 组,用
DOCKER_ROCM_DEVICES=card0,card1,card2,card3环境变量,启动时通过 --device 逐一挂载,并在容器内用rocm-smi --id 0,1,2,3限定查询范围,实现业务级 GPU 分区。 - 与 Kubernetes 设备插件联动:AMD 官方 k8s-device-plugin 已支持 device plugin v1beta1,在 Pod 里申请
amd.com/gpu: 1后,插件会自动注入 /dev/kfd 与对应 renderD*,无需人工写 volumeMount;但监控 sidecar 仍需共享 IPC,建议用 EmptyDir 共享 /tmp/rocm 让 sidecar 读到同一 hsa 句柄。 - 安全加固:金融场景要求非 root 运行,可在 Dockerfile 加
USER 65534:65534,同时把 /dev/kfd 权限改成 666,并通过 AppArmor 限制容器对 /sys/class/kfd 的写操作,实现“看得见、改不了”。 - 镜像预热与缓存:大模型镜像 8 GB+,国内 Harbor 可开 P2P 预热,结合 Dragonfly 把 rocm-smi 层提前分发到 GPU 节点,使 100 节点同时拉起时间从 15 min 降到 90 s。
- 与 Prometheus 生态对接:社区已提供 rocm-smi-exporter,容器化后挂在 DaemonSet,自动把 GPU 利用率、显存、温度转为 Prometheus 指标,再经 Grafana 模板展示,面试时可现场画一条 PromQL:
rate(rocm_gpu_utilization_percent[5m]) > 90,体现可观测性落地能力。