torch.profiler.trace未生成chrome trace文件是因为默认不自动保存,需显式调用export_chrome_trace()且record_shapes=true;常见错误是仅使用with profile但未导出,或prof初始化失败。

torch.profiler.trace 为什么没生成预期的 Chrome Trace 文件
默认调用 torch.profiler.profile 不会自动保存 Chrome Trace(.json),必须显式启用 record_shapes=True 并调用 export_chrome_trace()。常见错误是只写 with torch.profiler.profile() as prof:,然后就结束了——此时 prof 对象只是内存中记录,不落盘。
- 确保在
profile上下文结束后调用prof.export_chrome_trace("trace.json") -
record_shapes=True是导出 shape 信息的前提,否则 trace 中 tensor 维度为空,影响算子分析 - 若报错
AttributeError: 'NoneType' object has no attribute 'export_chrome_trace',说明prof未正确初始化,检查是否漏了with或提前del了 profiler 实例
profile 的 activities 参数该选哪些:CPU、CUDA 还是 both
实际性能瓶颈常分布在不同层级:模型前向/反向可能卡在 CUDA kernel,但数据加载或预处理逻辑跑在 CPU;若只开 activities=[torch.profiler.ProfilerActivity.CPU],会完全看不到 GPU 时间,误判“模型很快”。
- 训练阶段务必设为
activities=[torch.profiler.ProfilerActivity.CPU, torch.profiler.ProfilerActivity.CUDA] - 推理部署时若用 CPU 模式,禁用 CUDA 可减少开销(避免驱动通信延迟干扰)
- 注意:
CUDAactivity 在无 GPU 或未调用.cuda()时会静默失效,不会报错,需确认设备一致性
如何用 profile 定位 DataLoader 瓶颈而非模型本身
很多慢不是模型算得慢,而是 DataLoader 卡在 __getitem__ 或 collate 阶段。直接对整个训练循环 profile 会把 IO 和计算混在一起,难以区分。
- 单独 profile 数据加载:在
for batch in dataloader:外层加 profiler,并跳过模型 forward/backward - 设置
wait=0, warmup=1, active=1,只采集单个 iteration,避免平均效应掩盖毛刺 - 重点关注
torch.utils.data.dataloader._MultiProcessingDataLoaderIter._next_data和自定义__getitem__耗时,若占比 >30%,优先优化 transform 或启用pin_memory=True+num_workers>0
profile 结果里 self_cpu_time_total 和 cpu_time_total 的区别
cpu_time_total 是该算子及其所有子调用(比如 conv → cudnn_conv → memcpy)的累计 CPU 时间;self_cpu_time_total 扣除了子调用,只算它自己“裸”执行的时间。看瓶颈时优先盯 self_cpu_time_total,否则容易误把底层 memcpy 当成模型问题。
- 例如
aten::conv2d的cpu_time_total很高,但self_cpu_time_total接近 0,说明实际耗时在 cuDNN kernel 内部(属于 CUDA time),应查cuda_time_total - 若某自定义
torch.nn.Module.forward的self_cpu_time_total异常高,大概率是用了 Python 循环、list.append或未向量化的 numpy 操作 - Chrome Trace 中对应字段是
dur(总耗时)和tdur(self duration),可交叉验证
f"trace_rank{dist.get_rank()}.json"。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











