Accelerate 文档

性能分析器

Hugging Face's logo
加入 Hugging Face 社区

并获取增强的文档体验

开始使用

性能分析器

性能分析器是一个工具,允许在训练和推理期间收集性能指标。性能分析器的上下文管理器 API 可用于更好地理解哪些模型运算符最耗费资源,检查它们的输入形状和堆栈跟踪,研究设备内核活动,并可视化执行跟踪。它提供了关于模型性能的深入了解,使你能够优化和改进模型。

本指南解释了如何使用 PyTorch 性能分析器来测量模型运算符的时间和内存消耗,以及如何将其与 Accelerate 集成。我们将涵盖各种用例,并为每个用例提供示例。

使用性能分析器分析执行时间

性能分析器允许检查在用性能分析器上下文管理器包装的代码范围内调用了哪些运算符。

让我们看看如何使用性能分析器来分析执行时间

PyTorch
Accelerate
import torch
import torchvision.models as models
from torch.profiler import profile, record_function, ProfilerActivity

model = models.resnet18()
inputs = torch.randn(5, 3, 224, 224)

with profile(activities=[ProfilerActivity.CPU], record_shapes=True) as prof:
    model(inputs)

print(prof.key_averages().table(sort_by="cpu_time_total", row_limit=10))

生成的表格输出(省略了一些列)

---------------------------------  ------------  ------------  ------------  ------------  
                             Name      Self CPU     CPU total  CPU time avg    # of Calls  
---------------------------------  ------------  ------------  ------------  ------------  
                     aten::conv2d     171.000us      52.260ms       2.613ms            20  
                aten::convolution     227.000us      52.089ms       2.604ms            20  
               aten::_convolution     270.000us      51.862ms       2.593ms            20  
         aten::mkldnn_convolution      51.273ms      51.592ms       2.580ms            20  
                 aten::batch_norm     118.000us       7.059ms     352.950us            20  
     aten::_batch_norm_impl_index     315.000us       6.941ms     347.050us            20  
          aten::native_batch_norm       6.305ms       6.599ms     329.950us            20  
                 aten::max_pool2d      40.000us       4.008ms       4.008ms             1  
    aten::max_pool2d_with_indices       3.968ms       3.968ms       3.968ms             1  
                       aten::add_     780.000us     780.000us      27.857us            28  
---------------------------------  ------------  ------------  ------------  ------------  
Self CPU time total: 67.016ms

要获得更精细的结果粒度并包含运算符输入形状,请传递 group_by_input_shape=True(注意:这需要使用 record_shapes=True 运行性能分析器)

print(prof.key_averages(group_by_input_shape=True).table(sort_by="cpu_time_total", row_limit=10))

使用性能分析器分析内存消耗

性能分析器还可以显示在模型运算符执行期间分配(或释放)的内存量(由模型的张量使用)。要启用内存性能分析功能,请传递 profile_memory=True

PyTorch
Accelerate
model = models.resnet18()
inputs = torch.randn(5, 3, 224, 224)

with profile(activities=[ProfilerActivity.CPU],
        profile_memory=True, record_shapes=True) as prof:
    model(inputs)

print(prof.key_averages().table(sort_by="self_cpu_memory_usage", row_limit=10))

生成的表格输出(省略了一些列)

---------------------------------  ------------  ------------  ------------  
                             Name       CPU Mem  Self CPU Mem    # of Calls  
---------------------------------  ------------  ------------  ------------  
                      aten::empty      94.85 Mb      94.85 Mb           205  
    aten::max_pool2d_with_indices      11.48 Mb      11.48 Mb             1  
                      aten::addmm      19.53 Kb      19.53 Kb             1  
                       aten::mean      10.00 Kb      10.00 Kb             1  
              aten::empty_strided         492 b         492 b             5  
                        aten::cat         240 b         240 b             6  
                        aten::abs         480 b         240 b             4  
              aten::masked_select         120 b         112 b             1  
                         aten::ne          61 b          53 b             3  
                         aten::eq          30 b          30 b             1  
