概述

介绍 PyTorch 2.0,这是我们迈向下一代 PyTorch 2 系列发布的初步步骤。在过去的几年里,我们从 PyTorch 1.0 创新迭代到最新的 1.13 版本,并加入了新成立的 PyTorch 基金会,该基金会是 Linux 基金会的一部分。

除了我们出色的社区之外,PyTorch 最大的优势在于我们继续作为一流的 Python 集成,命令式风格,API 的简洁性和选项。PyTorch 2.0 提供了相同的急切模式开发和用户体验,同时在底层编译器级别对 PyTorch 的操作进行了根本性的改变和增强。我们能够提供更快的性能和对动态形状和分布式支持。

下面您将找到所有您需要了解 PyTorch 2.0 是什么,它将走向何方以及更重要的是如何今天开始(例如,教程、要求、模型、常见问题解答)的信息。还有很多东西要学习和开发,但我们期待社区的反馈和贡献,以使 2 系列变得更好,并感谢所有使 1 系列如此成功的人。

PyTorch 2.x:更快、更 Pythonic,动态性一如既往

今天,我们宣布 torch.compile ,这是一个将 PyTorch 性能提升到新高度并开始将 PyTorch 的部分从 C++重新带回 Python 的功能。我们相信这是 PyTorch 的一个重大新方向——因此我们称之为 2.0。 torch.compile 是一个完全可添加(且可选)的功能,因此 2.0 在定义上 100%向后兼容。

torch.compile 的底层是新技术——TorchDynamo、AOTAutograd、PrimTorch 和 TorchInductor。

  • TorchDynamo 使用 Python 帧评估钩子安全地捕获 PyTorch 程序,这是 5 年研发投入的结果,是一项重大的创新,它实现了安全图捕获。

  • AOTAutograd 作为跟踪自动微分重载了 PyTorch 的 autograd 引擎,用于生成提前生成的反向跟踪。

  • PrimTorch 将超过 2000 个 PyTorch 算子归约到约 250 个基本算子的封闭集合中,开发者可以针对这些算子构建完整的 PyTorch 后端。这大大降低了编写 PyTorch 功能或后端的门槛。
  • TorchInductor 是一个深度学习编译器,为多个加速器和后端生成快速代码。对于 NVIDIA 和 AMD GPU,它使用 OpenAI Triton 作为关键构建块。

TorchDynamo、AOTAutograd、PrimTorch 和 TorchInductor 是用 Python 编写的,支持动态形状(即发送不同大小的张量而无需重新编译的能力),这使得它们灵活、易于修改,降低了开发者和供应商的入门门槛。

为了验证这些技术,我们在各个机器学习领域使用了 163 个开源模型。我们精心构建了这个基准,包括图像分类、目标检测、图像生成、各种 NLP 任务,如语言模型、问答、序列分类、推荐系统和强化学习。我们将基准分为三个类别:

  • HuggingFace Transformers 模型库中的 46 个模型
  • TIMM 模型库:由 Ross Wightman 收集的 61 个最先进的 PyTorch 图像模型
  • TorchBench 模型库:来自 GitHub 各地的 56 个流行代码库精选集

我们不对这些开源模型进行修改,除非添加一个包装它们的 torch.compile 调用。

我们随后对这些模型进行加速测试并验证其准确性。由于加速可能依赖于数据类型,我们在 float32 和自动混合精度(AMP)上进行了加速测试。我们报告了加权平均加速为 0.75 * AMP + 0.25 * float32,因为我们发现 AMP 在实际应用中更为常见。

在这 163 个开源模型中, torch.compile 在 93%的时间内工作,模型在 NVIDIA A100 GPU 上的训练速度提高了 43%。在 Float32 精度下,平均运行速度快 21%,在 AMP 精度下,平均运行速度快 51%。

注意事项:在桌面级 GPU(如 NVIDIA 3090)上,我们测量到的加速低于服务器级 GPU(如 A100)。截至今天,我们的默认后端 TorchInductor 支持 CPU 和 NVIDIA Volta 和 Ampere GPU。它(目前)不支持其他 GPU、xPUs 或较老的 NVIDIA GPU。

在 NVIDIA A100 GPU 上,torch.compile 与 eager 模式相比的加速

