使用 Intel® VTune™ Profiler 的 ITT API 分析 PyTorch 工作负载#
创建日期:2022 年 10 月 27 日 | 最后更新:2024 年 10 月 24 日 | 最后验证:未经验证
在本实践中,您将学习
什么是 Intel® VTune™ Profiler
什么是仪器和跟踪技术 (ITT) API
如何在 Intel® VTune™ Profiler 中可视化 PyTorch 模型层次结构
一个简短的示例代码,展示了如何使用 PyTorch ITT API
要求#
PyTorch 1.13 或更高版本
Intel® VTune™ Profiler
PyTorch 的安装说明可在 pytorch.org 上找到。
什么是 Intel® VTune™ Profiler#
Intel® VTune™ Profiler 是一款用于串行和多线程应用程序的性能分析工具。对于熟悉 Intel 架构的用户,Intel® VTune™ Profiler 提供了一套丰富的指标,帮助用户了解应用程序在 Intel 平台上的执行情况,从而找出性能瓶颈所在。
更详细的信息,包括入门指南,可在 Intel 网站上获取。
什么是仪器和跟踪技术 (ITT) API#
Intel® VTune™ Profiler 提供的仪器和跟踪技术 API (ITT API) 允许目标应用程序在其执行期间生成和控制跟踪数据的收集。
ITT 功能的优势在于,可以在 Intel® VTune™ Profiler GUI 上标记单个 PyTorch 运算符以及自定义区域的时间跨度。当用户发现任何异常时,这对于定位行为异常的运算符非常有帮助。
注意
ITT API 自 1.13 版本起已集成到 PyTorch 中。用户无需调用原始的 ITT C/C++ API,只需调用 PyTorch 中的 Python API。更详细的信息可以在 PyTorch 文档中找到。
如何在 Intel® VTune™ Profiler 中可视化 PyTorch 模型层次结构#
PyTorch 提供了两种使用方式:
隐式调用:默认情况下,当启用该功能时,所有遵循 PyTorch 运算符注册机制注册的运算符都将由 ITT 功能自动标记。
显式调用:如果需要自定义标记,用户可以显式调用 PyTorch 文档中提到的 API 来标记所需的范围。
要启用显式调用,应在 torch.autograd.profiler.emit_itt() 范围下调用期望被标记的代码。例如:
with torch.autograd.profiler.emit_itt():
<code-to-be-profiled...>
启动 Intel® VTune™ Profiler#
要验证此功能,您需要启动一个 Intel® VTune™ Profiler 实例。请查阅 Intel® VTune™ Profiler 用户指南以了解启动 Intel® VTune™ Profiler 的步骤。
注意
用户还可以通过遵循 Intel® VTune™ Profiler Web Server UI 指南使用 web-server-ui,例如:vtune-backend –web-port=8080 –allow-remote-access –enable-server-profiling
一旦启动了 Intel® VTune™ Profiler GUI,您应该会看到如下所示的用户界面:

在左侧导航栏的 sample (matrix) 项目下有三个示例结果。如果您不希望分析结果出现在此默认的示例项目中,可以通过“New Project…”按钮在蓝色的“Configure Analysis…”按钮下方创建一个新项目。要开始新的分析,请单击蓝色的“Configure Analysis…”按钮以开始分析的配置。
配置 CPU 分析#
单击“Configure Analysis…”按钮后,您应该会看到如下屏幕:

