训练慢、GPU utilization 低怎么查?
训练 hang 住怎么查?

英文问法If GPU utilization is low during training, how would you debug and benchmark performance? · Your multi-node job hangs. How do you find out why?

考过面经:NVIDIA SWE 2025-12("If GPU utilization is low during training, how would you debug and benchmark performance?",Aced 用户提交);国内:快手("hang都有可能因为什么,分别要如何排查");其他公司:Tower("Debug Oscillating GPU Utilization During Training")

先弄清楚:每个概念是什么

GPU utilization(nvidia-smi)
采样周期里有任意 kernel 在跑的时间比例,不是 SM 用满了多少。一个很小的 kernel 一直跑也算 100%,hang 住时 NCCL kernel 在等对端也可能显示很高。
Profiler trace 与 GPU gap
把 CPU 和 GPU 每个 kernel 画在时间线上。GPU 上的空白就是浪费,空白前 CPU 在干什么,瓶颈就在哪。
Implicit sync
CPU 必须等 GPU 算完才能往下走:.item()、print(cuda_tensor)、.cpu()、依赖 GPU 结果的 if。CPU 没法提前排队,GPU 就出现空白。
Straggler
某一张卡比别人慢(数据更长、降频、网卡有问题),所有卡在下一次 collective 都得等它。
Collective hang
collective 要求所有 rank 都调用、顺序和 shape 一致。一个 rank 没进来,其余的就一直等。

看图:排查流程和两个例子

训练慢、GPU util 低① 量化:step time、tokens/s、MFUnvidia-smi util 只说明有 kernel 在跑② profile 几步,看 timelinetorch.profiler 或 Nsight Systems③ GPU 上的空白在哪?每步开头 GPU 空等 → DataLoader密集小空隙 → launch-bound.item() 后的空隙 → implicit syncNCCL 旁边没计算 → comm exposed某 rank 总最后到 → straggler④ 对症修,再量一次单卡 → 单机 → 多机,synthetic data训练中途 hang 住① 每个 rank:py-spy dump加 --native 看 C++ 栈② flight recorder超时自动 dump,fr_trace 找缺席的 rank③ 谁没进同一个 collective?再看它停在代码哪一行④ 复现时查 collective 类型、shapeTORCH_DISTRIBUTED_DEBUG=DETAIL⑤ 设 timeout,把 hang 变成报错另一种:init 时就卡住NCCL_DEBUG=INFONCCL_DEBUG_SUBSYS=INIT,BOOTSTRAP,NET
图 1:左边查“慢”,右边查“hang”,都从上往下走,加粗框是起点和最关键的一步。虚线框是连 init 都没过的情况。
慢:一步 400 ms 拆开看修之前等数据 120计算 24040露出的 all-reducenvidia-smi 算作“有 kernel 在跑”:280 / 400 = 70%真正在计算:240 / 400 = 60%修之后计算 24040280 ms,吞吐 ×1.43num_workers 0 → 8、pin_memory=True 后等数据消失;剩下的 40 ms 再查通信hang:8 卡停在 step 1200,py-spy 看每个 rankrank 0rank 1rank 2rank 3rank 4rank 5rank 6rank 7停在 loss.backward() 里的 DDP all-reduce停在 save_checkpoint() 里的 all_gather(写在 if rank == 0: 里)两边等的不是同一个 collective,谁也等不到谁;修法:所有 rank 都调用,或挪出 if
图 2:下面两个手算例子画出来,上半是慢的那一步的 GPU 时间线,下半是 hang 时每个 rank 停在哪。

30 秒回答

For slow training I first quantify step time, throughput and MFU; nvidia-smi utilization only tells whether any kernel is running. Then I profile a few steps with torch.profiler or Nsight Systems and classify the GPU-timeline gaps: idle at step start means the data loader; many tiny gaps mean launch overhead; gaps after .item() or .cpu() are implicit syncs; long NCCL kernels with nothing beside them are exposed communication. For a hang, I dump every rank's stack with py-spy, turn on NCCL_DEBUG=INFO and the flight recorder, and find the rank that is not in the same collective as the others.

训练慢:步骤

  1. 量化:step time、tokens/s、MFU;nvidia-smi / DCGM 看 util 和显存
  2. profile 几步:torch.profiler(schedule 跳过 warmup)或 Nsight Systems,看 timeline
  3. 按下表归类;再做控制变量:单卡 → 单机 → 多机看 scaling,换 synthetic data 排除 DataLoader
trace 上看到原因怎么修
每步开头 GPU 空等DataLoadernum_workers、pin_memory、预处理离线
kernel 之间密集小空隙launch-boundCUDA Graphs、kernel fusion、更大 batch
.item() / .cpu() 后的空隙implicit sync别每步同步,攒几步再取
NCCL kernel 很长、旁边没计算comm exposednccl-tests 测 busbw;开 overlap;TP 留在机内
某 rank 总是最后到 collectivestraggler比各 rank 的 step time,换节点、balance 数据

训练 hang:步骤

  1. init 就卡住:NCCL_DEBUG=INFO NCCL_DEBUG_SUBSYS=INIT,BOOTSTRAP,NET 看 bootstrap 和网卡选择。常见是 NCCL 选错网卡(用 NCCL_SOCKET_IFNAME 指定)、MASTER_ADDR / 端口不通、防火墙
  2. 训练中卡住:每个 rank py-spy dump --pid PID(加 --native 看 C++ 栈)
  3. flight recorder:TORCH_NCCL_TRACE_BUFFER_SIZE=2000 + TORCH_NCCL_DUMP_ON_TIMEOUT=true,超时时每个 rank dump 最近的 collective,用 fr_trace 找缺席的 rank
  4. 复现时开 TORCH_DISTRIBUTED_DEBUG=DETAIL:检查每次 collective 的类型和 shape 是否一致
  5. 设 init_process_group(timeout=...)(NCCL 默认 10 分钟),让 hang 变成报错退出

常见原因:rank 相关的 if 让 collective 顺序或次数不一致。PP send / recv 不配对。某 rank OOM 退出。网络或 PCIe ACS 有问题。

手算例子

必答点

追问

GPU util 周期性忽高忽低(Tower 题)?

把低谷和代码对齐:每 N 步的 checkpoint / eval,DataLoader 的 buffer 取空再填,或 comm 和计算交替暴露。trace 里看低谷时 CPU 在干什么。

怎么找 straggler?

各 rank 记录 step time,TORCH_NCCL_ENABLE_TIMING=1 记录每个 collective 的耗时。慢的 rank 计算时间长,其他 rank 在 collective 里等得久。

timeout 之后会发生什么?

NCCL backend 的 watchdog 会 abort 这个 collective 并让进程崩溃,因为失败的异步 NCCL 操作可能让后续 CUDA 计算用到坏数据。TORCH_NCCL_ASYNC_ERROR_HANDLING 控制怎么 abort。

来源nvidia-smi docs(Utilization)· torch.profiler(schedule、trace handler)· PyTorch Performance Tuning Guide(num_workers、pin_memory、CUDA Graphs、avoid CPU-GPU sync)· NCCL Logging(Diagnosing Initialization Hangs)、NCCL env(NCCL_DEBUG、NCCL_DEBUG_SUBSYS、NCCL_SOCKET_IFNAME)· nccl-tests · py-spy README(dump、--native)· torch.distributed(init_process_group timeout、TORCH_DISTRIBUTED_DEBUG)、PyTorch NCCL env vars · Flight Recorder tutorial