尝试一下: torch.compile 目前处于开发初期。从今天开始,您可以在 nightly 的二进制文件中尝试 torch.compile 。我们预计将在 2023 年 3 月初发布第一个稳定的 2.0 版本。

在 PyTorch 2.x 的路线图中,我们希望将编译模式在性能和可扩展性方面进一步推进。其中一些工作正在进行中,正如我们在今天的会议上所讨论的那样。还有一些工作尚未开始。还有一些工作是我们希望看到的,但我们自己没有足够的时间和资源去做。如果您有兴趣贡献,请在这个月的“工程师问答:2.0 直播问答系列”中与我们交流(详情见文章末尾)或通过 Github / 论坛。

用户评价

以下是 PyTorch 用户对我们新方向的看法:

Sylvain Gugger 是 HuggingFace transformers 的主要维护者:

“只需添加一行代码,PyTorch 2.0 就能在训练 Transformers 模型时提供 1.5 倍到 2 倍的速度提升。这是自混合精度训练引入以来最令人兴奋的事情!”

Ross Wightman 是 TIMM(PyTorch 生态系统中最大的视觉模型中心之一)的主要维护者:

“它可以直接与大多数 TIMM 模型配合进行推理和训练工作负载,无需修改任何代码。”

Luca Antiga,Lightning AI 的 CTO,同时也是 PyTorch Lightning 的主要维护者之一

PyTorch 2.0 体现了深度学习框架的未来。无需用户干预即可捕获 PyTorch 程序,并实现开箱即用的设备端速度提升和程序操作,这为 AI 开发者开辟了一个全新的维度。

动机

我们对 PyTorch 的哲学一直是将灵活性和可修改性作为首要任务,性能紧随其后。我们努力实现:

  1. 高性能的即时执行
  2. Pythonic 内部机制
  3. 分布式、自动微分、数据加载、加速器等良好的抽象

自从 2017 年我们推出 PyTorch 以来,硬件加速器(如 GPU)在计算速度上提高了约 15 倍,在内存访问速度上提高了约 2 倍。为了保持急切执行的高性能,我们不得不将 PyTorch 内部的大量部分移入 C++。将内部结构移入 C++使得它们更难以修改,并增加了代码贡献的门槛。

从一开始,我们就知道急切执行的性能限制。2017 年 7 月,我们开始了第一个针对 PyTorch 编译器的研究项目。这个编译器需要使 PyTorch 程序运行得更快,但不能以牺牲 PyTorch 体验为代价。我们的关键标准是保留某些类型的灵活性——支持动态形状和动态程序,研究人员在探索的各个阶段都会使用这些。

技术概述

几年来,我们在 PyTorch 中构建了多个编译器项目。让我们将编译器分解为三个部分:

  • 图获取
  • 图降低
  • 图编译

在构建 PyTorch 编译器时,图获取是更具挑战性的难题。

在过去 5 年里,我们构建了 torch.jit.trace ,TorchScript,FX 跟踪,Lazy Tensors。但它们都没有给我们带来我们想要的一切。有些很灵活但不够快,有些很快但不够灵活,有些既不快也不灵活。有些用户体验不佳(比如静默错误)。虽然 TorchScript 很有前景,但它需要对您的代码以及您的代码所依赖的代码进行大量修改。这种对代码的大量修改使得它对许多 PyTorch 用户来说难以接受。

PyTorch 编译过程

TorchDynamo:可靠且快速地获取图

今年早些时候,我们开始着手开发 TorchDynamo,这是一种利用 PEP-0523 中引入的 CPython 特性——帧评估 API 的方法。我们采用数据驱动的方法来验证其在图捕获方面的有效性。我们使用了超过 7,000 个用 PyTorch 编写的 GitHub 项目作为我们的验证集。在 TorchScript 和其他方法连获取图都只有 50%的成功率,并且通常伴随着很大的开销时,TorchDynamo 能够以 99%的成功率正确、安全地获取图,且开销可忽略不计——无需对原始代码进行任何修改。这时,我们知道我们终于突破了多年来在灵活性和速度方面所面临的障碍。

TorchInductor:使用定义-by-运行 IR 进行快速代码生成

