PyTorch训练首epoch后GPU利用率骤降、训练变慢问题求助
问题排查方案:Slurm下PyTorch训练首epoch正常,后续GPU利用率骤降
1. 优先排查数据加载/IO瓶颈
首epoch数据大概率被系统缓存到内存,后续缓存失效或磁盘IO跟不上,导致GPU长期等待数据,利用率暴跌。
- 检查方法:
- 用
nvidia-smi dmon -s u实时监控GPU的sm(流多处理器)利用率,同时用iostat -x 1看磁盘IO使用率。如果GPU idle时磁盘IO占满,直接坐实IO瓶颈。 - 在训练循环里记录每个step的开始/结束时间,后续epoch如果step耗时突然飙升,且大部分时间花在
dataloader.next()上,就是数据加载慢。
- 用
- 解决措施:
- 开启DataLoader的
persistent_workers=True,让数据加载worker进程在epoch间不销毁,避免重复初始化开销。 - 把数据集复制到节点本地临时存储(比如
/tmp),Slurm提交任务时可以用--tmp=100G申请临时磁盘空间,训练前先同步数据到本地。 - 调整
num_workers(建议设为CPU核心数的1-2倍)和pin_memory=True,让数据直接加载到GPU显存的 pinned 内存,减少数据拷贝时间。
- 开启DataLoader的
2. 检查Slurm资源调度问题
远程服务器的Slurm集群可能在首epoch后调整了你的任务资源,导致数据加载或计算受限。
- 检查方法:
- 用
sacct -j <你的任务ID>查看任务状态,有没有NODE_FAIL、REQUEUE或者PARTITION_LIMIT这类异常状态。 - 用
htop监控CPU使用率,如果后续epoch数据加载的worker进程CPU占用率极低或卡死,说明CPU资源被限制。
- 用
- 解决措施:
- 提交任务时加
--exclusive参数,独占节点所有资源,避免其他任务抢占IO/CPU。 - 检查Slurm任务日志(默认是
slurm-<job_id>.out),看有没有节点资源被回收、进程被杀死的报错信息。 - 如果是共享集群,换负载较低的分区提交任务。
- 提交任务时加
3. 排除多进程数据加载的bug
自定义Dataset或DataLoader的多进程逻辑可能存在线程不安全的问题,首epoch正常,后续worker进程出错导致数据加载卡住。
- 检查方法:
- 把
num_workers设为0,只用主进程加载数据,跑几个epoch看GPU利用率是否正常。如果正常,就是多进程加载的问题。 - 查看Slurm日志里有没有worker进程的报错信息(比如文件找不到、变量未定义),很多时候worker进程的错误不会被主进程捕获,只会静默卡住。
- 把
- 解决措施:
- 确保自定义Dataset里没有全局变量、非线程安全的文件操作(比如多个worker同时写同一个文件)。
- 如果用了自定义的采样器,检查采样器是否在epoch间正确重置状态。
4. 最后验证模型/优化器逻辑(概率较低)
虽然你认为首epoch正常就排除代码问题,但还是可以快速验证:
- 打印每个epoch的总step数、梯度值、学习率,看是否有异常(比如学习率骤降到0,导致参数不再更新,计算量减少)。
- 在每个step后加
torch.cuda.synchronize()再统计耗时,区分是计算时间还是数据加载时间。如果计算时间骤降,再排查模型代码。
内容的提问来源于stack exchange,提问作者K.S Kim
相关产品推荐
相关产品推荐

