默认参数几乎没用,因不设schedule只录首个batch(含初始化噪声),record_shapes=False漏隐式拷贝,profile_memory=False无法捕获显存峰值,且必须同时启用CPU/CUDA活动才能识别跨设备搬运瓶颈。

torch.profiler.profile 默认不录真瓶颈,直接用会白跑。必须配对启用 CPU 和 CUDA 活动、设 schedule、开 record_shapes 和 profile_memory,否则看到的只是表象。
为什么默认参数几乎没用?
不设 schedule 就只录第一个 batch,而它常被初始化、JIT 编译、CUDA 上下文建立污染;record_shapes=False 会导致张量尺寸异常引发的隐式拷贝(比如 aten::copy_)无法溯源;profile_memory=False 则看不到某层输出是否卡在显存分配峰值上。
必须同时启用双设备:activities=[ProfilerActivity.CPU, ProfilerActivity.CUDA]——否则跨设备搬运(如 tensor.to("cuda"))会被拆成两段,根本看不出是数据加载慢还是模型计算慢。
-
wait=1:跳过首 step,避开冷启动抖动 -
warmup=1:让 CUDA kernel 完成编译,避免把编译时间算进耗时 -
active=3:只分析紧接其后的 3 步,平衡精度与开销
record_function 怎么插才不混逻辑?
record_function 不是装饰器,是上下文管理器,必须包住实际执行逻辑,而不是仅包模型调用。否则 loss.backward() 和 optimizer.step() 的耗时会被散落在各算子中,无法归到“backward”名下。
立即学习“Python免费学习笔记(深入)”;
SkillSub Pro - Python 题解与代码注释双功能技能功能概述SkillSub Pro - Python 题解与代码注释双功能技能是一项面向实际任务的技能,主要用于SkillSub Pro 是一个 Python 题解生成与代码注释的 双功能合体技能 ,专为学生、算法学习者和开发者设计;✅ 一个技能,两种用途 :;核心要点📝 题解模式 :输入题目/题号,自动生成完整 Python 题解(含详细注释、解题思路、复杂度分析);💬 注释模式 :输入 Python 代码,自动添加详细中。它将相关步骤、
常见错误:在 train_loader 迭代外加 record_function("forward"),导致 DataLoader.__next__ 的 I/O 时间全算进 forward 统计里。
- forward 段要包含
model(inputs)全过程,不能只写model - backward 段必须含
loss.backward()+optimizer.step()+optimizer.zero_grad() - data loading 要单独包裹,比如
with record_function("data_load"):放在for ... in train_loader:内部
怎么看输出才能避开误导性排序?
直接调 prof.key_averages().table(sort_by="cpu_time_total") 容易被累计时间带偏——比如看到 aten::add 排第一,其实是它被调用了 2000 次,单次才 0.01ms;真正该盯的是 Self CPU time total,排除子调用膨胀。
若某算子 # Calls 异常高(如 index_select 超 1000 次),大概率是 Python for 循环写在了 GPU 上;若 aten::copy_ 占比高,先查输入 tensor 是否在 CPU、模型是否在 GPU,而非急着改 clone。
- 优先看
Self CPU time total和GPU Kernel Utilization曲线 - 结合
with_stack=True查自定义模块(但会拖慢 profiler,只在必要时开) - 用
prof.export_chrome_trace("trace.json")导出后,在 Chrome 地址栏输入chrome://tracing打开,看 timeline 是否存在长空档
容易被忽略的协作断点
PyTorch Profiler 不会自动标记同步点,但 torch.cuda.synchronize() 或隐式同步(如 tensor.item()、tensor.cpu())会让 GPU 频繁空转。这类问题不会出现在算子列表里,只能靠 timeline 中的 gap 发现——如果 GPU 利用率曲线频繁跌零,八成是这里卡住了。
另外,pin_memory=True 但 num_workers=0,或 prefetch_factor 设得过大,都会让 data loader 成为隐形瓶颈,而 profiler 可能只显示 __next__ 耗时高,需结合 nvitop 看 CPU/GPU 利用率是否错峰。


