为 PyTorch 2.0 开发的新编译器后端,我们受到了用户编写高性能自定义内核方式的启发:越来越多地使用 Triton 语言。我们还希望有一个与 PyTorch eager 类似的抽象,并且足够通用,以支持 PyTorch 中广泛的功能。TorchInductor 使用 Pythonic 的 define-by-run 循环级 IR,自动将 PyTorch 模型映射到在 GPU 上生成的 Triton 代码以及在 CPU 上的 C++/OpenMP。TorchInductor 的核心循环级 IR 仅包含约 50 个运算符,并且是用 Python 实现的,这使得它易于修改和扩展。

AOTAutograd:重用 Autograd 进行编译时图

对于 PyTorch 2.0,我们知道我们想要加速训练。因此,我们不仅要捕获用户级别的代码,还要捕获反向传播。此外,我们知道我们想要重用现有的经过实战考验的 PyTorch autograd 系统。AOTAutograd 利用 PyTorch 的 torch_dispatch 可扩展机制,通过我们的 Autograd 引擎进行跟踪,使我们能够“提前”捕获反向传播。这使我们能够使用 TorchInductor 加速正向和反向传播。

PrimTorch:稳定的原始运算符

为 PyTorch 编写后端具有挑战性。PyTorch 有 1200 多个运算符,如果考虑每个运算符的各种重载,则超过 2000 个。

2000 多个 PyTorch 运算符的分解

因此,编写后端或跨切面功能变成了一项耗时的任务。在 PrimTorch 项目中,我们正在努力定义更小、更稳定的操作集。PyTorch 程序可以持续地降低到这些操作集。我们的目标是定义两个操作集:

  • Prim ops 包含大约 ~250 个操作符,属于较低级别。这些操作符适合编译器,因为它们足够低级,需要将它们重新融合在一起才能获得良好的性能。
  • ATen ops 包含大约 ~750 个规范操作符,适合直接导出。这些操作符适合已经集成在 ATen 层级的后端或不会通过编译从较低级别的操作集(如 Prim ops)中恢复性能的后端。

我们将在下面的开发者/供应商体验部分进一步讨论这个话题。

用户体验

我们引入一个简单的函数 torch.compile ,它包装您的模型并返回一个编译后的模型。

compiled_model = torch.compile(model)

compiled_model 持有对您的模型的引用,并将 forward 函数编译为一个更优化的版本。在编译模型时,我们提供了一些旋钮来调整它:

def torch.compile(model: Callable,
  *,
  mode: Optional[str] = "default",
  dynamic: bool = False,
  fullgraph:bool = False,
  backend: Union[str, Callable] = "inductor",
  # advanced backend options go here as kwargs
  **kwargs
) -> torch._dynamo.NNOptimizedModule
  • mode 指定编译器在编译时应该优化什么。

    • 默认模式是一个预设,旨在高效编译,同时不会花费太多时间编译或使用额外内存。
    • 其他模式如 reduce-overhead 可以大幅减少框架开销,但会消耗少量额外内存。 max-autotune 编译时间较长,试图生成尽可能快的代码。
  • dynamic 指定是否启用 Dynamic Shapes 的代码路径。某些编译器优化无法应用于动态形状的程序。明确您是否希望编译程序具有动态形状或静态形状,将有助于编译器为您提供更好的优化代码。
  • fullgraph 类似于 Numba 的 nopython 。它将整个程序编译成单个图或给出错误解释为什么无法这样做。大多数用户不需要使用此模式。如果您非常关注性能,那么您可以尝试使用它。
  • 后端指定要使用哪个编译器后端。默认情况下使用 TorchInductor,但还有其他几个可供选择。

编译体验旨在在默认模式下提供最大化的好处和灵活性。以下是每个模式下的心理模型。

现在,让我们来看一个编译真实模型并运行它的完整示例(使用随机数据)。

import torch
import torchvision.models as models

model = models.resnet18().cuda()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
compiled_model = torch.compile(model)

x = torch.randn(16, 3, 224, 224).cuda()
optimizer.zero_grad()
out = compiled_model(x)
out.sum().backward()
optimizer.step()

第一次运行 compiled_model(x) 时,会编译模型。因此,运行时间较长。后续运行则很快。

模式

编译器有一些预设,可以以不同的方式调整编译后的模型。你可能正在运行一个由于框架开销而运行缓慢的小型模型。或者,你可能正在运行一个几乎无法装入内存的大型模型。根据你的需求,你可能需要使用不同的模式。