窗口的右侧分为三部分:“WHERE”(左上角)、“WHAT”(左下角)和“HOW”(右侧)。在“WHERE”中,您可以指定要在其上运行分析的机器。在“WHAT”中,您可以设置要分析的应用程序的路径。要分析 PyTorch 脚本,建议将所有手动步骤(包括激活 Python 环境和设置必需的环境变量)包装到一个 bash 脚本中,然后分析此 bash 脚本。在上图的截图中,我们将所有步骤包装到 launch.sh bash 脚本中,并使用参数 `
配置 XPU 分析#
选择 GPU Offload Profiling Type 而不是 Hotspots,并遵循与 CPU 相同的说明来启动应用程序。

读取分析结果#
成功使用 ITT 进行分析后,您可以打开分析结果的“Platform”选项卡,在 Intel® VTune™ Profiler 时间线上查看标记。

时间线显示顶部的 python 线程为主线程,下方的为各个 OpenMP 线程。标记的 PyTorch 运算符和自定义区域显示在主线程行中。所有以 aten:: 开头的运算符都是 PyTorch 中 ITT 功能隐式标记的运算符。标签 iteration_N 是通过特定 API torch.profiler.itt.range_push()、torch.profiler.itt.range_pop() 或 torch.profiler.itt.range() 范围显式标记的。请参阅下一节的示例代码了解详情。
注意
以 convolution 和 reorder 标记的红色框来自 Intel® oneAPI Deep Neural Network Library (oneDNN)。
正如右侧导航栏所示,时间线行中的棕色部分显示了每个线程的 CPU 使用情况。线程行中棕色部分所占的高度百分比在某个时间戳上,与该时间戳下该线程的 CPU 使用率对齐。因此,从这个时间线可以直观地理解以下几点:
每个线程的 CPU 核心利用率如何。
所有线程的 CPU 核心利用率如何。所有线程的 CPU 使用率是否良好?
OpenMP 线程的同步情况如何。OpenMP 线程启动或完成时是否存在抖动?
当然,Intel® VTune™ Profiler 提供了更多丰富的分析功能,可以帮助您理解性能问题。当您了解性能问题的根本原因后,就可以修复它。更详细的使用说明可以在 Intel® VTune™ Profiler 用户指南中找到。
读取 XPU 分析结果#
成功使用 ITT 进行分析后,您可以打开分析结果的“Platform”选项卡,在 Intel® VTune™ Profiler 时间线上查看标记。

时间线显示顶部的 python 线程为主线程。标记的 PyTorch 运算符和自定义区域显示在主线程行中。所有以 aten:: 开头的运算符都是 PyTorch 中 ITT 功能隐式标记的运算符。时间线还显示顶部的 GPU 计算队列,用户可以看到不同的 XPU Kernels 被分派到 GPU 队列中。
一个简短的示例代码,展示了如何使用 PyTorch ITT API#
下面的示例代码是在上面截图中用于分析的脚本。
拓扑由两个运算符组成:Conv2d 和 Linear。执行了三次推理。每次推理都通过 PyTorch ITT API 标记为文本字符串 iteration_N。成对的 torch.profile.itt.range_push 和 torch.profile.itt.range_pop 或 torch.profile.itt.range 范围实现了自定义标记功能。
# sample.py
import torch
import torch.nn as nn
class ITTSample(nn.Module):
def __init__(self):
super(ITTSample, self).__init__()
self.conv = nn.Conv2d(3, 5, 3)
self.linear = nn.Linear(292820, 1000)
def forward(self, x):
x = self.conv(x)
x = x.view(x.shape[0], -1)
x = self.linear(x)
return x
def main():
m = ITTSample
# unmark below code for XPU
# m = m.to("xpu")
x = torch.rand(10, 3, 244, 244)
# unmark below code for XPU
# x = x.to("xpu")
with torch.autograd.profiler.emit_itt():
for i in range(3)
# Labeling a region with pair of range_push and range_pop
#torch.profiler.itt.range_push(f'iteration_{i}')
#m(x)
#torch.profiler.itt.range_pop()
# Labeling a region with range scope
with torch.profiler.itt.range(f'iteration_{i}'):
m(x)
if __name__ == '__main__':
main()
下面显示了在 Intel® VTune™ Profiler GUI 截图中提到的包装所有手动步骤的 launch.sh bash 脚本。
# launch.sh
#!/bin/bash
# Retrieve the directory path where the path contains both the sample.py and launch.sh so that this bash script can be invoked from any directory
BASEFOLDER=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
<Activate a Python environment>
cd ${BASEFOLDER}
python sample.py