跳转到主要内容
博客

PyTorch 1.5 发布,新旧 API 更新,包括 C++ 前端 API 与 Python 的对等

作者: 2020 年 4 月 21 日2024 年 11 月 16 日暂无评论

今天,我们宣布 PyTorch 1.5 正式发布,同时发布了新的和更新的库。此版本包括几项主要的 API 新增和改进。PyTorch 现在包含对 C++ 前端的重大更新、用于计算机视觉模型的“通道优先”(channels last)内存格式,以及用于模型并行训练的分布式 RPC 框架的稳定版本。该版本还新增了用于 Hessian 矩阵和 Jacobian 矩阵的 autograd API,以及受 pybind 启发、允许创建自定义 C++ 类的 API。

您可以在此处找到详细的发布说明。

C++ 前端 API(稳定版)

C++ 前端 API 现在与 Python 对等,并且整体功能已移至“稳定”状态(以前标记为实验性)。主要亮点包括:

  • 现在,C++ `torch::nn` 模块/功能拥有约 100% 的覆盖率和文档,用户可以轻松地将模型从 Python API 转换为 C++ API,从而使模型编写体验更加流畅。
  • C++ 中的优化器曾与 Python 等效功能有所不同:C++ 优化器不能将参数组作为输入,而 Python 优化器可以。此外,`step` 函数的实现也不完全相同。在 1.5 版本中,C++ 优化器将始终与 Python 等效优化器保持相同的行为。
  • C++ 中缺少张量多维索引 API 是一个众所周知的问题,并在 PyTorch Github 问题跟踪器和论坛中引发了许多帖子。以前的解决方法是结合使用 `narrow` / `select` / `index_select` / `masked_select`,这与 Python API 优雅的 `tensor[:, 0, ..., mask]` 语法相比,笨拙且容易出错。在 1.5 版本中,用户可以使用 `tensor.index({Slice(), 0, "...", mask})` 来实现相同的目的。

用于计算机视觉模型的“通道优先”内存格式(实验性)

“通道优先”内存布局解锁了使用高性能卷积算法和硬件(NVIDIA 的 Tensor Cores、FBGEMM、QNNPACK)的能力。此外,它旨在自动通过运算符传播,从而可以轻松地在内存布局之间切换。

要了解有关如何编写内存格式感知运算符的更多信息,请访问此处

自定义 C++ 类(实验性)

此版本新增了一个 API,`torch::class_`,用于同时将自定义 C++ 类绑定到 TorchScript 和 Python。此 API 的语法与 pybind11 几乎相同。它允许用户将其 C++ 类及其方法公开给 TorchScript 类型系统和运行时系统,以便他们可以从 TorchScript 和 Python 实例化和操作任意 C++ 对象。一个 C++ 绑定示例:

template <class T>
struct MyStackClass : torch::CustomClassHolder {
  std::vector<T> stack_;
  MyStackClass(std::vector<T> init) : stack_(std::move(init)) {}

  void push(T x) {
    stack_.push_back(x);
  }
  T pop() {
    auto val = stack_.back();
    stack_.pop_back();
    return val;
  }
};

static auto testStack =
  torch::class_<MyStackClass<std::string>>("myclasses", "MyStackClass")
      .def(torch::init<std::vector<std::string>>())
      .def("push", &MyStackClass<std::string>::push)
      .def("pop", &MyStackClass<std::string>::pop)
      .def("size", [](const c10::intrusive_ptr<MyStackClass>& self) {
        return self->stack_.size();
      });

它公开了一个您可以在 Python 和 TorchScript 中使用的类,如下所示:

@torch.jit.script
def do_stacks(s : torch.classes.myclasses.MyStackClass):
    s2 = torch.classes.myclasses.MyStackClass(["hi", "mom"])
    print(s2.pop()) # "mom"
    s2.push("foobar")
    return s2 # ["hi", "foobar"]

您可以在此处的教程中尝试一下。

分布式 RPC 框架 API(现已稳定)

分布式 RPC 框架 在 1.4 版本中作为实验性功能推出,建议将分布式 RPC 框架标记为稳定版,不再是实验性功能。这项工作涉及大量增强和错误修复,以使分布式 RPC 框架整体上更可靠、更健壮,并新增了一些功能,包括分析支持、在 RPC 中使用 TorchScript 函数以及一些易用性增强。以下是该框架中各种 API 的概述:

RPC API

RPC API 允许用户指定要在远程节点上运行的函数和要实例化的对象。这些函数被透明地记录下来,以便梯度可以使用分布式 Autograd 通过远程节点反向传播。

分布式 Autograd

分布式 Autograd 连接多个节点之间的 autograd 图,并允许梯度在反向传播过程中流动。梯度被累积到一个上下文(与 Autograd 中的 `.grad` 字段不同)中,用户必须在 `with dist_autograd.context()` 管理器下指定其模型的前向传播,以确保所有 RPC 通信都被正确记录。目前,仅实现了 FAST 模式(有关 FAST 和 SMART 模式之间的区别,请参阅此处)。

分布式优化器

分布式优化器为每个工作器上的优化器创建 RRef,这些优化器具有需要梯度的参数,然后使用 RPC API 远程运行优化器。用户必须收集所有远程参数并将它们包装在 `RRef` 中,因为这是分布式优化器所需的输入。用户还必须指定分布式 autograd `context_id`,以便优化器知道在哪个上下文中查找梯度。

在此处了解有关分布式 RPC 框架 API 的更多信息:此处

新的高级 autograd API(实验性)

PyTorch 1.5 在 `torch.autograd.functional` 子模块中新增了 jacobian、hessian、jvp、vjp、hvp 和 vhp 等函数。此功能基于当前的 API 构建,允许用户轻松执行这些函数。

有关 GitHub 上的详细设计讨论,请参阅此处

不再支持 Python 2

从 PyTorch 1.5.0 开始,我们将不再支持 Python 2,特别是 2.7 版本。今后对 Python 的支持将仅限于 Python 3,特别是 Python 3.5、3.6、3.7 和 3.8(首次在 PyTorch 1.4.0 中启用)。

我们感谢整个 PyTorch 团队和社区为这项工作做出的所有贡献。

干杯!

PyTorch 团队