# API NOT FINAL
# default: optimizes for large models, low compile-time
#          and no extra memory usage
torch.compile(model)

# reduce-overhead: optimizes to reduce the framework overhead
#                and uses some extra memory. Helps speed up small models
torch.compile(model, mode="reduce-overhead")

# max-autotune: optimizes to produce the fastest model,
#               but takes a very long time to compile
torch.compile(model, mode="max-autotune")

读取和更新属性

访问模型属性的方式与急切模式相同。你可以像通常那样访问或修改模型的属性(如 model.conv1.weight )。这在代码修正方面是完全安全可靠的。TorchDynamo 会在代码中插入守卫来检查其假设是否成立。如果属性以某种方式发生变化,那么 TorchDynamo 就会知道需要自动重新编译。

# optimized_model works similar to model, feel free to access its attributes and modify them
optimized_model.conv1.weight.fill_(0.01)

# this change is reflected in model

钩子

目前模块和 Tensor 钩子还不能完全工作,但最终随着开发完成将能正常工作。

序列化

您可以将 optimized_model 的 state-dict 进行序列化,或者 model 。它们指向相同的参数和状态,因此是等效的。

torch.save(optimized_model.state_dict(), "foo.pt")
# both these lines of code do the same thing
torch.save(model.state_dict(), "foo.pt")

目前您不能序列化 optimized_model 。如果您想直接保存对象,请保存 model

torch.save(optimized_model, "foo.pt") # Error
torch.save(model, "foo.pt")           # Works

推理与导出

对于模型推理,在通过 torch.compile 生成编译后的模型后,运行一些预热步骤再进行实际模型服务。这有助于减轻初始服务期间的延迟峰值。

此外,我们将引入一个名为 torch.export 的模式,该模式会仔细导出整个模型和守护基础设施,以满足需要保证和可预测延迟的环境。 torch.export 可能需要对您的程序进行修改,尤其是如果您有数据相关的控制流。

# API Not Final
exported_model = torch._dynamo.export(model, input)
torch.save(exported_model, "foo.pt")

这处于开发初期阶段。请关注 PyTorch 会议上的“导出路径”演讲,以获取更多详细信息。您还可以从本月开始参与我们的“工程师问答:2.0 直播问答系列”讨论此话题(更多详情请见本文末尾)。

调试问题

编译模式是透明的,难以调试。您可能会有以下问题:

  • 为什么我的程序在编译模式下会崩溃?
  • 编译模式与急切模式一样准确吗?
  • 为什么我没有看到速度提升?

如果编译模式产生错误或崩溃,或者与急切模式(超出机器精度限制)的结果不一致,那么这很可能不是你的代码错误。然而,了解导致错误的代码片段是有用的。

为了帮助调试和可重现性,我们创建了几个工具和日志功能,其中之一脱颖而出:Minifier(最小化器)。

最小化器会自动将您遇到的问题简化为一个小代码片段。这个小代码片段可以重现原始问题,您可以带着这个最小化后的代码向 GitHub 提交问题。这将帮助 PyTorch 团队轻松快速地修复问题。

如果您没有看到预期的加速效果,那么我们有一个 torch._dynamo.explain 工具,它可以解释您的代码中哪些部分导致了所谓的“图断开”。图断开通常阻碍编译器加速代码,减少图断开的数量可能会加快您的代码运行速度(直到某些递减回报的极限)。

您可以在我们的故障排除指南中了解这些内容以及更多。

动态形状

在考虑支持 PyTorch 代码的通用性时,一个关键要求是支持动态形状,并允许模型接受不同大小的张量,而无需在形状每次更改时重新编译。

截至 today,对 Dynamic Shapes 的支持有限,目前正处于快速开发中。它将在稳定版本中具备全部功能。它受制于 dynamic=True 参数,我们在 symbolic-shapes 特性分支上取得了更多进展,在该分支上我们成功运行了 BERT_pytorch 进行训练,并使用 TorchInductor 实现了完整的符号形状。对于动态形状的推理,我们覆盖面更广。例如,让我们看看动态形状有帮助的常见设置 - 文本生成与语言模型。

我们可以看到,即使形状从 4 动态变化到 256,编译模式也能持续优于 eager 模式高达 40%。在没有动态形状支持的情况下,一个常见的解决方案是将数据填充到最接近的 2 的幂。然而,正如下面的图表所示,这会带来大量的性能开销,并且也会导致编译时间显著增加。此外,填充有时并不简单。

