目录

故障 排除

请注意,本节中的信息可能会在 PyTorch/XLA 软件的未来版本中删除。 因为它们中的许多是给定的内部实现所特有的,这可能会发生变化。

健全性检查

在执行任何深入调试之前,我们希望对已安装的 PyTorch/XLA 进行健全性检查。

检查 PyTorch/XLA 版本

PyTorch 和 PyTorch/XLA 版本应匹配。查看我们的 README 以获取有关可用版本的更多详细信息。

vm:~$ python
>>> import torch
>>> import torch_xla
>>> print(torch.__version__)
2.1.0+cu121
>>> print(torch_xla.__version__)
2.1.0

执行简单计算

vm:~$ export PJRT_DEVICE=TPU
vm:~$ python3
>>> import torch
>>> import torch_xla.core.xla_model as xm
>>> t1 = torch.tensor(100, device=xm.xla_device())
>>> t2 = torch.tensor(200, device=xm.xla_device())
>>> print(t1 + t2)
tensor(300, device='xla:0')

使用虚构数据运行 Resnet

每晚

vm:~$ git clone https://github.com/pytorch/xla.git
vm:~$ python xla/test/test_train_mp_imagenet.py --fake_data

对于 release version ,您希望使用 branch .例如,如果您安装了 2.1 版本,您应该执行x.yrx.y

vm:~$ git clone --branch r2.1 https://github.com/pytorch/xla.git
vm:~$ python xla/test/test_train_mp_imagenet.py --fake_data

如果您能让 resnet 运行,我们可以得出结论,torch_xla 安装正确。

性能调试

要诊断性能问题,我们可以使用 PyTorch/XLA 提供的执行指标和计数器。当模型运行缓慢时,首先要检查的是生成指标报告。

指标报告在诊断问题方面非常有帮助。请尝试将其包含在您的 bug 中 如果您有报告,请发送给我们。

PyTorch/XLA 调试工具

您可以通过设置 来启用 PyTorch/XLA 调试工具,它提供了一些有用的调试功能。您还可以降低 debug 级别 to 以滑移执行分析。PT_XLA_DEBUG_LEVEL=21

执行自动指标分析

调试工具将分析指标报告并提供摘要。一些示例输出是

pt-xla-profiler: CompileTime too frequent: 21 counts during 11 steps
pt-xla-profiler: TransferFromDeviceTime too frequent: 11 counts during 11 steps
pt-xla-profiler: Op(s) not lowered: aten::_ctc_loss, aten::_ctc_loss_backward,  Please open a GitHub issue with the above op lowering requests.
pt-xla-profiler: CompileTime too frequent: 23 counts during 12 steps
pt-xla-profiler: TransferFromDeviceTime too frequent: 12 counts during 12 steps

编译和执行分析

调试工具将分析模型的每次编译和执行。一些示例输出是

Compilation Analysis: ================================================================================
Compilation Analysis: Compilation Cause
Compilation Analysis:   mark_step in parallel loader at step end
Compilation Analysis: Graph Info:
Compilation Analysis:   Graph Hash: c74c3b91b855b2b123f833b0d5f86943
Compilation Analysis:   Number of Graph Inputs: 35
Compilation Analysis:   Number of Graph Outputs: 107
Compilation Analysis: Python Frame Triggered Execution:
Compilation Analysis:   mark_step (/workspaces/dk3/pytorch/xla/torch_xla/core/xla_model.py:1055)
Compilation Analysis:   next (/workspaces/dk3/pytorch/xla/torch_xla/distributed/parallel_loader.py:44)
Compilation Analysis:   __next__ (/workspaces/dk3/pytorch/xla/torch_xla/distributed/parallel_loader.py:32)
Compilation Analysis:   train_loop_fn (/workspaces/dk3/pytorch/xla/examples/train_decoder_only_base.py:48)
Compilation Analysis:   start_training (/workspaces/dk3/pytorch/xla/examples/train_decoder_only_base.py:65)
Compilation Analysis:   <module> (/workspaces/dk3/pytorch/xla/examples/train_decoder_only_base.py:73)
Compilation Analysis: --------------------------------------------------------------------------------
Compilation Analysis: ================================================================================

Post Compilation Analysis: ================================================================================
Post Compilation Analysis: Graph input size: 1.548000 GB
Post Compilation Analysis: Graph output size: 7.922460 GB
Post Compilation Analysis: Aliased Input size: 1.547871 GB
Post Compilation Analysis: Intermediate tensor size: 12.124478 GB
Post Compilation Analysis: Compiled program size: 0.028210 GB
Post Compilation Analysis: --------------------------------------------------------------------------------
Post Compilation Analysis: ================================================================================

