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 直接打满。
调优

  1. 把卷积权重转 fp16
  2. 打开 PYTORCH_ROCM_FP16_ENABLED=1
  3. 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 宽度不友好,峰值算力吃不满。
调优

  1. micro_batch_size 从 1 提到 4;
  2. 打开 torch.backends.cudnn.benchmark=True
  3. 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()
调优

  1. 升级到 ROCm 5.7 内置 RCCL 2.17;
  2. 关同步:export NCCL_ASYNC_ERROR_HANDLING=0
  3. DDPbucket_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% 日常疑问:

  1. 先看卡rocminfo | grep -E "Compute Unit|SIMD"
  2. 再跑指标omniperf profile -n $JOB -- $CMD
  3. 盯颜色:红→带宽,橙→缓存/命中率,绿→健康
  4. VALU<50% 先加 batch / pad 维度;Memory>85% 先降精度 / 融合算子
  5. Sync Stall 红 先升 RCCL 版本、调 bucket_size,再关同步

5. 结语

nvidia-smirocminfo,从 nvprofomniperf,命令换了一茬,排查思路却相通:先确认硬件身份,再采集运行时指标,最后对照颜色找“最红”的那一项。把本文 3 组调优模板直接套到你的 PyTorch、vLLM 或 SGLang 任务里,基本能在 1 小时内定位是“内存墙”“计算墙”还是“同步墙”。下次再有人问你“AMD 卡怎么调优”,直接把这篇小抄甩过去,剩下的就是改代码、收指标、看绿色条慢慢变长。

立即加入 AI 开发者计划,免费领取 100 小时算力

添加微信小助手 csdn-01 还可额外领取「Openclaw 实战秘籍」

Logo

免费领 200 小时云算力,进群参与显卡、AI PC 幸运抽奖

更多推荐