通过在 PyTorch 2.0 的编译模式下支持动态形状,我们可以获得最佳的性能和易用性。

当前工作进展非常迅速,我们可能暂时让一些模型退步,以便我们为基础设施实施根本性的改进。关于我们动态形状进展的最新更新,请在此处查看。

分布式

总结来说,torch.distributed 的两个主要分布式包装器在编译模式下运行良好。

两者 DistributedDataParallel (DDP)和 FullyShardedDataParallel (FSDP)都以编译模式工作,相对于急切模式,提供了改进的性能和内存利用率,但有一些注意事项和限制。

加速 AMP 精度
左侧:编译模式下的 FSDP 相对于急切模式(AMP 精度)的速度提升。
右侧:编译模式下的 FSDP 比急切模式占用内存少得多。

分布式数据并行(DDP)

DDP 依赖于与反向计算重叠的 AllReduce 通信,并将较小的每层 AllReduce 操作分组到“桶”中以实现更高的效率。TorchDynamo 编译的 AOTAutograd 函数,在与 DDP 天真地结合时,会防止通信重叠,但通过为每个“桶”编译单独的子图并允许通信操作在子图之外和之间发生,可以恢复性能。编译模式下的 DDP 支持目前还要求 static_graph=False 。有关 DDP + TorchDynamo 的方法和结果的更多详细信息,请参阅此帖子。

FullyShardedDataParallel (FSDP)

FSDP 本身是一个“beta”版本的 PyTorch 功能,由于可以调整要包装的子模块,并且通常有更多的配置选项,因此其系统复杂度比 DDP 高。如果配置了 use_original_params=True 标志,FSDP 可以与 TorchDynamo 和 TorchInductor 一起用于各种流行的模型。目前可能会出现一些特定模型或配置的兼容性问题,但将会积极改进,如果提交 github 问题,可以优先考虑特定模型。

用户指定一个 auto_wrap_policy 参数来指示要包装在一起用于状态分片的模型子模块,或者手动在 FSDP 实例中包装子模块。例如,许多 Transformer 模型在将每个“Transformer 块”分别包装在单独的 FSDP 实例中时表现良好,因此只需要在某一时刻物化一个 Transformer 块的完整状态。Dynamo 将在每个 FSDP 实例的边界插入图断点,以便在正向(和反向)传播中发生通信操作,并在图外并行于计算操作。

如果在没有将子模块封装在单独的实例中时使用 FSDP,它将回退到类似于 DDP 的操作方式,但没有桶化。因此,所有梯度在一个操作中减少,即使在 Eager 中也无法实现计算/通信重叠。此配置仅针对功能与 TorchDynamo 进行了测试,但未针对性能进行测试。

开发者/供应商体验

在 PyTorch 2.0 中,我们希望简化后端(编译器)集成体验。为此,我们专注于减少操作符的数量并简化启动 PyTorch 后端所需的操作符集的语义。

以图形形式,PT2 堆栈看起来如下:

从图表中间开始,AOTAutograd 以预编译的方式动态捕获自动微分逻辑,以 FX 图格式生成前向和反向算子的图。

我们提供了一套经过强化的分解(即用其他算子编写的算子实现),可以用来减少后端需要实现的算子数量。我们还通过一个称为函数化的过程,选择性地重写复杂的 PyTorch 逻辑,包括突变和视图,简化 PyTorch 算子的语义,并保证算子元数据信息,如形状传播公式。这项工作正在进行中;我们的目标是提供一个原始且稳定的约 250 个算子集合,具有简化的语义,称为 PrimTorch,供厂商利用(即选择加入)以简化他们的集成。
在减少和简化算子集之后,后端可以选择在 Dynamo(即中间层,紧接在 AOTAutograd 之后)或 Inductor(底层)中进行集成。以下描述了做出这种选择的考虑因素,以及关于后端混合的未来工作。

Dynamo 后端

具有现有编译器堆栈的供应商可能发现将其集成为 TorchDynamo 后端最为简便,因为它们将以 ATen/Prims IR 的形式接收 FX Graph。请注意,对于训练和推理,集成点将直接位于 AOTAutograd 之后,因为我们目前将分解作为 AOTAutograd 的一部分来应用,如果针对推理,则仅跳过特定于反向传播的步骤。