Execution Analysis: ================================================================================
Execution Analysis: Execution Cause
Execution Analysis:   mark_step in parallel loader at step end
Execution Analysis: Graph Info:
Execution Analysis:   Graph Hash: c74c3b91b855b2b123f833b0d5f86943
Execution Analysis:   Number of Graph Inputs: 35
Execution Analysis:   Number of Graph Outputs: 107
Execution Analysis: Python Frame Triggered Execution:
Execution Analysis:   mark_step (/workspaces/dk3/pytorch/xla/torch_xla/core/xla_model.py:1055)
Execution Analysis:   next (/workspaces/dk3/pytorch/xla/torch_xla/distributed/parallel_loader.py:44)
Execution Analysis:   __next__ (/workspaces/dk3/pytorch/xla/torch_xla/distributed/parallel_loader.py:32)
Execution Analysis:   train_loop_fn (/workspaces/dk3/pytorch/xla/examples/train_decoder_only_base.py:48)
Execution Analysis:   start_training (/workspaces/dk3/pytorch/xla/examples/train_decoder_only_base.py:65)
Execution Analysis:   <module> (/workspaces/dk3/pytorch/xla/examples/train_decoder_only_base.py:73)
Execution Analysis: --------------------------------------------------------------------------------
Execution Analysis: ================================================================================

编译/执行的一些常见原因是

  1. 用户手动调用 。mark_step

  2. 每个 x (可配置) 批次的并行加载器调用。mark_step

  3. 退出分析器 StepTrace 区域

  4. Dynamo 决定编译/执行图形。

  5. 用户尝试访问(通常是由于日志记录)张量的值。mark_step

由 1-4 引起的执行是意料之中的,我们希望通过降低访问 tensor 值的频率或在访问前手动添加 a 来避免 5。mark_step

用户应该会在前几个步骤中看到此 + 对。模型稳定后,用户应该只看到(您可以通过以下方式禁用执行分析)。为了有效地使用 PyTorch/XLA,我们希望每个步骤都运行相同的模型代码,并且每个图形只编译一次。如果您一直看到 ,则应尝试按照本节转储 IR/HLO,并比较每个步骤的图表并了解差异的来源。Compilation CauseExecutation CauseExecution CausePT_XLA_DEBUG_LEVEL=1Compilation Cause

以下部分将介绍如何获取和理解更详细的量度报告。

获取指标报告

将以下行放入程序中以生成报告:

import torch_xla.debug.metrics as met

# For short report that only contains a few key metrics.
print(met.short_metrics_report())
# For full report that includes all metrics.
print(met.metrics_report())

了解指标报告

该报告包括以下内容:

  • 我们发布 XLA 汇编的时间和发布所花费的时间。

  • 我们执行的次数和执行所花费的时间

  • 我们创建/销毁了多少个设备数据句柄等。

此信息以样本的百分位数报告。例如:

Metric: CompileTime
  TotalSamples: 202
  Counter: 06m09s401ms746.001us
  ValueRate: 778ms572.062us / second
  Rate: 0.425201 / second
  Percentiles: 1%=001ms32.778us; 5%=001ms61.283us; 10%=001ms79.236us; 20%=001ms110.973us; 50%=001ms228.773us; 80%=001ms339.183us; 90%=001ms434.305us; 95%=002ms921.063us; 99%=21s102ms853.173us

我们还提供计数器,这些计数器是跟踪内部软件状态的整数变量。例如:

Counter: CachedSyncTensors
  Value: 395

在此报告中,任何以 开头的计数器都表示 XLA 设备和 CPU 之间的上下文切换,可以是 模型代码中的潜在性能优化区域。aten::

计数器有助于了解哪些作路由回 PyTorch 的 CPU 引擎。 它们的 C++ 命名空间是完全限定的:

Counter: aten::nonzero
  Value: 33

如果您看到 ops 不是 和 ,这通常意味着缺少 在 PyTorch/XLA 中降低。欢迎在 GitHub 问题上打开功能请求。aten::nonzero_local_scalar_dense

清除 Metrics 报告

如果要清除步骤/纪元之间的量度,可以使用

import torch_xla.debug.metrics as met

met.clear_all()

PyTorch/XLA + Dynamo 调试工具

您可以通过设置 来启用 PyTorch/XLA + Dynamo 调试工具。XLA_DYNAMO_DEBUG=1

性能分析

要深入分析您的工作负载以了解瓶颈,请查看以下资源:

简单基准测试

查看 ''examples/train_resnet_benchmark.py' <https://github.com/pytorch/xla/blob/master/examples/train_resnet_benchmark.py>'_ 了解如何对 PyTorch/XLA 模型进行基准测试。