---------------------------------  ------------  ------------  ------------  
Self CPU time total: 69.332ms

导出 Chrome 跟踪

你可以在 Chrome 跟踪查看器 (chrome://tracing) 中检查分析的运算符和 CUDA 内核的序列

profile_export

PyTorch
Accelerate
model = models.resnet18().cuda()
inputs = torch.randn(5, 3, 224, 224).cuda()

with profile(activities=[ProfilerActivity.CPU, ProfilerActivity.CUDA]) as prof:
    model(inputs)

prof.export_chrome_trace("trace.json")

使用性能分析器分析长时间运行的作业

性能分析器提供了一个额外的 API 来处理长时间运行的作业(例如训练循环)。跟踪所有执行过程可能很慢,并导致非常大的跟踪文件。为了避免这种情况,请使用可选参数

  • schedule_option:调度选项允许你控制性能分析何时处于活动状态。这对于长时间运行的作业很有用,以避免收集过多数据。可用的键是 waitwarmupactiverepeatskip_first。性能分析器将跳过前 skip_first 步,然后等待 wait 步,然后为接下来的 warmup 步进行预热,然后为接下来的 active 步进行活动记录,然后重复循环,从 wait 步开始。可选的循环次数由 repeat 参数指定,零值表示循环将持续到性能分析完成。
  • on_trace_ready:指定一个函数,该函数将性能分析器的引用作为输入,并在每次新跟踪准备就绪时由性能分析器调用。

为了说明 API 的工作原理,请考虑以下示例

PyTorch
Accelerate
from torch.profiler import schedule

my_schedule = schedule(
    skip_first=1,
    wait=5,
    warmup=1,
    active=3,
    repeat=2
)

def trace_handler(p):
    output = p.key_averages().table(sort_by="self_cuda_time_total", row_limit=10)
    print(output)
    p.export_chrome_trace("/tmp/trace_" + str(p.step_num) + ".json")

with profile(
    activities=[ProfilerActivity.CPU, ProfilerActivity.CUDA],
    schedule=my_schedule,
    on_trace_ready=trace_handler
) as p:
    for idx in range(8):
        model(inputs)
        p.step()

FLOPS

使用公式估算特定运算符(矩阵乘法和 2D 卷积)的 FLOPs(浮点运算)。

要测量浮点运算 (FLOPS)

PyTorch
Accelerate
with profile(
    activities=[ProfilerActivity.CPU, ProfilerActivity.CUDA],
    with_flops=True
) as prof:
    model(inputs)

print(prof.key_averages().table(sort_by="flops", row_limit=10))

生成的表格输出(省略了一些列)

-------------------------------------------------------  ------------  ------------  ------------  
                                                   Name      Self CPU     Self CUDA    Total FLOPs  
-------------------------------------------------------  ------------  ------------  ------------  
                                           aten::conv2d     197.000us       0.000us  18135613440.000  
                                            aten::addmm     103.000us      17.000us     5120000.000  
                                              aten::mul      29.000us       2.000us          30.000  
                                      aten::convolution     409.000us       0.000us            --  
                                     aten::_convolution     253.000us       0.000us            --  
                                aten::cudnn_convolution       5.465ms       2.970ms            --  
                                        cudaEventRecord     138.000us       0.000us            --  
                                  cudaStreamIsCapturing      43.000us       0.000us            --  
                                  cudaStreamGetPriority      40.000us       0.000us            --  
                       cudaDeviceGetStreamPriorityRange      10.000us       0.000us            --  
-------------------------------------------------------  ------------  ------------  ------------  
Self CPU time total: 21.938ms
Self CUDA time total: 4.165ms

结论与更多信息

PyTorch 性能分析器是一个强大的工具,用于分析模型性能。通过将其与 Accelerate 集成,你可以轻松地分析你的模型并深入了解其性能,从而帮助你优化和改进它们。

有关更多详细信息,请参阅 PyTorch 性能分析器文档

< > GitHub 上更新