传感器后端

供应商还可以直接将他们的后端集成到 Inductor 中。Inductor 接收由 AOTAutograd 生成的图,该图由 ATen/Prim 操作组成,并将其进一步降低到循环级 IR。今天,Inductor 为其循环级 IR 提供了点操作、归约、scatter/gather 和窗口操作的降低。此外,Inductor 创建融合组,进行索引简化、维度折叠,并调整循环迭代顺序以支持高效的代码生成。供应商可以通过提供从循环级 IR 到特定硬件代码的映射来实现集成。目前,Inductor 有两个后端:(1)C++生成多线程 CPU 代码,(2)Triton 生成高性能 GPU 代码。这些 Inductor 后端可以作为替代后端灵感的来源。

后端混合接口(即将推出)

我们已经为将 FX 图分割成包含后端支持的子图以及执行剩余部分提供了实用工具。这些实用工具可以扩展以支持“混合后端”,配置图中的哪些部分在哪个后端上运行。然而,目前还没有稳定的接口或协议供后端暴露其操作符支持、操作符模式的偏好等。这仍然是正在进行中的工作,我们欢迎早期用户的反馈。

总结

我们对 PyTorch 2.0 及其以后的路线感到非常兴奋。通往最终 2.0 发布的道路将会崎岖,但请尽早加入我们的旅程。如果您有兴趣深入了解或为编译器做出贡献,请继续阅读以下内容,包括如何开始(例如教程、基准、模型、常见问题解答)以及本月的“工程师问答:2.0 Live Q&A 系列”。其他资源包括:

使用 PyTorch 2.0 加速 Hugging Face 和 TIMM 模型

作者:马克·萨拉菲姆

torch.compile() 使您能够轻松尝试不同的编译器后端,通过单行装饰器 torch.compile() 来使 PyTorch 代码更快。它可以直接作为 torch.jit.script() 的替代品应用于 nn.Module,而无需对源代码进行任何修改。我们预计这一行代码更改将为您在大多数模型上提供 30%-2 倍的训练时间加速。

opt_module = torch.compile(module)

torch.compile 支持任意 PyTorch 代码、控制流、突变,并附带对动态形状的实验性支持。我们对这一发展感到非常兴奋,因此将其称为 PyTorch 2.0。

对于我们来说,这个公告的不同之处在于,我们已经对一些最受欢迎的开源 PyTorch 模型进行了基准测试,并获得了从 30% 到 2 倍的显著加速。https://github.com/pytorch/torchdynamo/issues/681。

这里没有技巧,我们已通过 pip 安装了流行的库,如 https://github.com/huggingface/transformers、https://github.com/huggingface/accelerate 和 https://github.com/rwightman/pytorch-image-models,然后对它们运行了 torch.compile(),就这样了。

同时获得性能和便利性是罕见的,这就是为什么核心团队对 PyTorch 2.0 如此兴奋的原因。

要求

对于 GPU(新一代 GPU 将看到显著更好的性能)

pip3 install numpy --pre torch --force-reinstall --index-url https://download.pytorch.org/whl/nightly/cu117

对于 CPU

pip3 install --pre torch --index-url https://download.pytorch.org/whl/nightly/cpu

可选:验证安装

git clone https://github.com/pytorch/pytorch
cd tools/dynamo
python verify_dynamo.py

可选:Docker 安装

我们还在 PyTorch 夜间构建中提供了所有必需的依赖项,您可以通过以下方式下载:

docker pull ghcr.io/pytorch/pytorch-nightly

对于临时实验,请确保您的容器可以访问所有 GPU

docker run --gpus all -it ghcr.io/pytorch/pytorch-nightly:latest /bin/bash

开始使用

请阅读马克·萨拉菲姆的完整博客文章,他在其中为您介绍教程和真实模型,让您今天就能尝试 PyTorch 2.0。

我们使用 PyTorch 的目标是构建一个广度优先的编译器,以加快人们在开源中运行的绝大多数实际模型的速度。Hugging Face Hub 最终成为我们极具价值的基准测试工具,确保我们进行的任何优化实际上有助于加速人们想要运行的模型。

