用 rocminfo 与 omniperf 给 ROCm 性能体检,一文看懂输出每个字段
1. 登录后第一件事:把卡“验明正身”
习惯 nvidia-smi 的同学,第一次 SSH 到 AMD Instinct™ 实例总会下意识敲 nvidia-smi,结果当然是 command not found。在 ROCm 世界里,等价的“身份证”命令是 rocminfo。下面这 30 秒的操作,能告诉你“我到底拿了几张卡、每张卡有多少 SIMD、多少 CU、显存多大、PCIe 位宽多少”。
# 1. 确认驱动已加载
lsmod | grep amdgpu
# 2. 看卡
rocminfo | grep -E "Name|Device ID|Compute Unit|SIMD|VRAM|PCIe"
输出片段示例(已脱敏):
Device Type: GPU
Name: AMD Instinct MI210
Device ID: 0x740f
Compute Unit: 104
SIMD per CU: 4
VRAM: 65536 MB
PCIe ID: 0000:4b:00.0
重点字段速记
- Compute Unit(CU):相当于 NVIDIA 的 SM,直接决定“理论并发线程块”上限。
- SIMD per CU:MI210 每 CU 有 4 个 SIMD,一个 SIMD 宽度 64,换算成 CUDA 概念≈256 线程/SM。
- VRAM:如果低于模型峰值占用 20% 余量,后续训练大概率 OOM。
把上面几行贴进团队群,就能避免“明明要 8 卡却只占 4 卡”的尴尬。
2. 用 omniperf 给 kernel 做“血常规”
rocminfo 只是体检表,真正定位瓶颈得看运行时指标。ROCm 官方开源的 omniperf 把底层 ROCm-SMI + rocprofiler 的计数器做了可视化封装,零插桩就能采集 Top-Level(TBP)、Cache、VALU 等 200+ 指标。
2.1 一键安装
# 需要 ROCm 5.6+,Python≥3.8
pip install omniperf
omniperf --version # 验证
2.2 采集三步走
# 1. 生成工作目录
omniperf profile -n bert_large -- ./train_bert.sh
# 2. 等待程序跑完,自动落盘
# 3. 启动报告服务器
omniperf report -p workloads/bert_large/mi210/
浏览器打开 http://<ip>:8000,就能看到类似下图的 Dashboard(截图已脱敏,关键色块保留):
| 区域 | 颜色 | 含义 |
|---|---|---|
| Memory BW 条形图 | 深红 | 带宽利用率 >85%,瓶颈 |
| VALU Busy | 浅绿 | 利用率 42%,健康 |
| L2 Cache Hit | 橙 | 命中率 71%,偏低 |
颜色口诀:红=堵,橙=慢,绿=畅。先扫一眼“红条”在哪,再决定是砍 batch、砍特征维度还是换融合算子。
3. 真实场景三连击:内存 / 计算 / 同步
下面 3 组案例来自魔搭创空间(ModelScope)社区用户实测,均用同一套 MI210 8 卡节点,框架为 PyTorch 2.1 + ROCm 5.7。每张图左侧为调优前,右侧为调优后,纵坐标统一用 omniperf 的“瓶颈百分比”展示。
3.1 内存带宽受限——Stable Diffusion UNet
现象
Memory BW 条红到顶,VALU 仅 30%。
根因
UNet 大量 fp32 常数读写,把 1 096 GB/s 的 HBM 直接打满。
调优
- 把卷积权重转
fp16; - 打开
PYTORCH_ROCM_FP16_ENABLED=1; - 在
nn.Conv2d外加torch.cuda.amp.autocast()。
命令
export PYTORCH_ROCM_FP16_ENABLED=1
python train_sd.py --mixed-precision fp16
结果
Memory BW 降到 62%,VALU 升到 78%,单卡迭代时间 1.7 s → 1.1 s。
3.2 计算受限——LLaMA-7B 预训练
现象
VALU Busy 94%,Memory BW 仅 38%。
根因hidden_size=4096 时,矩阵乘维度对 SIMD 宽度不友好,峰值算力吃不满。
调优
- 把
micro_batch_size从 1 提到 4; - 打开
torch.backends.cudnn.benchmark=True; - 在
matmul前手动pad到 64 倍数,再slice还原。
命令
pad = (64 - K % 64) % 64
x = F.pad(x, (0, pad))
out = torch.matmul(x, weight)
out = out[:, :, :orig_K]
结果
VALU 利用率 94% → 98%,单步时间 2.3 s → 1.9 s,收敛总时长缩短 17%。
3.3 同步受限——多卡 AllReduce 拖尾
现象
Kernel 尾部出现大块“空白”时间,omniperf 的 Sync Stall 条红。
根因
PyTorch 默认 NCCL_ASYNC_ERROR_HANDLING=1 会插同步,ROCm 后端额外做一次 hipDeviceSynchronize()。
调优
- 升级到 ROCm 5.7 内置 RCCL 2.17;
- 关同步:
export NCCL_ASYNC_ERROR_HANDLING=0; - 把
DDP的bucket_size从 25 MB 提到 100 MB。
命令
export NCCL_ASYNC_ERROR_HANDLING=0
export RCCL_BUFFSIZE=104857600
torchrun --nproc_per_node=8 train.py
结果
Sync Stall 占比 18% → 3%,8 卡扩展效率 0.78 → 0.91。
4. 把排查流程写成 5 行小抄
把上面经验浓缩成一张“排查速查表”,贴到 tmux 状态栏旁边,基本能覆盖 90% 日常疑问:
- 先看卡:
rocminfo | grep -E "Compute Unit|SIMD" - 再跑指标:
omniperf profile -n $JOB -- $CMD - 盯颜色:红→带宽,橙→缓存/命中率,绿→健康
- VALU<50% 先加 batch / pad 维度;Memory>85% 先降精度 / 融合算子
- Sync Stall 红 先升 RCCL 版本、调
bucket_size,再关同步
5. 结语
从 nvidia-smi 到 rocminfo,从 nvprof 到 omniperf,命令换了一茬,排查思路却相通:先确认硬件身份,再采集运行时指标,最后对照颜色找“最红”的那一项。把本文 3 组调优模板直接套到你的 PyTorch、vLLM 或 SGLang 任务里,基本能在 1 小时内定位是“内存墙”“计算墙”还是“同步墙”。下次再有人问你“AMD 卡怎么调优”,直接把这篇小抄甩过去,剩下的就是改代码、收指标、看绿色条慢慢变长。
添加微信小助手 csdn-01 还可额外领取「Openclaw 实战秘籍」
更多推荐



所有评论(0)