如何在 pytorch 训练中优化 cudaHostAlloc 和 cudaLaunchKernel 时间

Nag*_*S N 7 profiler deep-learning pytorch

我正在尝试使用 pytorch profiler 来分析我的模型。我使用下面的代码来分析

with profile(activities=[ProfilerActivity.CPU, ProfilerActivity.CUDA], record_shapes=True) as prof:
    with record_function("model_inference"):
        output_batch = self.model(input_batch)
print(prof.key_averages().table(sort_by="cpu_time_total", row_limit=10))
Run Code Online (Sandbox Code Playgroud)

分析器输出如下

-------------------------------------------------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  
                                                   Name    Self CPU %      Self CPU   CPU total %     CPU total  CPU time avg     Self CUDA   Self CUDA %    CUDA total  CUDA time avg    # of Calls  
-------------------------------------------------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  
                                        model_inference         3.17%      83.011ms        63.97%        1.675s        1.675s       0.000us         0.00%     373.844ms     373.844ms             1  
                                            aten::copy_         0.24%       6.333ms        39.93%        1.046s       1.504ms      28.758ms         7.69%      29.035ms      41.777us           695  
                                          cudaHostAlloc        36.02%     943.053ms        36.02%     943.053ms      30.421ms       0.000us         0.00%       0.000us       0.000us            31  
                                       cudaLaunchKernel        35.93%     940.773ms        35.93%     940.773ms      86.619us       0.000us         0.00%       0.000us       0.000us         10861  
                                           aten::repeat         0.04%     979.000us        33.77%     884.170ms      30.489ms       0.000us         0.00%     204.000us       7.034us            29  
                                           aten::conv2d         0.06%       1.481ms         8.71%     228.183ms     695.680us       0.000us         0.00%     145.688ms     444.171us           328  
                                      aten::convolution         0.05%       1.391ms         8.66%     226.702ms     691.165us       0.000us         0.00%     145.688ms     444.171us           328  
                                     aten::_convolution         0.10%       2.742ms         8.61%     225.311ms     686.924us       0.000us         0.00%     145.688ms     444.171us           328  
                                aten::cudnn_convolution         0.53%      13.803ms         8.33%     218.051ms     664.790us     137.822ms        36.87%     137.822ms     420.189us           328  
                                               cudaFree         7.46%     195.373ms         7.46%     195.373ms      48.843ms       0.000us         0.00%       0.000us       0.000us             4  
-------------------------------------------------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  ------------  
Self CPU time total: 2.618s
Self CUDA time total: 373.844ms
Run Code Online (Sandbox Code Playgroud)

我注意到很大一部分时间(自CPU)被cudaHostAlloc和占用cudaLaunchKernelcudaHostAlloc这些和是什么cudaLaunchKernel?是否可以减少这个时间?如果是的话怎么办?我是否遗漏了任何标准操作,从而导致了如此高的时间消耗?

PS:我对分析还很陌生。如果需要任何其他信息,请告诉我。

小智 1

我不是专家,但我认为 cudaLaunchKernel 在使用 cuda 完成的每个操作中都会被调用。所以我认为你无法优化它。

如果您绘制详细的跟踪https://pytorch.org/tutorials/recipes/recipes/profiler_recipe.html#using-tracing-functionity,您会发现每次您对线性层执行 cuda 操作时都会调用它。

分析器追踪

关于分析器输出的一点说明:aten::copy_ cudaHostAlloc cudaLaunchKernel所有aten::repeat这些都大约占用 CPU 总时间的 40%。ProfilerActivity.CUDA我认为这可能与记录 CUDA 操作有关,但它也会在分析的第一个 CUDA 操作上增加大量CPU 时间。就我而言,一个简单的操作torch.ones(1000, device="cuda")占用了整整一秒的 CPU 时间,因为这是第一个 cuda 操作。

这可能是您的情况的问题,尝试删除andProfilerActivity.CUDA也许会有更小的 CPU 时间并且会从表中消失。aten::copy_ cudaHostAlloc cudaLaunchKernelaten::repeat