如何使用nvprof观测PyTorch脚本的CUDA内核调用与运行耗时
可行性结论
完全可行。nvprof工作在CUDA驱动层,和上层宿主语言是C还是Python无关,只要程序调用CUDA接口向GPU发射内核,nvprof就能拦截到对应的调用记录、统计运行耗时。PyTorch的GPU算子底层均基于CUDA实现,2D卷积默认调用cuDNN的优化内核,完全可以被nvprof正常捕获,你之前分析C/CUDA混合程序积累的nvprof使用经验基本可以直接复用。
具体操作步骤
- 第一步:修改你的PyTorch测试代码,补全GPU同步逻辑
PyTorch默认采用GPU异步执行机制,CPU代码提交完GPU任务后会立刻往下走,不会等GPU任务执行完成,如果不做同步,程序提前退出会导致内核耗时统计不准、甚至截断未执行完的内核记录。你需要在卷积运算执行完成后,显式调用同步接口,最小可运行测试代码参考如下:import torch import torch.nn.functional as F # 绑定目标GPU设备 device = torch.device("cuda:0") # 构造卷积测试用的输入、权重张量,直接分配在GPU显存上 input_ten = torch.randn(1, 3, 224, 224, device=device) conv_w = torch.randn(64, 3, 7, 7, device=device) # 执行单次2D卷积 output = F.conv2d(input_ten, conv_w, stride=2, padding=3) # 阻塞等待所有GPU任务执行完成 torch.cuda.synchronize() - 第二步:执行nvprof采集数据
命令格式和你之前分析C++程序几乎一致,只需要把可执行程序替换为你环境里运行PyTorch的python解释器即可,最基础的采集GPU内核调用时序与耗时的命令为:
常用参数和你之前的用法完全通用:nvprof --print-gpu-trace python your_conv_file.py- 加
--log-file prof_result.txt可以把采集结果输出到指定文件,避免控制台输出被Python日志冲掉 - 需要统计各内核累计耗时、占比时,把
--print-gpu-trace换成--print-gpu-summary即可 - 需要采集内核占用率、显存带宽等细粒度指标时,用
--metrics参数指定对应指标项即可 - 需要导出可视化结果用nvvp分析时,加
--output-profile conv_prof.nvvp即可,导出的文件和C++程序采集的结果格式完全一致,可以直接打开分析。
采集结果里你要找的2D卷积对应内核,一般名称带cudnn::convolution相关标识,很容易和其他内存拷贝、初始化类的内核区分开。
- 加
常见踩坑提示
- 必须保证你使用的nvprof版本,和PyTorch编译时绑定的CUDA大版本完全一致,版本不匹配会出现采集不到内核、程序崩溃的问题,可以通过
nvprof --version和torch.version.cuda分别查看两边版本做比对。 - 采集前先确认你的PyTorch是GPU版本,运行代码前先打印
torch.cuda.is_available()确认返回True,CPU版本的PyTorch根本不会发射CUDA内核,自然拿不到任何结果。 - 安培架构及更新的GPU需要CUDA 11.0及以上版本自带的nvprof才能正常识别,老版本CUDA带的nvprof不支持新GPU硬件。
- 采集时不要额外设置
CUDA_LAUNCH_BLOCKING=1环境变量,这个环境变量会强制所有内核发射时同步,会改变内核运行的真实时序,导致耗时统计失真。
内容的提问来源于stack exchange,提问作者binaryBigInt
相关产品推荐
相关产品推荐

