跳转到主要内容
博客

PyTorch Profiler 1.9 有何新功能?

作者: 2021 年 8 月 3 日2024 年 11 月 16 日暂无评论

PyTorch Profiler v1.9 已发布!此新版本(之前的 PyTorch Profiler 版本)的目标是为您提供最先进的新工具,帮助您诊断和修复机器学习性能问题,无论您是在一台还是多台机器上工作。目标是针对耗时和/或内存开销最大的执行步骤,并可视化 GPU 和 CPU 之间工作负载的分布。

以下是正在发布的五项主要功能的摘要:

  1. 分布式训练视图:这有助于您了解分布式训练作业消耗了多少时间和内存。当您将训练模型分解为并行运行的工作节点时,可能会出现许多问题,因为它可能是一个黑盒。总体模型目标是加快模型训练。此分布式训练视图将帮助您诊断和调试各个节点内的问题。
  2. 内存视图:此视图允许您更好地了解内存使用情况。该工具将通过在程序运行的各个点显示活动内存分配,帮助您避免臭名昭著的内存不足错误。
  3. GPU 利用率可视化:此工具可帮助您确保 GPU 得到充分利用。
  4. 云存储支持:Tensorboard 插件现在可以从 Azure Blob 存储、Amazon S3 和 Google Cloud Platform 读取分析数据。
  5. 跳转到源代码:此功能允许您可视化堆栈跟踪信息并直接跳转到源代码。这有助于您根据分析结果快速优化和迭代代码。

PyTorch 分析工具入门

PyTorch 包含一个名为“PyTorch Profiler”的分析功能。PyTorch Profiler 教程可在此处找到:此处

要为分析检测您的 PyTorch 代码,您必须

$ pip install torch-tb-profiler

import torch.profiler as profiler
With profiler.profile(XXXX)

评论:

• 有关 CUDA 和 CPU 分析,请参阅下方