博客教程将向您展示如何精确复制这些加速,让您像我们一样对 PyTorch 2.0 充满期待。所以请尝试使用 PyTorch 2.0,享受免费的性能提升,如果您没有看到效果,请打开一个 issue,我们将确保您的模型得到支持 https://github.com/pytorch/torchdynamo/issues

毕竟,除非您的模型实际上运行得更快,否则我们无法声称我们创建了一个广度优先。

常见问题解答

  1. PT 2.0 是什么?
    2.0 是 PyTorch 的最新版本。PyTorch 2.0 提供了相同的 eager-mode 开发体验,同时通过 torch.compile 添加了编译模式。这种编译模式有可能在训练和推理过程中加速您的模型。

  2. 为什么是 2.0 而不是 1.14?
    PyTorch 2.0 就是 1.14 本应成为的样子。我们发布了大量新特性,我们认为这些特性将改变您有意义地使用 PyTorch 的方式,因此我们将其命名为 2.0。

  3. 我该如何安装 2.0?需要额外的要求吗?

    安装最新夜间版本:

    CUDA 11.8

     pip3 install numpy --pre torch torchvision torchaudio --force-reinstall --index-url https://download.pytorch.org/whl/nightly/cu118
    

    CUDA 11.7

     pip3 install numpy --pre torch torchvision torchaudio --force-reinstall --index-url https://download.pytorch.org/whl/nightly/cu117
    

    CPU

     pip3 install numpy --pre torch torchvision torchaudio --force-reinstall --index-url https://download.pytorch.org/whl/nightly/cpu
    
  4. 2.0 代码与 1.X 版本向后兼容吗?
    是的,使用 2.0 不需要修改您的 PyTorch 工作流程。一行代码 model = torch.compile(model) 可以将您的模型优化为使用 2.0 堆栈,并与其他 PyTorch 代码平滑运行。这是完全可选的,您不需要使用新的编译器。

  5. 2.0 默认启用吗?
    2.0 是发布版的名称。torch.compile 是 2.0 版本中发布的特性,您需要显式使用 torch.compile。

  6. 如何将我的 PT1.X 代码迁移到 PT2.0?
    您的代码应该无需迁移即可正常工作。如果您想使用 2.0 版本中引入的新编译模式特性,可以从优化您的模型开始,只需一行代码: model = torch.compile(model)
    虽然速度提升主要在训练过程中观察到,但如果您的模型在 eager 模式运行更快,您也可以用于推理。
     import torch
          
     def train(model, dataloader):
       model = torch.compile(model)
       for batch in dataloader:
         run_epoch(model, batch)
    
     def infer(model, input):
       model = torch.compile(model)
       return model(\*\*input)
    
  7. 为什么我应该使用 PT2.0 而不是 PT 1.X?
    请参阅问题(2)的答案。

  8. 当运行 PyTorch 2.0 时,我的代码与 PyTorch 1.x 有什么不同之处?
    默认情况下,PyTorch 2.0 与 PyTorch 1.x 相同,即您的模型在 eager-mode 模式下运行,即每行 Python 代码依次执行。
    在 2.0 版本中,如果您将模型用 model = torch.compile(model) 包裹,模型在执行前会经过 3 个步骤:
    1. 图获取:首先将模型重写为子图块。可以被 TorchDynamo 编译的子图会被“展平”,而包含控制流代码或其他不受支持的 Python 结构的子图将回退到 Eager-Mode。
    2. 图降低:将所有 PyTorch 操作分解为特定于所选后端的构成内核。
    3. 图编译,其中内核调用它们对应的低级设备特定操作。
  9. PT2.0 新增了哪些新组件?
    • TorchDynamo 从 Python 字节码生成 FX 图。它使用守卫来维护 eager 模式的功能,以确保生成的图是有效的(了解更多)
    • AOTAutograd 用于生成与 TorchDynamo 捕获的前向图相对应的逆向图(了解更多)。
    • PrimTorch 将复杂的 PyTorch 操作分解成更简单、更基本的操作(了解更多)。
    • [后端] 后端与 TorchDynamo 集成,将图编译成可在加速器上运行的 IR。例如,TorchInductor 将图编译为用于 GPU 执行的 Triton 或用于 CPU 执行的 OpenMP(了解更多)。
  10. 2.0 版本目前支持哪些编译器后端?
    默认且最完整的后端是 TorchInductor,但 TorchDynamo 有一个不断增长的后端列表,可以通过调用 torchdynamo.list_backends() 来找到。

  11. 分布式训练在 2.0 中是如何工作的?
    编译模式下,DDP 和 FSDP 可以比 Eager-Mode 快 15%,在 AMP 精度下可以快 80%。PT2.0 进行了一些额外的优化,以确保 DDP 的通信-计算重叠与 Dynamo 的局部图创建良好配合。请确保使用 DDP 时 static_graph=False。更多详情请见此处。

  12. 我该如何了解 PT2.0 的发展情况?
    PyTorch 开发者论坛是直接从构建它们的开发者那里了解 2.0 组件的最佳地方。

  13. 帮帮我,我的代码在 2.0 的编译模式下运行变慢了!
    性能下降的最可能原因是图形断开太多。例如,在模型前向中的打印语句这样的无害操作也会触发图形断开。我们有一些方法可以诊断这些问题——更多信息请在此处查看。

  14. 我之前运行的代码在 2.0 的编译模式下崩溃了!我该如何调试它?
    这里有一些技术可以帮助您诊断代码可能失败的地方,并打印出有用的日志:https://maskerprc.github.io/docs/stable/torch.compiler_faq.html#why-is-my-code-crashing。