已知性能注意事项

PyTorch/XLA在语义上的行为与常规PyTorch类似,而XLA张量与CPU和GPU张量共享完整的张量接口。 但是,XLA/hardware 中的约束和惰性评估模型表明某些模式可能会导致性能不佳。

如果您的模型显示性能不佳,请记住以下注意事项:

  1. XLA/TPU 的重新编译次数过多,性能会下降。

    XLA 编译成本高昂。PyTorch/XLA 在每次遇到新形状时都会自动重新编译图形。 通常,模型应该在几个步骤内稳定下来,并且您可以看到其余训练的速度有了巨大的提升。

    为了避免重新编译,不仅形状必须恒定,而且所有主机中 XLA 设备之间的计算也应该是恒定的。

    可能的来源

    • 直接或间接使用 introduce dynamic shapes;例如,掩码索引其中 是掩码张量。nonzerobase[index]index

    • 步骤之间迭代次数不同的循环可能会导致不同的执行图,因此需要重新编译。

    解决方案

    • Tensor 形状在迭代之间应相同,或者应使用少量的形状变化。

    • 尽可能将张量填充到固定大小。

  2. 某些作没有 XLA 的本机翻译。

    对于这些作,PyTorch/XLA 会自动传输到 CPU 内存,在 CPU 上进行评估,并将结果传输回 XLA 设备。 在训练步骤中执行过多此类作可能会导致速度明显变慢。

    可能的来源

    • 该作显式要求评估结果。除非必要,否则不要使用它。item()

    解决方案

    • 对于大多数作,我们可以将它们降低到 XLA 来修复它。查看指标报告部分以查找缺少的作并在 GitHub 上打开功能请求。

    • 即使 PyTorch 张量称为标量,也请避免使用 .将其保留为 Tensor 并对其使用 Tensor作。tensor.item()

    • 用于替换控制流(如果适用)。 例如,在 clip_grad*norm* 中使用的控制流是有问题的,并且会影响性能,因此我们通过调用 (call) 来修补,这给我们带来了显著的性能提升。 ..代码块:: Pythontorch.whereitem()clip_grad_norm_torch.where

      … 还:

      device = parameters[0].device total_norm = torch.zeros([], device=device if parameters else None) 对于 P in 参数:

      param_norm = p.grad.data.norm(norm_type) ** norm_type total_norm.add_(param_norm)

      total_norm = (total_norm ** (1. / norm_type))

      clip_coef = torch.tensor(max_norm, device=device) / (total_norm + 1e-6) 对于 P in 参数:

      p.grad.data.mul_(torch.where(clip_coef < 1, clip_coef, torch.tensor(1., device=device)))

  3. ''torch_xla.distributed.data_parallel'' 中的迭代器可能会删除输入迭代器中的最后几批。

    这是为了确保我们在所有 XLA 设备上执行相同的工作量。

    解决方案

    • 当 dataset 较小且步骤太少时,这可能会导致无作 epoch。因此,最好使用 在这些情况下,批量较小。

XLA 张量怪癖

  1. XLA 张量内部是不透明的。XLA 张量似乎始终为 连续且无存储。网络不应尝试检查步幅 的 XLA 张量。

  2. 在保存 XLA 张量之前,应将其移动到 CPU。储蓄 XLA 张量直接导致它们被重新加载回原来的设备上 保存自。如果设备在加载时不可用,则加载将失败。 在保存 XLA 张量之前将其移动到 CPU 可让您决定哪个 device(s) 来放置加载的张量。如果您想 在没有 XLA 设备的计算机上加载张量。应小心 但是,在保存 XLA 张量之前,将其移动到 CPU 中,作为移动 跨设备类型的 Tensors 不会保留视图关系。相反 加载张量后,应根据需要重建视图。

  3. 使用 Python 的 copy.copy 复制 XLA 张量将返回深层副本,而不是 浅拷贝。使用 XLA 张量的视图获取它的浅表副本。

  4. 处理共享权重。模块可以通过设置 一个模块到另一个模块的参数。这种模块权重的 “捆绑” 应该 在将模块移动到 XLA 设备完成。否则为 2 将在 XLA 设备上创建共享张量的独立副本。

更多调试工具

我们不希望用户使用本节中的工具来调试他们的模型。但我们可能会要求 它们,因为它们提供了指标报告的其他信息 没有。

  • print(torch_xla._XLAC._get_xla_tensors_text([res]))其中 是 tensor 打印出 IR 的结果。res

  • print(torch_xla._XLAC._get_xla_tensors_hlo([res]))其中 是结果张量打印出生成的 XLA HLO。res

请注意,这些函数必须在 之前调用,否则张量将已经物化。mark_step()