with torch.profiler.profile( 
activities=[ 
torch.profiler.ProfilerActivity.CPU, 
torch.profiler.ProfilerActivity.CUDA], 

• 使用 profiler.record_function("$NAME"):允许为函数块放置装饰器(与名称关联的标签)

• profiler.profile 下的 profile_memory=True 参数允许您分析 CPU 和 GPU 内存占用

使用 PyTorch Profiler 可视化 PyTorch 模型性能

分布式训练

深度学习的最新进展强调了大型数据集和大型模型的价值,这要求您将模型训练扩展到更多的计算资源。分布式数据并行 (DDP) 和 NVIDIA 集合通信库 (NCCL) 是 PyTorch 中广泛采用的范式,用于加速您的深度学习训练。

在此版本的 PyTorch Profiler 中,现在支持带有 NCCL 后端的 DDP。

计算/通信概述

在分布式训练视图下的计算/通信概述中,您可以观察每个工作器和 [负载均衡器](https://en.wikipedia.org/wiki/Load_balancing_(computing) 节点之间的计算与通信比率,该比率以粒度衡量。

场景 1:

如果一个工作器的计算和重叠时间比其他工作器大得多,这可能表明工作负载平衡存在问题或工作器是滞后器。计算是 GPU 上的内核时间之和减去重叠时间。重叠时间是通过在计算期间交错通信来节省的时间。更多的重叠时间表示计算和通信之间更好的并行性。理想情况下,计算和通信完全相互重叠。通信是总通信时间减去重叠时间。下图显示了此场景在 Tensorboard 上的显示方式。

图:滞后器示例

场景 2:

如果批处理大小很小(即每个工作器的计算量较少)或者要传输的数据很大,则计算与通信的比率也可能很小,并且在分析器中表现为 GPU 利用率低和等待时间长。此计算/通信视图将允许您诊断代码,通过采用梯度累积来减少通信,或通过增加批处理大小来减少通信比例。DDP 通信时间取决于模型大小。批处理大小与模型大小无关。因此,增加批处理大小可能会使计算时间更长,并使计算与通信比率更大。

同步/通信概述

在同步/通信视图中,您可以观察通信效率。这是通过将步长减去计算和通信时间来完成的。同步时间是总通信时间中用于等待和与其他工作器同步的一部分。同步/通信视图包括初始化、数据加载器、CPU 计算等。从此视图可以得出诸如总通信中真正用于交换数据的比例是多少以及等待来自其他工作器的数据的空闲时间是多少等见解。

例如,如果存在低效的工作负载平衡或滞后问题,您将能够在此同步/通信视图中识别它。此视图将显示多个工作器的等待时间比其他工作器长。

上面的表格视图允许您查看每个节点中所有通信操作的详细统计信息。这使您可以看到调用了哪些操作类型、每个操作被调用了多少次、每个操作传输的数据大小是多少等。

内存视图:

此内存视图工具可帮助您了解模型中操作符的硬件资源消耗。了解操作符级别的时间和内存消耗使您能够解决性能瓶颈,进而使您的模型执行得更快。鉴于有限的 GPU 内存大小,优化内存使用可以

  1. 允许更大的模型,这可能在最终级别任务上更好地泛化。
  2. 允许更大的批处理大小。更大的批处理大小会增加训练速度。

分析器在分析器间隔期间记录所有内存分配。选择“设备”将允许您查看每个操作符在 GPU 端或主机端的内存使用情况。您必须启用 profile_memory=True 才能生成如下所示的内存数据:此处

With torch.profiler.profile(
Profiler_memory=True # this will take 1 – 2 minutes to complete. 
)

重要定义:

• “大小增加”显示所有分配字节的总和减去所有内存释放字节。

• “分配大小”显示所有分配字节的总和,不考虑内存释放。

• “自身”表示分配的内存不是来自任何子操作符,而是来自操作符本身。

时间轴上的 GPU 指标:

当一个或多个 GPU 未充分利用时,此功能将帮助您调试性能问题。理想情况下,您的程序应该具有高 GPU 利用率(目标是 100% GPU 利用率)、最小的 CPU 到 GPU 通信以及没有开销。

概述:概述页面突出显示了三个重要 GPU 使用指标在不同级别(即 GPU 利用率、估计 SM 效率和估计实现占用率)的结果。本质上,每个 GPU 都有一堆 SM,每个 SM 都有一堆可以并发执行一堆线程的 warp。Warps 执行一堆是因为数量取决于 GPU。但从高层次来看,此时间轴上的 GPU 指标工具允许您查看整个堆栈,这很有用。

如果 GPU 利用率结果较低,这表明您的模型中存在潜在瓶颈。常见原因:

• 内核并行度不足(即,批处理大小小)

• 在循环中调用的小内核。这意味着启动开销没有分摊。

• CPU 或 I/O 瓶颈导致 GPU 未收到足够的工作来保持繁忙。

查看概述页面的性能推荐部分,您将找到关于如何提高 GPU 利用率的潜在建议。在此示例中,GPU 利用率较低,因此性能推荐是增加批处理大小。根据性能推荐,将批处理大小从 4 增加到 32,GPU 利用率增加了 60.68%。

GPU 利用率:分析器中 GPU 引擎执行工作负载的步长间隔时间。利用率百分比越高越好。仅使用 GPU 利用率来诊断性能瓶颈的缺点是它太高级和粗糙。它无法告诉您有多少流多处理器正在使用。请注意,虽然此指标对于检测空闲时间段很有用,但高值并不表示 GPU 的有效利用,而仅表示它正在做任何事情。例如,一个单线程持续运行的内核将获得 100% 的 GPU 利用率。

估计流多处理器效率(Est. SM Efficiency)是一个更细粒度的指标,它表示在跟踪的任何点上正在使用的 SM 的百分比。此指标报告至少有一个活动 warp 在 SM 上并且那些处于停滞状态的时间百分比(NVIDIA 文档)。估计 SM 效率也有其局限性。例如,每个块只有一个线程的内核无法完全利用每个 SM。SM 效率不能告诉我们每个 SM 有多忙,只告诉我们它们正在做任何事情,其中可能包括在等待内存加载结果时停滞。为了保持 SM 繁忙,需要有足够数量的就绪 warp,以便在发生停滞时随时运行。

估计实现占用率(Est. Achieved Occupancy)比估计 SM 效率和 GPU 利用率在诊断性能问题方面更深一层。估计实现占用率表示每个 SM 可以同时有多少个活动 warp。拥有足够数量的活动 warp 通常是实现良好吞吐量的关键。与 GPU 利用率和 SM 效率不同,目标不是使此值尽可能高。根据经验,通过将此指标提高到 15% 及以上可以获得良好的吞吐量增益。但在某个时候,您将遇到收益递减。例如,如果该值已经达到 30%,则进一步的增益将是不确定的。此指标报告内核执行期间所有 warp 调度程序的平均值(NVIDIA 文档)。估计实现占用率值越大越好。

概述详情:Resnet50_batchsize4

概述详情:Resnet50_batchsize32

内核视图 内核具有“每个 SM 的块”和“估计实现占用率”,这是比较模型运行的绝佳工具。

每个 SM 的平均块数
每个 SM 的块数 = 此内核的块数 / 此 GPU 的 SM 数量。如果此数字小于 1,则表示 GPU 多处理器未充分利用。“每个 SM 的平均块数”是此内核名称所有运行的加权平均值,使用每次运行的持续时间作为权重。

平均估计实现占用率
估计实现占用率的定义如概述中所示。“平均估计实现占用率”是此内核名称所有运行的加权平均值,使用每次运行的持续时间作为权重。

跟踪视图 此跟踪视图显示了一个时间轴,显示了模型中操作符的持续时间以及哪个系统执行了该操作。此视图可以帮助您确定高消耗和长时间执行是否是由于输入或模型训练造成的。目前,此跟踪视图在时间轴上显示 GPU 利用率和估计 SM 效率。

GPU 利用率是独立计算的,并划分为多个 10 毫秒的桶。桶的 GPU 利用率值在时间轴上绘制,范围为 0-100%。在上面的示例中,“ProfilerStep5”期间线程 28022 繁忙时间的 GPU 利用率高于“Optimizer.step”期间的 GPU 利用率。您可以在此处放大以调查其原因。

从上面我们可以看到,前者的内核比后者的内核长。后者的内核执行时间太短,导致 GPU 利用率较低。

估计 SM 效率:每个内核都计算了一个 0-100% 之间的估计 SM 效率。例如,下面的内核只有 64 个块,而此 GPU 中的 SM 数量为 80。那么它的“估计 SM 效率”为 64/80,即 0.8。

云存储支持

运行 pip install tensorboard 后,要通过这些云提供商读取数据,您现在可以运行:

torch-tb-profiler[blob] 
torch-tb-profiler[gs] 
torch-tb-profiler[s3] 

pip install torch-tb-profiler[blob]pip install torch-tb-profiler[gs]pip install torch-tb-profiler[S3] 以便通过这些云提供商读取数据。有关更多信息,请参阅此 README

跳转到源代码:

将 TensorBoard 和 PyTorch Profiler 直接集成到 Visual Studio Code (VS Code) 中的一个巨大好处是能够直接从分析器堆栈跟踪跳转到源代码(文件和行)。VS Code Python 扩展现在支持 TensorBoard 集成

只有在 VS Code 中启动 Tensorboard 时,跳转到源代码才可用。如果分析时 with_stack=True,堆栈跟踪将出现在插件 UI 上。当您从 PyTorch Profiler 中单击堆栈跟踪时,VS Code 将自动并排打开相应的文件,并直接跳转到您感兴趣的代码行进行调试。这使您可以根据分析结果和建议快速对代码进行可操作的优化和更改。

Gify:使用 Visual Studio Code 插件 UI 跳转到源代码

有关如何优化批处理大小性能,请参阅此处的分步教程:此处。PyTorch Profiler 还与 PyTorch Lightning 集成,您只需使用 –trainer.profiler=pytorch 标志启动 Lightning 训练作业即可生成跟踪。

PyTorch Profiler 的下一步是什么?

您刚刚了解了 PyTorch Profiler 如何帮助优化模型。您现在可以通过 pip install torch-tb-profiler 尝试使用 Profiler 来优化您的 PyTorch 模型。

请期待未来此教程的进阶版本。我们也很高兴能继续为 PyTorch 用户带来最先进的工具,以提高 ML 性能。我们很乐意听取您的意见。请随时在此处提出问题:此处

有关 PyTorch Profiler 即将推出的新功能和令人兴奋的功能,请在 Twitter 上关注 @PyTorch,并在 pytorch.org 上查看我们。

致谢

作者要感谢以下个人对本文的贡献。来自 Facebook 的:Geeta Chauhan、Gisle Dankel、Woo Kim、Sam Farahzad 和 Mark Saroufim。来自微软的:AI 框架工程师(Teng Gao、Mike Guo 和 Yang Gu)、Guoliang Hua 和 Thuy Nguyen。