工程师问答:2.0 直播问答系列

我们将为社区举办一系列现场问答环节,让大家与专家进行更深入的提问和对话。请随时查看全年主题的完整日历。如果您无法参加:1)它们将被录制供将来观看;2)您可以参加我们每周五上午 10 点太平洋标准时间(PST)的 Dev Infra Office Hours,详情请访问 https://github.com/pytorch/pytorch/wiki/Dev-Infra-Office-Hours。

请点击此处查看日期、时间、描述和链接。

声明:请在加入现场会议和提交问题时,不要分享您的个人信息、姓氏、公司。

TOPIC HOST
使用 2.0 的新开发者体验(安装、设置、克隆示例、使用 2.0 运行) 苏拉吉·苏布拉马尼亚
领英 | 推特
PT2 性能分析和调试 贝特·马赫
领英 | 推特
深入探讨 TorchInductor 和 PT 2.0 后端集成 吉梅尔申娜,包斌,黄雪瑞
吉梅尔申娜
领英

黄 Sherlock
领英
无需 C++ 和 functorch 扩展 PyTorch:为 PyTorch 提供类似 JAX 的可组合函数转换 安贾利·乔尔迪亚和萨曼莎·安德奥
安贾利·乔尔迪亚
领英 | 推特

萨曼莎·安德鲁
领英 | 推特
TorchDynamo 深度解析 米哈伊尔·沃兹涅先斯基
领英
重新思考使用 TorchData 加载数据:Datapipes 和 Dataloader2 凯文·蔡
领英
可组合训练(+ torcheval,torchsnapshot) 安南特·苏布拉曼尼亚
如何以及为什么为 PyTorch 贡献代码和教程 赞因·里兹维、斯维特拉娜·卡尔斯利奥古卢和卡尔·帕克
赞因·里兹维
领英 | 推特

斯维特拉娜·卡尔什利奥古卢
领英 | 推特
动态形状和计算最大批次大小 杨德昌和伊利亚斯·埃利森
杨德昌
推特
PyTorch 2.0 导出:为 PyTorch 捕获完整图音 苏宇和曹艳南
曹艳南
领英
使用 DistributedTensor 和 PyTorch DistributedTensor 的 2-D 并行性 梁旺超和阿利松·古萨蒂·阿佐利尼
梁万超
领英 | 推特

阿利松·古萨蒂·阿佐利尼
领英
TorchRec 和 FSDP 在生产中的应用 Dennis van der Staay, Andrew Gu 和 Rohan Varma
Dennis van der Staay
领英
Rohan Varma
领英 | 推特
PyTorch 设备上的未来 拉齐尔·阿尔瓦雷斯·格瓦拉
领英 | 推特
Torch 多模态
沉浸式翻译博客
扩展博客
卡特卡伊·汗德尔瓦尔
领英 | 推特
BetterTransformers(+与 Hugging Face 的集成)、模型服务与优化
博客 1
Github
哈米德·肖贾纳泽里和马克·萨拉菲姆
马克·萨拉菲姆
领英 | 推特
PT2 和分布式 威尔·康斯特布尔
领英

查看 PyTorch 会议的演讲