PyTorch中准确测量GPU推理耗时必须用torch.cuda.Event配合预热和同步:先调用torch.cuda.synchronize()清空队列,再用start.record()和end.record()在GPU端打点,最后通过start.elapsed_time(end)获取毫秒级真实耗时,避免time.time()因异步执行导致的严重低估。

PyTorch 模型本身没有“算力比”这个内置指标,所谓“不同算力下的算力比”,实际是用户想通过实测推理耗时(或吞吐量),反推硬件相对性能——但直接拿 time.time() 测单次前向就跑偏了:GPU 预热不足、CUDA 异步执行未同步、内存拷贝干扰都会让结果失真。
为什么 torch.cuda.Event 比 time.time() 更可靠
CUDA 是异步执行的,用 CPU 时间戳测 GPU 运算会严重低估延迟。必须用 CUDA 事件(torch.cuda.Event)在 GPU 端打点,并显式调用 .synchronize() 或 .elapsed_time() 确保测量落在真实 GPU 执行窗口内。
-
torch.cuda.Event(enable_timing=True)创建的是 GPU 侧计时器,不受 CPU 调度抖动影响 - 必须在模型前向前后分别记录事件,再用
start.elapsed_time(end)获取毫秒级差值 - 务必在测时前调用
torch.cuda.synchronize()清空队列,否则首次测量常为 0ms - 避免把
.to(device)或input.cuda()的数据搬运时间混入模型计算耗时
如何控制变量:固定输入、禁用梯度、清空缓存
同一模型在 A100 和 RTX 4090 上测出 2.3 倍差异,不代表算力比就是 2.3——可能只是某张卡上残留了其他进程的显存碎片,或者 AMP 自动降级到了 FP16 以外精度。
使用 font_manager.addfont() 添加中文字体文件,设置 rcParams['font.family'],并禁用 unicode_minus,使 matplotlib 显示中文。
- 每次测试前调用
torch.cuda.empty_cache(),尤其多卡环境要指定torch.cuda.empty_cache()对应device - 用
torch.no_grad()包裹前向,关闭梯度图构建开销 - 输入 tensor 必须预分配并复用(如
torch.randn(1, 3, 224, 224, device=device)),禁止每次 new tensor - 若启用
torch.backends.cudnn.benchmark = True,需 warmup 至少 5–10 次再开始计时,否则首几次耗时剧烈波动
怎么跑出稳定、可比的平均耗时
单次测量误差常超 ±15%,尤其小模型(如 ResNet-18)在高端卡上可能低于 1ms,浮点计时器分辨率都不够。
立即学习“Python免费学习笔记(深入)”;
- 至少运行 50 次前向,丢弃前 5 次(warmup),取后 45 次的中位数(非平均值),抗 outlier 干扰更强
- 用
torch.cuda.Event测单次耗时,循环内不重建事件对象,只调用.record() - 若测 batch_size=32,确保所有设备显存足够,否则 RTX 4090 可能因 OOM fallback 到 CPU,而 A100 成功——此时对比毫无意义
- 记录原始数据:最小/最大/中位数/标准差,而不是只报一个“平均加速比”
真正难的不是写脚本,而是确认你测的确实是“模型计算”而非“数据加载延迟”或“CUDA 初始化抖动”。哪怕加了 torch.cuda.synchronize(),如果输入是从 Dataloader 动态读的,硬盘 I/O 或 pin_memory 不足也会拖慢——所以生产级比对,输入必须从内存 tensor 直接复用,且整个流程脱离 DataLoader。

