环境变量

还有许多环境变量控制 PyTorch/XLA 软件堆栈的行为。

设置此类变量将导致不同程度的性能下降,因此它们应该 仅启用调试。

  • XLA_IR_DEBUG:允许在创建 IR 节点时捕获 Python 堆栈跟踪, 因此,可以了解哪个 PyTorch作负责生成 IR。

  • XLA_HLO_DEBUG:启用在_XLA_IR DEBUG 处于活动状态时捕获的 Python 堆栈帧, 传播到 XLA HLO 元数据。

  • XLA_SAVE_TENSORS_FILE:将用于转储 IR 图的文件路径 执行。请注意,如果该选项处于启用状态并且 PyTorch 程序长时间运行,则文件可能会变得非常大。图表将附加到文件中,因此要有一个干净的 sheet 时,应显式删除该文件。

  • XLA_SAVE_TENSORS_FMT:存储在 _XLA_SAVE_TENSORSFILE 文件中的图表的格式。可以是(默认)、(Graphviz 格式)或 .textdothlo

  • XLA_FLAGS=--xla_dump_to:如果设置为 ,XLA 编译器将在每次编译时转储未优化和优化的 HLO。=/tmp/dir_name

  • XLA_METRICS_FILE:如果设置,则为内部量度所在的本地文件的路径 每一步都节省了。如果已存在,则 Metrics 将附加到文件中。

  • XLA_SAVE_HLO_FILE:如果设置,则为本地文件的路径,其中,在编译/执行的情况下 错误,将保存有问题的 HLO 图。

  • XLA_SYNC_WAIT:强制 XLA 张量同步作等待其完成,然后 进入下一步。

  • XLA_USE_EAGER_DEBUG_MODE:强制 XLA 张量急切执行,这意味着编译并执行 torch作 1 由 1 个。这对于绕过较长的编译时间很有用,但总体单步时间会慢得多,内存使用率会更高 因为所有编译器 optimizaiton 都将被跳过。

  • TF_CPP_LOG_THREAD_ID:如果设置为 1,则 TF 日志将显示线程 ID 帮助调试多线程进程。

  • TF_CPP_VMODULE:用于 TF VLOG 的环境变量,并采用 的形式。请注意,对于 VLOG,您必须设置 .TF_CPP_VMODULE=name=value,...TF_CPP_MIN_LOG_LEVEL=0

  • TF_CPP_MIN_LOG_LEVEL:打印消息的级别。 将转动 在 INFO 日志记录、WARNING 等上。我们的 PyTorch/XLA 默认使用 level,因此要查看设置的 VLOG。TF_CPP_MIN_LOG_LEVEL=0TF_CPP_MIN_LOG_LEVEL=1TF_VLOGtensorflow::INFOTF_CPP_MIN_LOG_LEVEL=0

  • XLA_DUMP_HLO_GRAPH:如果设置为在出现编译或执行错误的情况下, 有问题的 HLO 图将作为 引发的运行时错误的一部分转储。=1xla_util.cc

常见的调试环境变量组合

  • 以 IR 格式记录图形执行

    XLA_IR_DEBUG=1 XLA_HLO_DEBUG=1 XLA_SAVE_TENSORS_FMT="text" XLA_SAVE_TENSORS_FILE="/tmp/save1.ir"
    
  • 以 HLO 格式记录图形执行

    XLA_IR_DEBUG=1 XLA_HLO_DEBUG=1 XLA_SAVE_TENSORS_FMT="hlo" XLA_SAVE_TENSORS_FILE="/tmp/save1.hlo"
    
  • 显示用于运行时和图形编译/执行的调试 VLOG

    TF_CPP_MIN_LOG_LEVEL=0 TF_CPP_VMODULE="xla_graph_executor=5,pjrt_computation_client=3"
    

重现 PyTorch/XLA CI/CD 单元测试失败。

您可能会看到 PR 的一些测试失败,例如:

To execute this test, run the following from the base repo dir:
    PYTORCH_TEST_WITH_SLOW=1 python ../test/test_torch.py -k test_put_xla_uint8

直接在命令行中运行此命令不起作用。您需要将环境变量设置为本地 .例如:TORCH_TEST_DEVICESpytorch/xla/test/pytorch_test_base.py

TORCH_TEST_DEVICES=/path/to/pytorch/xla/test/pytorch_test_base.py PYTORCH_TEST_WITH_SLOW=1 python ../test/test_torch.py -k test_put_xla_uint8应该有效。

文档

访问 PyTorch 的全面开发人员文档

查看文档

教程

获取面向初学者和高级开发人员的深入教程

查看教程

资源

查找开发资源并解答您的问题

查看资源