提交 8129deb3 编写于 作者: 绝不原创的飞龙's avatar 绝不原创的飞龙

2024-02-05 16:25:22

上级 71243891
......@@ -7,7 +7,7 @@
> 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/)
## 如何添加新的维护者[](#how-to-add-a-new-maintainer "跳转到此标题")
## 如何添加新的维护者
要成为维护者,一个人需要:
......
......@@ -91,15 +91,15 @@ PyTorch 的运作方式与 GitHub 上的大多数开源项目类似。但是,
如果您无法自行解决问题,请评论并分享您是否可以重现问题,这有助于团队确定问题区域。
### 审查未解决的拉取请求[](#reviewing-open-pull-requests "跳转到此标题")
### 审查未解决的拉取请求
我们感谢您帮助审查和评论拉取请求。我们的团队努力保持可管理大小的未解决拉取请求数量,如果需要更多信息,我们会迅速回应,并合并我们认为有用的 PR。然而,由于高度的兴趣,对拉取请求的额外关注总是受欢迎的。
### 提高代码可读性[](#improving-code-readability "跳转到此标题")
### 提高代码可读性
提高代码可读性有助于每个人。通常最好提交少量涉及少数文件的拉取请求,而不是涉及许多文件的大型拉取请求。在 PyTorch 论坛[这里](https://discuss.pytorch.org/)开始讨论或与您的改进相关的问题是开始的最佳方式。
### 添加测试用例以使代码库更加健壮[](#adding-test-cases-to-make-the-codebase-more-robust "跳转到此标题")
### 添加测试用例以使代码库更加健壮
额外的测试覆盖是受欢迎的。
......@@ -111,7 +111,7 @@ PyTorch 的运作方式与 GitHub 上的大多数开源项目类似。但是,
如果您认为某个问题可以从特定标签或复杂性级别中受益,请在问题上发表评论并分享您的意见。如果您认为某个问题没有正确分类,请发表评论并让团队知道。
## 关于开源开发[](#about-open-source-development "跳转到此标题")
## 关于开源开发
如果这是您第一次为开源项目做贡献,开发过程的某些方面可能对您来说有些不寻常。
......@@ -147,7 +147,7 @@ PyTorch 的运作方式与 GitHub 上的大多数开源项目类似。但是,
+ **您是否触及了与 PR 无关的代码?** 为了帮助代码审查,请只在您的拉取请求中包含与您的更改直接相关的文件。
## 常见问题[](#frequently-asked-questions "跳转到此标题")
## 常见问题
+ **作为审阅者,我如何贡献?** 如果社区开发人员复制问题、尝试新功能或以其他方式帮助我们识别或解决问题,那将会有很大的价值。在任务或拉取请求上评论您的环境详细信息是有帮助和受欢迎的。
......@@ -193,6 +193,6 @@ PyTorch 教程是用来帮助理解如何使用 PyTorch 来完成特定任务或
在 PR 被接受后,站点将使用 GitHub Actions 进行重新构建和部署。
### 贡献新教程[](#contributing-a-new-tutorial "跳转到此标题的永久链接")
### 贡献新教程
请参阅[PyTorch.org 教程贡献指南](https://github.com/pytorch/tutorials/#contributing)
......@@ -123,13 +123,13 @@ PyTorch 采用了一个分层的技术治理结构。
+ 首席维护者评估所有信息,并做出最终决定,确认或拒绝提名,并清晰公开表明他们决定背后的理由。
### 删除首席核心维护者并提名新的首席核心维护者[](#removing-the-lead-core-maintainer-and-nominating-a-new-lead-core-maintainer "跳转到此标题")
### 删除首席核心维护者并提名新的首席核心维护者
+ 超过三分之二的核心维护者(75%)可以选择删除首席核心维护者。
+ 在删除首席核心维护者或在意外情况下(如首席核心维护者永久不可用)之后,核心维护者遵循排名选择投票方法选举新的首席核心维护者。
## 添加、删除和重新范围化模块和项目[](#add-remove-and-re-scope-modules-and-projects "跳转到此标题")
## 添加、删除和重新范围化模块和项目
核心维护者共同负责决定在 PyTorch 组织中添加、删除和重新范围化新模块,无论是作为 PyTorch GitHub 组织中的新存储库,还是作为[pytorch/pytorch](https://github.com/pytorch/pytorch)存储库中的文件夹。
......@@ -153,7 +153,7 @@ PyTorch 采用了一个分层的技术治理结构。
通知相关专家有关问题或拉取请求是重要的。强烈建议在给定兴趣领域的专家进行审查,特别是在拉取请求的批准上。如果未能这样做,可能会导致相关专家撤销更改。
### 有争议的决策过程[](#controversial-decision-process "跳转到此标题")
### 有争议的决策过程
在给定兴趣领域进行重大更改需要打开一个 GitHub 问题进行讨论。这包括:
......
......@@ -139,7 +139,7 @@
+ (名誉退休)Adam Paszke ([apaszke](https://github.com/apaszke))
### 线性代数(torch.linalg)[](#linear-algebra-torch-linalg "跳转到此标题的永久链接")
### 线性代数(torch.linalg)
+ 迈克·鲁贝里([mruberry](https://github.com/mruberry)
......@@ -161,7 +161,7 @@
+ 安德鲁·詹姆斯([amjames](https://github.com/amjames)
### 嵌套张量(torch.nested)[](#nestedtensor-torch-nested "跳转到此标题的永久链接")
### 嵌套张量(torch.nested)
+ 阿尔班·德马松([albanD](https://github.com/albanD)
......@@ -175,19 +175,19 @@
+ 娜塔莉亚·吉梅尔谢因([ngimel](https://github.com/ngimel)
### 掩码张量(torch.masked)[](#maskedtensor-torch-masked "跳转到此标题的永久链接")
### 掩码张量(torch.masked)
+ 克里斯蒂安·普赫施([cpuhrsch](https://github.com/cpuhrsch)
+ (名誉退休)乔治·齐([george-qi](https://github.com/george-qi)
### 快速傅里叶变换(torch.fft)[](#fast-fourier-transform-torch-fft "跳转到此标题的永久链接")
### 快速傅里叶变换(torch.fft)
+ 迈克·鲁贝里([mruberry](https://github.com/mruberry)
+ 彼得·贝尔([peterbell10](https://github.com/peterbell10)
### CPU 性能(Torch Inductor / MKLDNN)[](#cpu-performance-torch-inductor-mkldnn "跳转到此标题的永久链接")
### CPU 性能(Torch Inductor / MKLDNN)
+ 马明飞([mingfeima](https://github.com/mingfeima)
......@@ -211,7 +211,7 @@
+ (名誉退休)李建辉([Jianhui-Li](https://github.com/Jianhui-Li)
### GPU 性能(Torch Inductor / Triton / CUDA)[](#gpu-performance-torch-inductor-triton-cuda "跳转到此标题的永久链接")
### GPU 性能(Torch Inductor / Triton / CUDA)
+ 娜塔莉亚·吉梅尔谢因([ngimel](https://github.com/ngimel)
......@@ -295,7 +295,7 @@
+ (名誉退休)Will Feng([yf225](https://github.com/yf225)
### C10 utils and operator dispatch[](#c10-utils-and-operator-dispatch "Permalink to this heading")
### C10 utils and operator dispatch
+ Brian Hirsh([bdhirsh](https://github.com/bdhirsh)
......@@ -335,7 +335,7 @@
+ Tao Xu([xta0](https://github.com/xta0)
### 模型压缩与优化[](#model-compression-optimization "Permalink to this heading")
### 模型压缩与优化
+ Vasiliy Kuznetsov([vkuzo](https://github.com/vkuzo)
......
......@@ -44,7 +44,7 @@
+ 需要特定`dtype`的函数
## 典型的混合精度训练[](#typical-mixed-precision-training "跳转到此标题")
## 典型的混合精度训练
```py
# Creates model and optimizer in default precision
......@@ -77,7 +77,7 @@ for epoch in epochs:
scaler.update()
```
## 使用未缩放梯度[](#working-with-unscaled-gradients "跳转到此标题")
## 使用未缩放梯度
`scaler.scale(loss).backward()`产生的所有梯度都是经过缩放的。如果您希望在`backward()``scaler.step(optimizer)`之间修改或检查参数的`.grad`属性,您应该首先取消缩放它们。例如,梯度裁剪操作会操纵一组梯度,使它们的全局范数(参见`torch.nn.utils.clip_grad_norm_()`)或最大幅度(参见`torch.nn.utils.clip_grad_value_()`)小于某个用户设定的阈值。如果您尝试在不取消缩放的情况下裁剪梯度,梯度的范数/最大幅度也会被缩放,因此您请求的阈值(本来是用于*未缩放*梯度的阈值)将无效。
......@@ -118,9 +118,9 @@ for epoch in epochs:
`unscale_`应该每个优化器每次`step`调用只调用一次,并且只在为该优化器分配的参数的所有梯度都被累积之后才调用。在每个`step`之间为给定的优化器调用两次`unscale_`会触发一个运行时错误。
## 使用缩放梯度[](#working-with-scaled-gradients "跳转到此标题")
## 使用缩放梯度
### 梯度累积[](#gradient-accumulation "跳转到此标题")
### 梯度累积
梯度累积会在一个有效批次的大小上添加梯度,大小为`batch_per_iter * iters_to_accumulate`(如果是分布式的话还要乘以`num_procs`)。尺度应该校准到有效批次,这意味着在有效批次粒度上进行 inf/NaN 检查,如果发现 inf/NaN 梯度,则跳过步骤,同时尺度更新应该在有效批次粒度上发生。此外,梯度应该保持缩放,尺度因子应该保持恒定,而给定有效批次的梯度被累积。如果在累积完成之前梯度未被缩放(或尺度因子发生变化),下一个反向传播将会在将缩放的梯度添加到未缩放的梯度(或使用不同因子缩放的梯度)之后,无法恢复已累积的未缩放梯度,必须调用`step`
......@@ -224,7 +224,7 @@ for epoch in epochs:
scaler.update()
```
## 使用多个模型、损失和优化器[](#working-with-multiple-models-losses-and-optimizers "跳转到此标题")
## 使用多个模型、损失和优化器
如果您的网络有多个损失,您必须分别对每个损失调用`scaler.scale`。如果您的网络有多个优化器,您可以分别对其中任何一个调用`scaler.unscale_`,并且您必须分别对每个调用`scaler.step`
......
......@@ -11,7 +11,7 @@
这个笔记将介绍自动求导的工作原理以及记录操作的概述。虽然不是严格必要理解所有这些,但我们建议熟悉它,因为这将帮助您编写更高效、更清洁的程序,并可以帮助您调试。
## 自动求导如何编码历史[](#how-autograd-encodes-the-history "跳转到此标题")
## 自动求导如何编码历史
自动求导是一个反向自动微分系统。概念上,autograd 在执行操作时记录创建数据的所有操作的图,为您提供一个有向无环图,其叶子是输入张量,根是输出张量。通过从根到叶子跟踪这个图,您可以使用链式法则自动计算梯度。
......@@ -47,7 +47,7 @@ print(y is y.grad_fn._saved_result) # False
张量是否会打包为不同的张量对象取决于它是否是其自己`grad_fn`的输出,这是一个实现细节,可能会发生变化,用户不应依赖于此。
## 不可微函数的梯度[](#gradients-for-non-differentiable-functions "跳转到此标题")
## 不可微函数的梯度
使用自动微分进行梯度计算仅在每个使用的基本函数可微时有效。不幸的是,我们在实践中使用的许多函数都没有这个性质(例如在`0`处的`relu``sqrt`)。为了尝试减少不可微函数的影响,我们通过按照以下规则定义基本操作的梯度来实现:
......@@ -61,7 +61,7 @@ print(y is y.grad_fn._saved_result) # False
1. 如果函数未定义(例如`sqrt(-1)``log(-1)`或大多数函数在输入为`NaN`时),则用作梯度的值是任意的(我们也可能引发错误,但不能保证)。大多数函数将使用`NaN`作为梯度,但出于性能原因,某些函数将使用其他值(例如`log(-1)`)。
1. 如果函数不是确定性映射(即不是[数学函数](https://en.wikipedia.org/wiki/Function_(mathematics))),它将被标记为不可微。如果在`no_grad`环境之外使用需要梯度的张量,则在反向传播中将出现错误。##局部禁用梯度计算[](#locally-disabling-gradient-computation "跳转到此标题的永久链接")
1. 如果函数不是确定性映射(即不是[数学函数](https://en.wikipedia.org/wiki/Function_(mathematics))),它将被标记为不可微。如果在`no_grad`环境之外使用需要梯度的张量,则在反向传播中将出现错误。##局部禁用梯度计算
有几种机制可用于在 Python 中局部禁用梯度计算:
......@@ -254,7 +254,7 @@ Wirtinger 微积分建议研究 f(z, z*),如果 f 是实可微的,则保证
更多阅读,请查看:[`arxiv.org/pdf/0906.4835.pdf`](https://arxiv.org/pdf/0906.4835.pdf)
### Wirtinger 微积分在优化中有什么用处?[](#how-is-wirtinger-calculus-useful-in-optimization "Permalink to this heading")
### Wirtinger 微积分在优化中有什么用处?
研究人员在音频和其他领域更常见地使用梯度下降来优化具有复杂变量的实值损失函数。通常,这些人将实部和虚部视为可以更新的独立通道。对于步长 $\alpha/2$ 和损失 $L$,我们可以在 $ℝ²$ 中写出以下方程:
......@@ -268,7 +268,7 @@ Wirtinger 微积分建议研究 f(z, z*),如果 f 是实可微的,则保证
因为共轭 Wirtinger 导数给出了实值损失函数的正确步骤,所以当您对具有实值损失的函数进行微分时,PyTorch 会给出这个导数。
### PyTorch 如何计算共轭 Wirtinger 导数?[](#how-does-pytorch-compute-the-conjugate-wirtinger-derivative "Permalink to this heading")
### PyTorch 如何计算共轭 Wirtinger 导数?
通常,我们的导数公式将 grad_output 作为输入,表示我们已经计算过的传入向量雅可比乘积,即,∂s∗∂L​,其中 L 是整个计算的损失(产生实际损失),s 是我们函数的输出。这里的目标是计算∂z∗∂L​,其中 z 是函数的输入。事实证明,在实际损失的情况下,我们可以仅仅计算∂s∗∂L​,即使链式法则暗示我们也需要访问∂s∂L​。如果您想跳过这个推导,请查看本节中的最后一个方程,然后跳到下一节。
......@@ -324,7 +324,7 @@ Wirtinger 微积分建议研究 f(z, z*),如果 f 是实可微的,则保证
再次使用(4),我们得到$\frac{\partial L}{\partial z^*} = c$∂z∗∂L​=c。如您所见,第二种方法涉及更少的计算,并且更适用于更快的计算。
### 跨域函数呢?[](#what-about-cross-domain-functions "Permalink to this heading")
### 跨域函数呢?
一些函数从复杂输入映射到实数输出,或者反之亦然。这些函数形成了(4)的一个特殊情况,我们可以使用链式法则推导出来:
......@@ -367,7 +367,7 @@ def unpack_hook(temp_file):
对任何函数的输入执行原地操作是禁止的,因为这可能会导致意外的副作用。如果对 pack hook 的输入进行了原地修改,PyTorch 会抛出错误,但不会捕获对 unpack hook 的输入进行原地修改的情况。
### 注册保存的张量的钩子[](#registering-hooks-for-a-saved-tensor "跳转到此标题的永久链接")
### 注册保存的张量的钩子
您可以通过在`SavedTensor`对象上调用`register_hooks()`方法来注册一对保存的张量上的钩子。这些对象作为`grad_fn`的属性暴露,并以`_raw_saved_`前缀开头。
......@@ -383,7 +383,7 @@ y.grad_fn._raw_saved_self.register_hooks(pack_hook, unpack_hook)
如果在保存的张量被释放后(即在调用反向传播后)仍保留对`SavedTensor`的引用,则禁止调用其`register_hooks()`。PyTorch 大多数情况下会抛出错误,但在某些情况下可能无法这样做,可能会出现未定义的行为。
### 注册保存的张量的默认钩子[](#registering-default-hooks-for-saved-tensors "跳转到此标题的永久链接")
### 注册保存的张量的默认钩子
另外,您可以使用上下文管理器`saved_tensors_hooks`来注册一对钩子,这些钩子将应用于在该上下文中创建的*所有*保存的张量。
......@@ -434,11 +434,11 @@ with torch.autograd.graph.saved_tensors_hooks(lambda x: x, lambda x: x):
y = x * x
```
没有钩子,`x``y.grad_fn._saved_self``y.grad_fn._saved_other`都指向同一个张量对象。有了钩子,PyTorch 将 x 打包并解包为两个新的张量对象,这两个对象与原始 x 共享相同的存储(不执行复制)。## 后向钩子执行[](#backward-hooks-execution "Permalink to this heading")
没有钩子,`x``y.grad_fn._saved_self``y.grad_fn._saved_other`都指向同一个张量对象。有了钩子,PyTorch 将 x 打包并解包为两个新的张量对象,这两个对象与原始 x 共享相同的存储(不执行复制)。## 后向钩子执行
本节将讨论不同的钩子何时触发或不触发。然后将讨论它们触发的顺序。将涵盖的钩子包括:通过`torch.Tensor.register_hook()`注册到张量的后向钩子,通过`torch.Tensor.register_post_accumulate_grad_hook()`注册到张量的后累积梯度钩子,通过`torch.autograd.graph.Node.register_hook()`注册到节点的后钩子,以及通过`torch.autograd.graph.Node.register_prehook()`注册到节点的前钩子。
### 特定钩子是否会被触发[](#whether-a-particular-hook-will-be-fired "Permalink to this heading")
### 特定钩子是否会被触发
通过`torch.Tensor.register_hook()`注册到张量的钩子在计算该张量的梯度时执行。(请注意,这不需要执行张量的 grad_fn。例如,如果张量作为`inputs`参数的一部分传递给`torch.autograd.grad()`,则可能不会执行张量的 grad_fn,但是注册到该张量的钩子将始终被执行。)
......@@ -452,7 +452,7 @@ with torch.autograd.graph.saved_tensors_hooks(lambda x: x, lambda x: x):
另一方面,如果您使用`torch.autograd.grad()`,则注册到与传递给`input`的张量对应的节点的反向钩子可能不会被执行,因为除非有另一个依赖于此节点梯度结果的输入,否则不会执行这些节点。
### 不同钩子被触发的顺序[](#the-order-in-which-the-different-hooks-are-fired)
### 不同钩子被触发的顺序
发生事情的顺序是:
......@@ -476,7 +476,7 @@ with torch.autograd.graph.saved_tensors_hooks(lambda x: x, lambda x: x):
`torch.nn.modules.module.register_module_full_backward_hook()` 是使用注册到节点的钩子来实现的。在计算前向传播时,钩子被注册到与模块的输入和输出对应的 grad_fn 上。因为一个模块可能接受多个输入并返回多个输出,所以在前向传播之前,首先对模块的输入应用一个虚拟的自定义自动求导函数,然后将前向传播的输出返回到确保这些张量共享一个单一的 grad_fn,然后我们可以将我们的钩子附加到上面。
### 张量在原地修改时的钩子行为[](#behavior-of-tensor-hooks-when-tensor-is-modified-in-place "Permalink to this heading")
### 张量在原地修改时的钩子行为
通常,注册到张量的钩子接收相对于该张量的输出的梯度,其中张量的值被视为在计算反向传播时的值。
......
......@@ -51,7 +51,7 @@ with torch.cuda.device(1):
# d.device, e.device, and f.device are all device(type='cuda', index=2)
```
## Ampere(以及更高版本)设备上的 TensorFloat-32(TF32)[](#tensorfloat-32-tf32-on-ampere-and-later-devices "跳转到此标题的永久链接")
## Ampere(以及更高版本)设备上的 TensorFloat-32(TF32)
从 PyTorch 1.7 开始,有一个名为 allow_tf32 的新标志。在 PyTorch 1.7 到 PyTorch 1.11 中,默认为 True,在 PyTorch 1.12 及以后为 False。该标志控制 PyTorch 是否允许在 NVIDIA GPU 上使用 TensorFloat32(TF32)张量核心来计算 matmul(矩阵乘法和批量矩阵乘法)和卷积。
......@@ -114,7 +114,7 @@ at::globalContext().setAllowTF32CuDNN(false);
+ [CUDA 11](https://devblogs.nvidia.com/cuda-11-features-revealed/)
+ [Ampere 架构](https://devblogs.nvidia.com/nvidia-ampere-architecture-in-depth/) ## FP16 GEMMs 中的降低精度缩减[](#reduced-precision-reduction-in-fp16-gemms "跳转到此标题的永久链接")
+ [Ampere 架构](https://devblogs.nvidia.com/nvidia-ampere-architecture-in-depth/) ## FP16 GEMMs 中的降低精度缩减
fp16 GEMMs 可能使用一些中间降低精度的缩减(例如在 fp16 而不是 fp32 中)。这些选择性的精度降低可以在某些工作负载(特别是具有大 k 维度的工作负载)和 GPU 架构上实现更高的性能,但会牺牲数值精度和可能会发生溢出。
......@@ -233,7 +233,7 @@ with torch.cuda.stream(s):
尽管`s`上的计算不读取`A`的内容,也没有其他对`A`的使用,但仍然需要同步,因为`A`可能对应于由 CUDA 缓存分配器重新分配的内存,其中包含来自旧(已释放)内存的挂起操作。
### 反向传递的流语义[](#stream-semantics-of-backward-passes "跳转到此标题")
### 反向传递的流语义
每个反向 CUDA 操作都在用于其对应的前向操作的相同流上运行。如果您的前向传递在不同流上并行运行独立操作,这有助于反向传递利用相同的并行性。
......@@ -284,7 +284,7 @@ with torch.cuda.stream(s):
loss.backward(gradient=initial_grad)
```
#### BC 注意:在默认流上使用梯度[](#bc-note-using-grads-on-the-default-stream "跳转到此标题")
#### BC 注意:在默认流上使用梯度
在 PyTorch 的早期版本(1.9 及更早版本)中,自动求导引擎总是将默认流与所有反向操作同步,因此以下模式:
......@@ -303,7 +303,7 @@ torch.cuda.current_stream().wait_stream(s)
use grads
```
即使`使用梯度`在默认流上。## 内存管理[](#memory-management "跳转到此标题")
即使`使用梯度`在默认流上。## 内存管理
PyTorch 使用缓存内存分配器加速内存分配。这允许快速内存释放而无需设备同步。但是,分配器管理的未使用内存仍会显示为在 `nvidia-smi` 中使用。您可以使用 `memory_allocated()``max_memory_allocated()` 监视张量占用的内存,并使用 `memory_reserved()``max_memory_reserved()` 监视缓存分配器管理的总内存量。调用 `empty_cache()` 释放 PyTorch 中所有**未使用**的缓存内存,以便其他 GPU 应用程序可以使用。但是,张量占用的 GPU 内存不会被释放,因此不能增加供 PyTorch 使用的 GPU 内存量。
......@@ -504,7 +504,7 @@ y_cpu = torch.ones_like(x_cpu)
y_gpu = torch.zeros_like(x_gpu)
```
### 使用固定内存缓冲区[](#use-pinned-memory-buffers "Permalink to this heading")
### 使用固定内存缓冲区
警告
......@@ -514,7 +514,7 @@ y_gpu = torch.zeros_like(x_gpu)
此外,一旦您固定了一个张量或存储,您可以使用异步 GPU 拷贝。只需在`to()``cuda()`调用中传递一个额外的`non_blocking=True`参数。这可以用来重叠数据传输和计算。
您可以通过在其构造函数中传递`pin_memory=True`来使`DataLoader`返回放置在固定内存中的批次。### 使用 nn.parallel.DistributedDataParallel 而不是多进程或 nn.DataParallel[](#use-nn-parallel-distributeddataparallel-instead-of-multiprocessing-or-nn-dataparallel "Permalink to this heading")
您可以通过在其构造函数中传递`pin_memory=True`来使`DataLoader`返回放置在固定内存中的批次。### 使用 nn.parallel.DistributedDataParallel 而不是多进程或 nn.DataParallel
大多数涉及批量输入和多个 GPU 的用例应默认使用`DistributedDataParallel`来利用多个 GPU。
......@@ -673,7 +673,7 @@ for data, target in zip(real_inputs, real_targets):
g.replay()
# Params have been updated. static_y_pred, static_loss, and .grad
# attributes hold values from computing on this iteration's data.
``` ### 部分网络捕获[](#partial-network-capture "Permalink to this heading")
``` ### 部分网络捕获
如果您的网络中有一部分不安全可捕获(例如,由于动态控制流、动态形状、CPU 同步或基本的 CPU 端逻辑),您可以急切地运行不安全的部分,并使用`torch.cuda.make_graphed_callables()`仅对可捕获的部分进行图形化处理。
......@@ -724,7 +724,7 @@ for data, target in zip(real_inputs, real_targets):
# as well as module1's backward ops, run as graphs
loss.backward()
optimizer.step()
``` ### 与 torch.cuda.amp 一起使用[](#usage-with-torch-cuda-amp "跳转到此标题")
``` ### 与 torch.cuda.amp 一起使用
对于典型的优化器,`GradScaler.step`会将 CPU 与 GPU 同步,这在捕获过程中是被禁止的。为了避免错误,要么使用部分网络捕获,要么(如果前向、损失和反向是捕获安全的)捕获前向、损失和反向,但不捕获优化器步骤:
......@@ -764,7 +764,7 @@ for data, target in zip(real_inputs, real_targets):
# Runs scaler.step and scaler.update eagerly
scaler.step(optimizer)
scaler.update()
``` ### 与多个流一起使用[](#usage-with-multiple-streams "跳转到此标题")
``` ### 与多个流一起使用
捕获模式会自动传播到与捕获流同步的任何流。在捕获过程中,您可以通过向不同流发出调用来暴露并行性,但整体流依赖 DAG 必须从初始捕获流开始分支,并在捕获开始后重新加入初始流,然后在捕获结束前重新加入初始流:
......@@ -790,7 +790,7 @@ with torch.cuda.graph(g):
为了避免对在 nsight 系统或 nvprof 中查看重播的高级用户造成困惑: 与急切执行不同,图形在捕获中将非平凡的流 DAG 解释为提示,而不是命令。在重播过程中,图形可能会将独立操作重新组织到不同的流中,或以不同的顺序排队(同时尊重您原始 DAG 的整体依赖关系)。
### 使用 DistributedDataParallel[](#usage-with-distributeddataparallel "跳转到此标题")
### 使用 DistributedDataParallel
#### NCCL < 2.9.6
......@@ -818,13 +818,13 @@ NCCL 版本 2.9.6 或更高版本允许图中的集合。捕获整个反向传
1. 在捕获之前,您的预热必须至少运行 11 次启用 DDP 的急切迭代。
### 图内存管理[](#graph-memory-management "跳转到此标题")
### 图内存管理
捕获的图形在每次重播时都会作用于相同的虚拟地址。如果 PyTorch 释放内存,后续的重播可能会导致非法内存访问。如果 PyTorch 将内存重新分配给新张量,重播可能会破坏这些张量看到的值。因此,图形使用的虚拟地址必须在重播过程中保留给图形。PyTorch 缓存分配器通过检测捕获正在进行并从图形私有内存池中满足捕获的分配来实现这一点。私有池会一直保持活动,直到其`CUDAGraph`对象和捕获期间创建的所有张量超出范围。
私有池会自动维护。默认情况下,分配器为每个捕获创建一个单独的私有池。如果捕获多个图形,这种保守的方法确保图形重播永远不会破坏彼此的值,但有时会不必要地浪费内存。
#### 跨捕获共享内存[](#sharing-memory-across-captures "跳转到此标题")
#### 跨捕获共享内存
为了节省存储在私有池中的内存,`torch.cuda.graph``torch.cuda.make_graphed_callables()` 可选地允许不同的捕获共享同一个私有池。如果你知道一组图形将始终按照它们被捕获的顺序重播,并且永远不会同时重播,那么共享一个私有池是安全的。
......
......@@ -9,7 +9,7 @@
在本说明中,我们将介绍扩展`torch.nn``torch.autograd``torch`以及编写自定义 C++扩展的方法。
## 扩展`torch.autograd`[](#extending-torch-autograd "跳转到此标题的永久链接")
## 扩展`torch.autograd`
`autograd`添加操作需要为每个操作实现一个新的`Function`子类。请记住,`autograd`使用`Function`来编码操作历史并计算梯度。
......@@ -214,7 +214,7 @@ print(test)
有关有限差分梯度比较的更多详细信息,请参见数值梯度检查。如果您的函数用于高阶导数(对反向传递进行微分),则可以使用同一软件包中的`gradgradcheck`函数来检查高阶导数。
### 合并或单独的`forward()`和`setup_context()`[](#combined-or-separate-forward-and-setup-context "Permalink to this heading")
### 合并或单独的`forward()`和`setup_context()`
有两种主要方法来定义`Function`。要么:
......@@ -271,17 +271,17 @@ class LinearFunction(Function):
+ 前向模式梯度确实遵守`set_materialize_grads()`设置的标志,当禁用时,您可以获得 None 输入梯度。
### `torch.func`转换和/或`torch.vmap()`[](#torch-func-transforms-and-or-torch-vmap "跳转到此标题的永久链接")
### `torch.func`转换和/或`torch.vmap()`
有关详细信息,请参阅使用 autograd.Function 扩展 torch.func。
## 扩展`torch.nn`[](#extending-torch-nn "跳转到此标题的永久链接")
## 扩展`torch.nn`
`nn`导出两种接口 - 模块及其功能版本。您可以以两种方式扩展它,但我们建议对所有包含任何参数或缓冲区的层使用模块,并建议对参数为空的操作(如激活函数、池化等)使用功能形式。
在上面的部分中已经完全涵盖了添加操作的功能版本。
### 添加一个`Module`[](#adding-a-module "跳转到此标题的永久链接")
### 添加一个`Module`
由于`nn`大量使用`autograd`,添加一个新的`Module`需要实现一个执行操作并能计算梯度的`Function`。从现在开始,让我们假设我们想要实现一个`Linear`模块,并且我们已经按照上面的列表实现了该函数。添加这个需要非常少的代码。现在,需要实现两个函数:
......@@ -330,7 +330,7 @@ class Linear(nn.Module):
)
```
## 扩展`torch` Python API[](#extending-torch-python-api "Permalink to this heading")
## 扩展`torch` Python API
您可以通过定义一个具有与`Tensor`匹配的方法的自定义类来创建模拟`Tensor`的自定义类型。但是如果您希望能够将这些类型传递给像`torch.add()`这样的顶层`torch`命名空间中接受`Tensor`操作数的函数,该怎么办?
......@@ -674,7 +674,7 @@ vmap -> Autocast -> Autograd -> ZeroTensor -> Neg/Conj -> Functionalize -> Pytho
您可以在[subclass zoo](https://github.com/albanD/subclass_zoo)存储库中找到许多基于`__torch_dispatch__`的子类的示例。
## 通过 Modes 扩展所有`torch` API[](#extending-all-torch-api-with-modes "Permalink to this heading")
## 通过 Modes 扩展所有`torch` API。
不幸的是,有些函数不接受张量输入。这意味着上面描述的子类方法无法用于覆盖 PyTorch 的所有函数的行为。此外,如果用例要求拦截每个函数调用,将每个张量更改为子类可能会过于侵入性。
......@@ -743,7 +743,7 @@ Dispatch Log: aten.detach.default(*(tensor([2., 2., 2., 2., 2., 2., 2., 2., 2.,
Dispatch Log: aten.detach.default(*(tensor([2., 2., 2., 2., 2., 2., 2., 2., 2., 2.]),), **{})
```
## 编写自定义 C++扩展[](#writing-custom-c-extensions "跳转到此标题的永久链接")
## 编写自定义 C++扩展
查看这个[PyTorch 教程](https://pytorch.org/tutorials/advanced/cpp_extension.html)以获取详细解释和示例。
......
......@@ -45,7 +45,7 @@ PyTorch 将这两个概念结合到`torch.autograd.Function`中。
让我们看一些常见用例的例子。
### 示例 1:autograd.Function 调用另一个系统[](#example-1-autograd-function-calls-into-another-system "Permalink to this heading")
### 示例 1:autograd.Function 调用另一个系统
一个常见情况是一个同时调用另一个系统(如 C++,CUDA,numpy,triton)的`torch.autograd.Function`,同时具有 forward()和 backward()。
......@@ -147,7 +147,7 @@ grad_x = torch.func.grad(lambda x: numpy_sort(x).sum())(x)
assert torch.allclose(grad_x, torch.ones_like(x))
```
### 示例 2:autograd.Function 指定自定义梯度规则[](#example-2-autograd-function-specifies-custom-gradient-rules "Permalink to this heading")
### 示例 2:autograd.Function 指定自定义梯度规则
另一个常见情况是一个使用 PyTorch 操作实现的`torch.autograd.Function`。PyTorch 能够自动为 PyTorch 操作计算梯度,但也许我们希望自定义梯度的计算方式。我们可能希望自定义反向传递与 PyTorch 给出的不同的原因有:
......@@ -215,7 +215,7 @@ assert torch.allclose(ggx, 6 * x)
请只使用`save_for_backward()``save_for_forward()`来保存张量。请不要直接将张量或张量集合分配到 ctx 对象上 - 这些张量将不会被跟踪
## `torch.vmap()`支持[](#torch-vmap-support "Permalink to this heading")
## `torch.vmap()`支持
要使用`torch.autograd.Function``torch.vmap()`,您必须:
......@@ -223,7 +223,7 @@ assert torch.allclose(ggx, 6 * x)
+ 通过设置`generate_vmap_rule=True`来要求我们自动生成它。
### 自动生成一个 vmap 规则[](#automatically-generate-a-vmap-rule "Permalink to this heading")
### 自动生成一个 vmap 规则
如果您的`torch.autograd.Function`满足以下额外约束条件,则我们可以为其生成一个 vmap 规则。如果不满足约束条件或者希望在 vmap 下自定义行为,请手动定义一个 vmap 静态方法(请参见下一节)。
......@@ -268,7 +268,7 @@ result = torch.vmap(my_cube)(x)
assert torch.allclose(result, x ** 3)
```
### 定义 vmap 静态方法[](#defining-the-vmap-staticmethod "Permalink to this heading")
### 定义 vmap 静态方法
如果您的`torch.autograd.Function`调用另一个系统(如 NumPy、C++、CUDA、triton),那么为了使其与`torch.vmap()`或使用它的转换一起工作,您需要手动定义一个`vmap()`静态方法。
......
......@@ -7,7 +7,7 @@
> 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/)
## 我的模型报告“cuda 运行时错误(2):内存不足”[](#my-model-reports-cuda-runtime-error-2-out-of-memory "跳转到此标题的永久链接")
## 我的模型报告“cuda 运行时错误(2):内存不足”
正如错误消息所示,您的 GPU 上的内存已耗尽。由于我们在 PyTorch 中经常处理大量数据,小错误可能迅速导致程序使用完所有 GPU 的内存;幸运的是,在这些情况下修复通常很简单。以下是一些常见的检查事项:
......@@ -52,13 +52,13 @@ return output
**考虑使用检查点。**您可以通过使用[checkpoint](https://pytorch.org/docs/stable/checkpoint.html)来在内存和计算之间进行权衡。
## 我的 GPU 内存没有正确释放[](#my-gpu-memory-isn-t-freed-properly "跳转到此标题的永久链接")
## 我的 GPU 内存没有正确释放
PyTorch 使用缓存内存分配器来加速内存分配。因此,`nvidia-smi`中显示的值通常不反映真实的内存使用情况。有关 GPU 内存管理的更多详细信息,请参见内存管理。
如果即使在 Python 退出后 GPU 内存仍未释放,很可能仍有一些 Python 子进程在运行。您可以通过`ps -elf | grep python`找到它们,并使用`kill -9 [pid]`手动杀死它们。
## 我的内存不足异常处理程序无法分配内存[](#my-out-of-memory-exception-handler-can-t-allocate-memory "跳转到此标题")
## 我的内存不足异常处理程序无法分配内存
您可能有一些代码尝试从内存不足错误中恢复。
......@@ -84,9 +84,9 @@ if oom:
run_model(1)
```
## 我的数据加载器工作程序返回相同的随机数[](#my-data-loader-workers-return-identical-random-numbers "跳转到此标题")
## 我的数据加载器工作程序返回相同的随机数
您可能正在使用其他库在数据集中生成随机数,并且工作程序子进程是通过`fork`启动的。请查看`torch.utils.data.DataLoader`的文档,了解如何使用其`worker_init_fn`选项正确设置工作程序中的随机种子。## 我的循环网络无法与数据并行性一起工作[](#my-recurrent-network-doesn-t-work-with-data-parallelism "跳转到此标题")
您可能正在使用其他库在数据集中生成随机数,并且工作程序子进程是通过`fork`启动的。请查看`torch.utils.data.DataLoader`的文档,了解如何使用其`worker_init_fn`选项正确设置工作程序中的随机种子。## 我的循环网络无法与数据并行性一起工作
在使用`Module``DataParallel``data_parallel()`时,使用`pack sequence -> recurrent network -> unpack sequence`模式存在一个微妙之处。每个设备上的`forward()`的输入只会是整个输入的一部分。因为解包操作`torch.nn.utils.rnn.pad_packed_sequence()`默认只填充到它看到的最长输入,即该特定设备上的最长输入,当结果被收集在一起时会发生大小不匹配。因此,您可以利用`pad_packed_sequence()``total_length`参数,以确保`forward()`调用返回相同长度的序列。例如,您可以编写:
......
......@@ -173,11 +173,11 @@ $\begin{aligned} 2*CW u' &= (\frac{\partial y}{\partial a} + i \frac{\partial y}
这将需要四次实数到实数有限差分的评估(与上述方法相比多两倍)。由于这种方法没有更多的自由度(相同数量的实值变量),我们尝试在这里获得最快的评估,因此使用上述的另一种公式。
### 对于具有复杂输出的函数的快速 gradcheck[](#fast-gradcheck-for-functions-with-complex-outputs "跳转到本标题")
### 对于具有复杂输出的函数的快速 gradcheck
就像在慢速情况下一样,我们考虑两个实值函数,并对每个函数使用上面的适当规则。
## Gradgradcheck 实现[](#gradgradcheck-implementation "跳转到本标题")
## Gradgradcheck 实现
PyTorch 还提供了一个工具来验证二阶梯度。这里的目标是确保反向实现也是正确可微的,并计算正确的结果。
......
......@@ -92,7 +92,7 @@ PyTorch 使用缓存内存分配器来加速内存分配。这允许快速的内
`#if (defined(CUDA_VERSION) && CUDA_VERSION >= 11000) || (defined(USE_ROCM) && ROCM_VERSION >= 40300)`
## 参考 CUDA 语义文档[](#refer-to-cuda-semantics-doc "跳转到此标题")
## 参考 CUDA 语义文档
对于此处未列出的任何部分,请参考 CUDA 语义文档:CUDA 语义
......
......@@ -23,7 +23,7 @@
该说明假定您要么在组织中从源代码构建 PyTorch,要么具有在 PyTorch 使用时加载附加代码的静态链接能力。因此,许多钩子都公开为可以在集中位置触发一次的 C++ API,例如在静态初始化代码中。
## 全局操作符分析[](#fleet-wide-operator-profiling "跳转到此标题")
## 全局操作符分析
PyTorch 自带 `torch.autograd.profiler`,能够按需测量各个操作符所花费的时间。可以使用相同的机制对运行 PyTorch 的任何进程进行“始终开启”测量。这对于收集在给定进程或整个机器集上运行的 PyTorch 工作负载信息可能很有用。
......@@ -76,7 +76,7 @@ SetAPIUsageLogger([](const std::string& event_name) {
开发者注意:可以在 C++ 代码中使用 `C10_LOG_API_USAGE_ONCE("my_api")` 或在 Python 中使用 `torch._C._log_api_usage_once("my.api")` 来添加新的 API 触发点。
## 将元数据附加到保存的 TorchScript 模型[](#attaching-metadata-to-saved-torchscript-models "跳转到此标题")
## 将元数据附加到保存的 TorchScript 模型
TorchScript 模块可以保存为捆绑序列化参数和模块代码的存档文件,作为 TorchScript(参见`torch.jit.save()`)。通常方便将附加信息与模型一起捆绑,例如,模型生产者的描述或辅助工件。
......@@ -92,11 +92,11 @@ SetExportModuleExtraFilesHook([](const Module&) {
});
```
## 构建环境考虑[](#build-environment-considerations "跳转到此标题")
## 构建环境考虑
TorchScript 的编译需要访问原始的 Python 文件,因为它使用 Python 的`inspect.getsource`调用。在某些生产环境中,可能需要显式部署`.py`文件以及预编译的`.pyc`文件。
## 常见扩展点[](#common-extension-points "跳转到此标题")
## 常见扩展点
PyTorch 的 API 通常松散耦合,很容易用专门版本替换组件。常见的扩展点包括:
......
......@@ -43,7 +43,7 @@ PyTorch 使用模块来表示神经网络。模块是:
+ 使用 FX 转换模块
## 一个简单的自定义模块[](#a-simple-custom-module "跳转到此标题")
## 一个简单的自定义模块
要开始,让我们看一个更简单的自定义版本 PyTorch 的`Linear`模块。该模块对其输入应用仿射变换。
......@@ -96,7 +96,7 @@ tensor([ 0.3634, 0.2015, -0.8525], requires_grad=True))
通常,模块注册的参数是模块计算的方面,应该是“可学习的”。本笔记的后面部分展示了如何使用 PyTorch 的优化器更新这些参数。然而,在此之前,让我们首先看一下模块如何与其他模块组合。
## 模块作为构建模块[](#modules-as-building-blocks "跳转到此标题")
## 模块作为构建模块
模块可以包含其他模块,使它们成为开发更复杂功能的有用构建模块。最简单的方法是使用`Sequential`模块。它允许我们将多个模块链接在一起:
......@@ -268,7 +268,7 @@ dynamic_net.apply(init_weights)
+ 定义神经网络模块:[`pytorch.org/tutorials/beginner/examples_nn/polynomial_module.html`](https://pytorch.org/tutorials/beginner/examples_nn/polynomial_module.html)
## 使用模块进行神经网络训练[](#neural-network-training-with-modules "跳转到此标题的永久链接")
## 使用模块进行神经网络训练
构建完网络后,需要对其进行训练,并且可以使用 PyTorch 的优化器之一从`torch.optim`中轻松优化其参数:
......@@ -506,7 +506,7 @@ print(m_loaded.state_dict())
+ 什么是状态字典?[`pytorch.org/tutorials/recipes/recipes/what_is_state_dict.html`](https://pytorch.org/tutorials/recipes/recipes/what_is_state_dict.html)
## 模块初始化[](#module-initialization "跳转到此标题")
## 模块初始化
默认情况下,由`torch.nn`提供的模块的参数和浮点缓冲区在模块实例化时作为 32 位浮点值在 CPU 上初始化,使用的初始化方案是根据模块类型的历史表现确定的。对于某些用例,可能希望使用不同的数据类型、设备(例如 GPU)或初始化技术进行初始化。
......@@ -636,15 +636,15 @@ PyTorch 还提供了几个更高级的功能,旨在与模块一起使用。所
PyTorch 中存在各种分布式训练方法,既可以使用多个 GPU 进行训练,也可以跨多台机器进行训练。查看[分布式训练概述页面](https://pytorch.org/tutorials/beginner/dist_overview.html)以获取有关如何利用这些功能的详细信息。
### 性能分析[](#profiling-performance "跳转到此标题的永久链接")
### 性能分析
[PyTorch 性能分析器](https://pytorch.org/tutorials/beginner/profiler.html)可用于识别模型中的性能瓶颈。它可以测量和输出内存使用和时间消耗的性能特征。
### 通过量化提高性能[](#improving-performance-with-quantization "跳转到此标题的永久链接")
### 通过量化提高性能
将量化技术应用于模块可以通过使用比浮点精度更低的位宽来提高性能和内存使用。查看 PyTorch 提供的各种量化机制[这里](https://pytorch.org/docs/stable/quantization.html)
### 通过修剪改善内存使用[](#improving-memory-usage-with-pruning "跳转到此标题的永久链接")
### 通过修剪改善内存使用
大型深度学习模型通常存在过度参数化的问题,导致内存使用量很高。为了解决这个问题,PyTorch 提供了模型修剪的机制,可以帮助减少内存使用量同时保持任务准确性。[修剪教程](https://pytorch.org/tutorials/intermediate/pruning_tutorial.html)描述了如何利用 PyTorch 提供的修剪技术或根据需要定义自定义修剪技术。
......@@ -652,6 +652,6 @@ PyTorch 中存在各种分布式训练方法,既可以使用多个 GPU 进行
对于某些应用程序,在模型训练过程中约束参数空间可能是有益的。例如,强制学习参数的正交性可以改善 RNN 的收敛性。PyTorch 提供了一种应用[参数化](https://pytorch.org/tutorials/intermediate/parametrizations.html)的机制,还允许定义自定义约束。
### 使用 FX 转换模块[](#transforming-modules-with-fx "跳转到此标题")
### 使用 FX 转换模块
PyTorch 的[FX](https://pytorch.org/docs/stable/fx.html)组件提供了一种灵活的方式来通过直接操作模块计算图来转换模块。这可以用于以编程方式生成或操作各种用例的模块。要探索 FX,请查看使用 FX 进行[卷积+批量归一化融合](https://pytorch.org/tutorials/intermediate/fx_conv_bn_fuser.html)[CPU 性能分析](https://pytorch.org/tutorials/intermediate/fx_profiling_tutorial.html)的示例。
......@@ -29,17 +29,17 @@ CUDA 运行时不支持`fork`启动方法;在子进程中使用 CUDA 需要`sp
## 最佳实践和提示
### 避免和解决死锁[](#avoiding-and-fighting-deadlocks "跳转到此标题")
### 避免和解决死锁
当生成一个新进程时,有很多事情可能会出错,最常见的死锁原因是后台线程。如果有任何持有锁或导入模块的线程,并且调用了`fork`,那么子进程很可能处于损坏状态,并且会发生死锁或以不同方式失败。请注意,即使您没有,Python 内置库也会 - 不需要查看比[`multiprocessing`](https://docs.python.org/3/library/multiprocessing.html#module-multiprocessing "(在 Python v3.12 中)")更远的地方。[`multiprocessing.Queue`](https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Queue "(在 Python v3.12 中)")实际上是一个非常复杂的类,它生成多个线程用于序列化、发送和接收对象,它们也可能引起上述问题。如果您发现自己处于这种情况,请尝试使用`SimpleQueue`,它不使用任何额外的线程。
我们正在尽力让您轻松使用,并确保这些死锁不会发生,但有些事情超出我们的控制。如果您遇到无法解决的问题,请尝试在论坛上寻求帮助,我们会看看是否可以解决。
### 通过队列传递的缓冲区[](#reuse-buffers-passed-through-a-queue "跳转到此标题")
### 通过队列传递的缓冲区
请记住,每次将`Tensor`放入[`multiprocessing.Queue`](https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Queue "(在 Python v3.12 中)")时,它必须被移动到共享内存中。如果已经是共享的,则不会执行任何操作,否则将产生额外的内存复制,可能会减慢整个过程的速度。即使您有一组进程向单个进程发送数据,也要让它发送缓冲区回来 - 这几乎是免费的,并且可以避免在发送下一批数据时进行复制。
### 异步多进程训练(例如 Hogwild)[](#asynchronous-multiprocess-training-e-g-hogwild "跳转到此标题")
### 异步多进程训练(例如 Hogwild)
使用`torch.multiprocessing`,可以异步训练模型,参数可以始终共享,或者定期同步。在第一种情况下,我们建议发送整个模型对象,而在后一种情况下,我们建议只发送`state_dict()`
......
......@@ -9,7 +9,7 @@
在现代计算机中,浮点数使用 IEEE 754 标准表示。有关浮点运算和 IEEE 754 标准的更多详细信息,请参见[浮点运算](https://en.wikipedia.org/wiki/Floating-point_arithmetic)。特别要注意的是,浮点提供有限的精度(单精度浮点数约为 7 位小数,双精度浮点数约为 16 位小数),浮点加法和乘法不是结合的,因此操作的顺序会影响结果。因此,PyTorch 不能保证对于数学上相同的浮点计算产生按位相同的结果。同样,即使在控制随机源后,PyTorch 发布、单个提交或不同平台之间也不能保证按位相同的结果。特别是,即使输入按位相同,CPU 和 GPU 的结果也可能不同。
## 批处理计算或切片计算[](#batched-computations-or-slice-computations "跳转到此标题")
## 批处理计算或切片计算
PyTorch 中的许多操作支持批处理计算,其中对输入批次的元素执行相同的操作。一个例子是`torch.mm()``torch.bmm()`。可以将批处理计算实现为对批处理元素的循环,并对各个批处理元素应用必要的数学操作,出于效率原因,我们没有这样做,通常对整个批次进行计算。在这种情况下,我们调用的数学库和 PyTorch 内部操作的实现可能与非批处理计算产生略有不同的结果。特别是,设`A``B`为适合批处理矩阵乘法的三维张量。那么`(A@B)[0]`(批处理结果的第一个元素)不能保证与`A[0]@B[0]`(输入批次的第一个元素的矩阵乘积)按位相同,尽管在数学上它是相同的计算。
......@@ -26,7 +26,7 @@ a.norm() # produces tensor(inf)
a.double().norm() # produces tensor(1.4142e+20, dtype=torch.float64), representable in fp32
```
## 线性代数(`torch.linalg`)[](#linear-algebra-torch-linalg "跳转到此标题")
## 线性代数(`torch.linalg`)
### 非有限值
......@@ -44,13 +44,13 @@ a.double().norm() # produces tensor(1.4142e+20, dtype=torch.float64), representa
`float64`(默认情况下 NumPy 所做的)运行计算通常有所帮助,但并不总是解决所有问题。通过`torch.linalg.svdvals()`分析输入的频谱或通过`torch.linalg.cond()`分析它们的条件数可能有助于检测这些问题。
## Nvidia Ampere(以及之后)设备上的 TensorFloat-32(TF32)[](#tensorfloat-32-tf32-on-nvidia-ampere-and-later-devices "跳转到此标题的永久链接")
## Nvidia Ampere(以及之后)设备上的 TensorFloat-32(TF32)
在 Ampere(以及之后)的 Nvidia GPU 上,PyTorch 可以使用 TensorFloat32(TF32)来加速数学密集型操作,特别是矩阵乘法和卷积。当使用 TF32 张量核心执行操作时,只读取输入尾数的前 10 位。这可能会降低精度并产生令人惊讶的结果(例如,将矩阵乘以单位矩阵可能会产生与输入不同的结果)。默认情况下,TF32 张量核心在矩阵乘法中被禁用,并在卷积中启用,尽管大多数神经网络工作负载在使用 TF32 时具有与 fp32 相同的收敛行为。如果您的网络不需要完整的 float32 精度,我们建议通过`torch.backends.cuda.matmul.allow_tf32 = True`启用 TF32 张量核心进行矩阵乘法。如果您的网络在矩阵乘法和卷积中都需要完整的 float32 精度,则可以通过`torch.backends.cudnn.allow_tf32 = False`禁用卷积的 TF32 张量核心。
有关更多信息,请参阅 TensorFloat32。
## FP16 和 BF16 GEMM 的降低精度[](#reduced-precision-reduction-for-fp16-and-bf16-gemms "跳转到此标题的永久链接")
## FP16 和 BF16 GEMM 的降低精度
半精度 GEMM 操作通常使用单精度进行中间累积(降低)以提高数值精度和对溢出的抵抗力。为了性能,某些 GPU 架构,特别是较新的架构,允许将中间累积结果截断为降低精度(例如,半精度)。从模型收敛的角度来看,这种变化通常是良性的,尽管它可能导致意外的结果(例如,当最终结果应该在半精度中表示时出现`inf`值)。如果降低精度的降低造成问题,可以通过`torch.backends.cuda.matmul.allow_fp16_reduced_precision_reduction = False`关闭。
......@@ -58,7 +58,7 @@ BF16 GEMM 操作也有类似的标志,默认情况下是打开的。如果 BF1
有关更多信息,请参阅 allow_fp16_reduced_precision_reduction 和 allow_bf16_reduced_precision_reduction
## 在 AMD Instinct MI200 设备上降低精度的 FP16 和 BF16 GEMMs 和卷积[](#reduced-precision-fp16-and-bf16-gemms-and-convolutions-on-amd-instinct-mi200-devices "跳转到此标题的永久链接")
## 在 AMD Instinct MI200 设备上降低精度的 FP16 和 BF16 GEMMs 和卷积
在 AMD Instinct MI200 GPU 上,FP16 和 BF16 V_DOT2 和 MFMA 矩阵指令会将输入和输出的非规范化值刷新为零。FP32 和 FP64 MFMA 矩阵指令不会将输入和输出的非规范化值刷新为零。受影响的指令仅由 rocBLAS(GEMM)和 MIOpen(卷积)内核使用;所有其他 PyTorch 操作不会遇到这种行为。所有其他支持的 AMD GPU 不会遇到这种行为。
......
......@@ -15,9 +15,9 @@
确定性操作通常比非确定性操作慢,因此您的模型的单次运行性能可能会降低。然而,确定性可能会通过促进实验、调试和回归测试来节省开发时间。
## 控制随机性源[](#controlling-sources-of-randomness "Permalink to this heading")
## 控制随机性源
### PyTorch 随机数生成器[](#pytorch-random-number-generator "Permalink to this heading")
### PyTorch 随机数生成器
您可以使用`torch.manual_seed()`为所有设备(CPU 和 CUDA)设置 RNG 的种子:
......@@ -39,7 +39,7 @@ import random
random.seed(0)
```
### 其他库中的随机数生成器[](#random-number-generators-in-other-libraries "Permalink to this heading")
### 其他库中的随机数生成器
如果您或您正在使用的任何库依赖于 NumPy,您可以使用以下方法为全局 NumPy RNG 设置种子:
......@@ -52,7 +52,7 @@ np.random.seed(0)
如果您正在使用任何其他使用随机数生成器的库,请参考这些库的文档,看看如何为它们设置一致的种子。
### CUDA 卷积基准测试[](#cuda-convolution-benchmarking "Permalink to this heading")
### CUDA 卷积基准测试
由 CUDA 卷积操作使用的 cuDNN 库可能是应用程序多次执行中的不确定性源。当使用新的大小参数集调用 cuDNN 卷积时,一个可选功能可以运行多个卷积算法,并对它们进行基准测试以找到最快的算法。然后,在接下来的过程中,将始终使用最快的算法来处理相应的大小参数集。由于基准测试噪声和不同的硬件,基准测试可能会在后续运行中选择不同的算法,即使在同一台机器上也是如此。
......@@ -62,7 +62,7 @@ np.random.seed(0)
请注意,此设置与下面讨论的`torch.backends.cudnn.deterministic`设置不同。
## 避免非确定性算法[](#avoiding-nondeterministic-algorithms "跳转到此标题")
## 避免非确定性算法
`torch.use_deterministic_algorithms()`允许您配置 PyTorch 使用确定性算法,而不是非确定性算法(如果有的话),并且如果已知某个操作是非确定性的(且没有确定性替代方案),则会引发错误。
......@@ -94,7 +94,7 @@ tensor([[[ 1.1900, -2.3409],
此外,如果您正在使用 CUDA 张量,并且 CUDA 版本为 10.2 或更高,则应根据 CUDA 文档设置环境变量 CUBLAS_WORKSPACE_CONFIG:[`docs.nvidia.com/cuda/cublas/index.html#cublasApi_reproducibility`](https://docs.nvidia.com/cuda/cublas/index.html#cublasApi_reproducibility)
### CUDA 卷积确定性性[](#cuda-convolution-determinism "跳转到此标题")
### CUDA 卷积确定性性
虽然禁用 CUDA 卷积基准测试(如上所述)确保 CUDA 每次运行应用程序时选择相同的算法,但该算法本身可能是非确定性的,除非设置`torch.use_deterministic_algorithms(True)``torch.backends.cudnn.deterministic = True`。后者仅控制此行为,不像`torch.use_deterministic_algorithms()`会使其他 PyTorch 操作也表现出确定性。
......@@ -102,7 +102,7 @@ tensor([[[ 1.1900, -2.3409],
在某些版本的 CUDA 中,RNN 和 LSTM 网络可能具有非确定性行为。有关详细信息和解决方法,请参阅`torch.nn.RNN()``torch.nn.LSTM()`
### 填充未初始化内存[](#filling-uninitialized-memory "跳转到此标题")
### 填充未初始化内存
`torch.empty()``torch.Tensor.resize_()`这样的操作可能返回具有未初始化内存的张量,其中包含未定义的值。如果需要确定性,将这样的张量用作另一个操作的输入是无效的,因为输出将是不确定的。但实际上没有任何东西可以阻止运行这种无效代码。因此,为了安全起见,默认情况下将`torch.utils.deterministic.fill_uninitialized_memory`设置为`True`,如果设置了`torch.use_deterministic_algorithms(True)`,则会使用已知值填充未初始化的内存。这将防止这种非确定性行为的可能性。
......
......@@ -29,7 +29,7 @@
+ 实用函数
## 保存和加载张量[](#saving-and-loading-tensors "跳转到此标题")
## 保存和加载张量
`torch.save()``torch.load()` 让您轻松保存和加载张量:
......@@ -51,7 +51,7 @@ tensor([1., 2.])
{'a': tensor([1., 2.]), 'b': tensor([3., 4.])}
```
如果数据结构是可 pickle 的,那么包含 PyTorch 张量的自定义数据结构也可以保存。## 保存和加载张量保留视图[](#saving-and-loading-tensors-preserves-views "跳转到此标题")
如果数据结构是可 pickle 的,那么包含 PyTorch 张量的自定义数据结构也可以保存。## 保存和加载张量保留视图
保存张量保留它们的视图关系:
......@@ -93,7 +93,7 @@ tensor([ 1, 4, 3, 8, 5, 12, 7, 16, 9])
5
```
然而,由于克隆的张量彼此独立,它们没有原始张量的视图关系。如果在保存比其存储对象小的张量时,文件大小和视图关系都很重要,则必须小心构建新张量,以最小化其存储对象的大小,但仍具有所需的视图关系后再保存。## 保存和加载 torch.nn.Modules[](#saving-and-loading-torch-nn-modules "跳转到此标题")
然而,由于克隆的张量彼此独立,它们没有原始张量的视图关系。如果在保存比其存储对象小的张量时,文件大小和视图关系都很重要,则必须小心构建新张量,以最小化其存储对象的大小,但仍具有所需的视图关系后再保存。## 保存和加载 torch.nn.Modules
参见:[教程:保存和加载模块](https://pytorch.org/tutorials/beginner/saving_loading_models.html)
......@@ -158,7 +158,7 @@ OrderedDict([('l0.weight', tensor([[ 0.1400, 0.4563, -0.0271, -0.4406],
>>> new_m = MyModule()
>>> new_m.load_state_dict(m_state_dict)
<All keys matched successfully>
``` ## 序列化 torch.nn.Modules 并在 C++中加载它们[](#serializing-torch-nn-modules-and-loading-them-in-c "跳转到此标题")
``` ## 序列化 torch.nn.Modules 并在 C++中加载它们
另请参阅:[教程:在 C++中加载 TorchScript 模型](https://pytorch.org/tutorials/advanced/cpp_export.html)
......@@ -217,11 +217,11 @@ tensor(0)
>>> module = torch::jit::load('controlflowmodule_scripted.pt');
```
有关如何在 C++中使用 PyTorch 模块的详细信息,请参阅[PyTorch C++ API 文档](https://pytorch.org/cppdocs/)。## 在 PyTorch 版本间保存和加载 ScriptModules[](#saving-and-loading-scriptmodules-across-pytorch-versions "跳转到此标题")
有关如何在 C++中使用 PyTorch 模块的详细信息,请参阅[PyTorch C++ API 文档](https://pytorch.org/cppdocs/)。## 在 PyTorch 版本间保存和加载 ScriptModules
PyTorch 团队建议使用相同版本的 PyTorch 保存和加载模块。较旧版本的 PyTorch 可能不支持较新的模块,而较新版本可能已删除或修改了较旧的行为。这些更改在 PyTorch 的[发布说明](https://github.com/pytorch/pytorch/releases)中有明确描述,依赖已更改功能的模块可能需要更新才能继续正常工作。在有限的情况下,如下所述,PyTorch 将保留序列化 ScriptModules 的历史行为,因此它们不需要更新。
### torch.div 执行整数除法[](#torch-div-performing-integer-division "跳转到此标题")
### torch.div 执行整数除法
在 PyTorch 1.5 及更早版本中,当给定两个整数输入时,`torch.div()`将执行地板除法:
......@@ -245,7 +245,7 @@ tensor(1.6667)
`torch.div()`的行为在序列化的 ScriptModules 中得到保留。也就是说,使用 PyTorch 1.6 之前版本序列化的 ScriptModules 将继续看到当给定两个整数输入时,`torch.div()`执行地板除法,即使在较新版本的 PyTorch 中加载时也是如此。然而,使用`torch.div()`并在 PyTorch 1.6 及更高版本上序列化的 ScriptModules 无法在较早版本的 PyTorch 中加载,因为这些较早版本不理解新的行为。
### torch.full 总是推断浮点数据类型[](#torch-full-always-inferring-a-float-dtype "跳转到此标题的永久链接")
### torch.full 总是推断浮点数据类型
在 PyTorch 1.5 及更早版本中,`torch.full()`始终返回一个浮点张量,而不管给定的填充值是什么:
......@@ -272,7 +272,7 @@ tensor([1., 1., 1.])
tensor([1.+1.j, 1.+1.j, 1.+1.j])
```
`torch.full()`的行为在序列化的 ScriptModules 中得到保留。也就是说,使用 PyTorch 1.6 之前版本序列化的 ScriptModules 将继续看到 torch.full 默认返回浮点张量,即使给定布尔或整数填充值。然而,使用`torch.full()`并在 PyTorch 1.6 及更高版本上序列化的 ScriptModules 无法在较早版本的 PyTorch 中加载,因为这些较早版本不理解新的行为。## 实用函数[](#utility-functions "跳转到此标题的永久链接")
`torch.full()`的行为在序列化的 ScriptModules 中得到保留。也就是说,使用 PyTorch 1.6 之前版本序列化的 ScriptModules 将继续看到 torch.full 默认返回浮点张量,即使给定布尔或整数填充值。然而,使用`torch.full()`并在 PyTorch 1.6 及更高版本上序列化的 ScriptModules 无法在较早版本的 PyTorch 中加载,因为这些较早版本不理解新的行为。## 实用函数
以下实用函数与序列化相关:
......
......@@ -9,7 +9,7 @@
## 从源代码构建
### 包括可选组件[](#include-optional-components "跳转到此标题的永久链接")
### 包括可选组件
Windows PyTorch 有两个支持的组件:MKL 和 MAGMA。以下是使用它们构建的步骤。
......@@ -37,7 +37,7 @@ set "LIB=%cd%\mkl\lib;%LIB%"
set "MAGMA_HOME=%cd%\magma"
```
### 加速 Windows 的 CUDA 构建[](#speeding-cuda-build-for-windows "跳转到此标题的永久链接")
### 加速 Windows 的 CUDA 构建
Visual Studio 目前不支持并行自定义任务。作为替代方案,我们可以使用 `Ninja` 来并行化 CUDA 构建任务。只需输入几行代码即可使用。
......@@ -78,7 +78,7 @@ ffi = create_extension(
## 安装
### win-32 频道中找不到包。[](#package-not-found-in-win-32-channel "跳转到此标题的永久链接")
### win-32 频道中找不到包。
```py
Solving environment: failed
......@@ -141,7 +141,7 @@ conda install -c defaults intel-openmp -f
## 用法(多进程)
### 没有 if 语句保护的多进程错误[](#multiprocessing-error-without-if-clause-protection "跳转到此标题的永久链接")
### 没有 if 语句保护的多进程错误
```py
RuntimeError:
......@@ -173,7 +173,7 @@ if __name__ == '__main__':
main()
```
### 多进程错误“管道中断”[](#multiprocessing-error-broken-pipe "跳转到此标题的永久链接")
### 多进程错误“管道中断”
```py
ForkingPickler(file, protocol).dump(obj)
......@@ -183,7 +183,7 @@ BrokenPipeError: [Errno 32] Broken pipe
当子进程在父进程完成发送数据之前结束时,就会出现这个问题。您的代码可能有问题。您可以通过将 `DataLoader``num_worker` 减少到零来调试您的代码,看看问题是否仍然存在。
### 多进程错误“驱动程序关闭”[](#multiprocessing-error-driver-shut-down "跳转到此标题的永久链接")
### 多进程错误“驱动程序关闭”
```py
Couldnt open shared file mapping: <torch_14808_1591070686>, error code: <1455> at torch\lib\TH\THAllocator.c:154
......
......@@ -23,7 +23,7 @@ PyTorch 提供了几个用于处理 C++的功能,最好根据您的需求选
+ 使用 C++ Tensor API 构建输入并进行预处理
## 使用 C++扩展扩展 PyTorch 和 TorchScript[](#extending-pytorch-and-torchscript-with-c-extensions "跳转到此标题的永久链接")
## 使用 C++扩展扩展 PyTorch 和 TorchScript
TorchScript 可以通过自定义运算符和自定义类增强用户提供的代码。一旦在 TorchScript 中注册了这些运算符和类,这些运算符和类可以在 Python 中运行的 TorchScript 代码中被调用,或者作为序列化的 TorchScript 模型的一部分在 C++中被调用。[使用自定义 C++运算符扩展 TorchScript](https://pytorch.org/tutorials/advanced/torch_script_custom_ops.html)教程介绍了如何将 TorchScript 与 OpenCV 进行接口。除了使用自定义运算符包装函数调用外,C++类和结构体还可以通过类似于 pybind11 的接口绑定到 TorchScript 中,这在[使用自定义 C++类扩展 TorchScript](https://pytorch.org/tutorials/advanced/torch_script_custom_classes.html)教程中有解释。
......
......@@ -68,7 +68,7 @@ torch 包含用于多维张量的数据结构,并定义了这些张量上的
| `complex` | 构造一个复数张量,其实部等于`real`,虚部等于`imag`。 |
| `polar` | 构造一个复数张量,其元素是对应于绝对值`abs`和角度`angle`的极坐标。 |
| `heaviside` | 计算`input`中每个元素的 Heaviside 阶跃函数。 | ### 索引、切片、连接、变异操作[](#indexing-slicing-joining-mutating-ops "跳转到此标题的永久链接")
| `heaviside` | 计算`input`中每个元素的 Heaviside 阶跃函数。 | ### 索引、切片、连接、变异操作
| `adjoint` | 返回一个共轭并且最后两个维度转置的张量视图。 |
| --- | --- |
......@@ -123,7 +123,7 @@ torch 包含用于多维张量的数据结构,并定义了这些张量上的
| `where` | 根据`condition`从`input`或`other`中选择元素并返回张量。 |
| `Generator` | 创建并返回一个生成器对象,该对象管理产生伪随机数的算法的状态。 | ## 随机抽样[](#random-sampling "Permalink to this heading")
| `Generator` | 创建并返回一个生成器对象,该对象管理产生伪随机数的算法的状态。 | ## 随机抽样
| `seed` | 将生成随机数的种子设置为非确定性随机数。 |
| --- | --- |
......@@ -149,7 +149,7 @@ torch.default_generator Returns the default CPU torch.Generator
| `randn_like` | 返回与`input`相同大小的张量,其中填充有来自均值为 0,方差为 1 的正态分布的随机数。 |
| `randperm` | 返回从`0`到`n - 1`的整数的随机排列。 |
### 就地随机抽样[](#in-place-random-sampling "Permalink to this heading")
### 就地随机抽样
还有一些在张量上定义的就地随机抽样函数。点击查看它们的文档:
......@@ -188,7 +188,7 @@ torch.default_generator Returns the default CPU torch.Generator
| `get_num_interop_threads` | 返回在 CPU 上用于互操作并行性的线程数(例如 |
| `set_num_interop_threads` | 设置用于互操作并行性的线程数(例如 |
## 本地禁用梯度计算[](#locally-disabling-gradient-computation "Permalink to this heading")
## 本地禁用梯度计算
上下文管理器 `torch.no_grad()`、`torch.enable_grad()` 和 `torch.set_grad_enabled()` 对于本地禁用和启用梯度计算非常有用。有关它们的使用详情,请参阅本地禁用梯度计算。这些上下文管理器是线程局部的,因此如果使用 `threading` 模块等将工作发送到另一个线程,则它们将无法工作。
......
......@@ -135,7 +135,7 @@ torch.nn
| `nn.ConstantPad2d` | 使用常数值填充输入张量的边界。 |
| `nn.ConstantPad3d` | 使用常数值填充输入张量的边界。 |
## 非线性激活函数(加权和,非线性)[](#non-linear-activations-weighted-sum-nonlinearity "跳转到此标题")
## 非线性激活函数(加权和,非线性)
| `nn.ELU` | 对每个元素应用指数线性单元(ELU)函数,如论文中所述:[通过指数线性单元(ELUs)实现快速准确的深度网络学习](https://arxiv.org/abs/1511.07289)。 |
| --- | --- |
......@@ -282,12 +282,12 @@ torch.nn
| `nn.ChannelShuffle` | 分割并重新排列张量中的通道。 |
| --- | --- |
## 数据并行层(多 GPU,分布式)[](#module-torch.nn.parallel "跳转到此标题的永久链接")
## 数据并行层(多 GPU,分布式)
| `nn.DataParallel` | 在模块级别实现数据并行。 |
| --- | --- |
| `nn.parallel.DistributedDataParallel` | 在模块级别基于`torch.distributed`实现分布式数据并行。 | ## 实用工具[](#module-torch.nn.utils "跳转到此标题的永久链接")
| `nn.parallel.DistributedDataParallel` | 在模块级别基于`torch.distributed`实现分布式数据并行。 | ## 实用工具
来自`torch.nn.utils`模块:
......@@ -389,7 +389,7 @@ torch.nn
量化是指在比浮点精度更低的比特宽度上执行计算和存储张量的技术。PyTorch 支持每个张量和每个通道的非对称线性量化。要了解如何在 PyTorch 中使用量化函数,请参阅量化文档。
## 延迟模块初始化[](#lazy-modules-initialization "跳转到此标题")
## 延迟模块初始化
| `nn.modules.lazy.LazyModuleMixin` | 用于延迟初始化参数的模块混合,也称为“延迟模块”。 |
| --- | --- |
......@@ -47,7 +47,7 @@
| `scaled_dot_product_attention` | 在查询、键和值张量上计算缩放点积注意力,如果传递了可选的注意力掩码,则应用 dropout,如果指定了大于 0.0 的概率。 |
| --- | --- |
## 非线性激活函数[](#non-linear-activation-functions "跳转到此标题")
## 非线性激活函数
| `threshold` | 对输入张量的每个元素应用阈值。 |
| --- | --- |
......@@ -159,7 +159,7 @@
| `grid_sample` | 计算网格采样。 |
| `affine_grid` | 给定一批仿射矩阵`theta`,生成 2D 或 3D 流场(采样网格)。 |
## DataParallel functions (multi-GPU, distributed)[](#dataparallel-functions-multi-gpu-distributed "Permalink to this heading")
## DataParallel functions (multi-GPU, distributed)
### data_parallel
......
......@@ -47,7 +47,7 @@ Torch 定义了 10 种张量类型,包括 CPU 和 GPU 变体,如下所示:
`torch.Tensor` 是默认张量类型(`torch.FloatTensor`)的别名。
## 初始化和基本操作[](#initializing-and-basic-operations "跳转到此标题的永久链接")
## 初始化和基本操作
可以使用`torch.tensor()`构造来自 Python [`list`](https://docs.python.org/3/library/stdtypes.html#list "(在 Python v3.12 中)") 或序列的张量:
......
......@@ -241,7 +241,7 @@ torch.cuda.amp.custom_bwd(bwd)
class torch.cpu.amp.autocast(enabled=True, dtype=torch.bfloat16, cache_enabled=True)
```
请参见`torch.autocast``torch.cpu.amp.autocast(args...)`等同于`torch.autocast("cpu", args...)` ## 梯度缩放[](#gradient-scaling "跳转到此标题")
请参见`torch.autocast``torch.cpu.amp.autocast(args...)`等同于`torch.autocast("cpu", args...)` ## 梯度缩放
如果特定操作的前向传递具有`float16`输入,则该操作的反向传递将产生`float16`梯度。具有较小幅度的梯度值可能无法在`float16`中表示。这些值将刷新为零(“下溢”),因此相应参数的更新将丢失。
......@@ -548,7 +548,7 @@ update(new_scale=None)
警告
出于性能原因,我们不检查比例因子的值以避免同步,因此不能保证比例因子大于 1。如果比例低于 1 和/或在梯度或损失中看到 NaN,则可能有问题。例如,由于动态范围不同,bf16 预训练模型通常与 AMP/fp16 不兼容。 ## 自动混合精度操作参考[](#autocast-op-reference "跳转到此标题")
出于性能原因,我们不检查比例因子的值以避免同步,因此不能保证比例因子大于 1。如果比例低于 1 和/或在梯度或损失中看到 NaN,则可能有问题。例如,由于动态范围不同,bf16 预训练模型通常与 AMP/fp16 不兼容。 ## 自动混合精度操作参考
### 操作资格
......@@ -556,7 +556,7 @@ update(new_scale=None)
只有不改变原始数据的操作和张量方法才符合条件。在启用自动混合精度的区域中,可以使用就地变体和显式提供 `out=...` 张量的调用,但不会经过自动混合精度。例如,在启用自动混合精度的区域中,`a.addmm(b, c)` 可以自动混合精度,但 `a.addmm_(b, c)``a.addmm(b, c, out=d)` 不能。为了获得最佳性能和稳定性,请在启用自动混合精度的区域中使用不改变原始数据的操作。
使用显式 `dtype=...` 参数调用的操作不符合条件,并将生成符合 `dtype` 参数的输出。 ### CUDA 操作特定行为[](#cuda-op-specific-behavior "跳转到此标题")
使用显式 `dtype=...` 参数调用的操作不符合条件,并将生成符合 `dtype` 参数的输出。 ### CUDA 操作特定行为
以下列表描述了在启用自动混合精度的区域中符合条件的操作的行为。这些操作总是经过自动混合精度,无论它们作为 `torch.nn.Module` 的一部分调用,作为一个函数调用,还是作为 `torch.Tensor` 方法调用。如果函数在多个命名空间中公开,无论命名空间如何,它们都会经过自动混合精度。
......@@ -564,15 +564,15 @@ update(new_scale=None)
如果某个操作未列出,我们会假定它在 `float16` 中是数值稳定的。如果您认为某个未列出的操作在 `float16` 中是数值不稳定的,请提交一个问题。
#### 可以自动混合精度为 `float16` 的 CUDA 操作[](#cuda-ops-that-can-autocast-to-float16 "跳转到此标题")
#### 可以自动混合精度为 `float16` 的 CUDA 操作
`__matmul__`, `addbmm`, `addmm`, `addmv`, `addr`, `baddbmm`, `bmm`, `chain_matmul`, `multi_dot`, `conv1d`, `conv2d`, `conv3d`, `conv_transpose1d`, `conv_transpose2d`, `conv_transpose3d`, `GRUCell`, `linear`, `LSTMCell`, `matmul`, `mm`, `mv`, `prelu`, `RNNCell`
#### 可以自动混合精度为 `float32` 的 CUDA 操作[](#cuda-ops-that-can-autocast-to-float32 "跳转到此标题的永久链接")
#### 可以自动混合精度为 `float32` 的 CUDA 操作
`__pow__`, `__rdiv__`, `__rpow__`, `__rtruediv__`, `acos`, `asin`, `binary_cross_entropy_with_logits`, `cosh`, `cosine_embedding_loss`, `cdist`, `cosine_similarity`, `cross_entropy`, `cumprod`, `cumsum`, `dist`, `erfinv`, `exp`, `expm1`, `group_norm`, `hinge_embedding_loss`, `kl_div`, `l1_loss`, `layer_norm`, `log`, `log_softmax`, `log10`, `log1p`, `log2`, `margin_ranking_loss`, `mse_loss`, `multilabel_margin_loss`, `multi_margin_loss`, `nll_loss`, `norm`, `normalize`, `pdist`, `poisson_nll_loss`, `pow`, `prod`, `reciprocal`, `rsqrt`, `sinh`, `smooth_l1_loss`, `soft_margin_loss`, `softmax`, `softmin`, `softplus`, `sum`, `renorm`, `tan`, `triplet_margin_loss`
#### CUDA 操作会将输入类型提升为最宽的类型[](#cuda-ops-that-promote-to-the-widest-input-type "跳转到此标题")
#### CUDA 操作会将输入类型提升为最宽的类型
这些操作不需要特定的 dtype 来保持稳定性,但需要多个输入并要求输入的 dtype 匹配。如果所有输入都是`float16`,则操作将在`float16`中运行。如果任何输入是`float32`,自动转换将所有输入转换为`float32`并在`float32`中运行操作。
......@@ -580,11 +580,11 @@ update(new_scale=None)
这里未列出的一些操作(例如,`add`等二元操作)会在没有自动转换干预的情况下自然提升输入。如果输入是`float16``float32`的混合,这些操作将在`float32`中运行并产生`float32`输出,无论自动转换是否启用。
#### 优先使用`binary_cross_entropy_with_logits`而不是`binary_cross_entropy`[](#prefer-binary-cross-entropy-with-logits-over-binary-cross-entropy "跳转到此标题")
#### 优先使用`binary_cross_entropy_with_logits`而不是`binary_cross_entropy`
`torch.nn.functional.binary_cross_entropy()`的反向传播(以及包装它的`torch.nn.BCELoss`)可能会产生在`float16`中无法表示的梯度。在启用自动转换的区域中,前向输入可能是`float16`,这意味着反向梯度必须在`float16`中表示(将`float16`前向输入自动转换为`float32`是没有帮助的,因为这种转换在反向传播中必须被逆转)。因此,在启用自动转换的区域中,`binary_cross_entropy``BCELoss`会引发错误。
许多模型在二元交叉熵层之前使用一个 sigmoid 层。在这种情况下,使用`torch.nn.functional.binary_cross_entropy_with_logits()``torch.nn.BCEWithLogitsLoss`结合这两个层。`binary_cross_entropy_with_logits``BCEWithLogits`可以安全地进行自动转换。 ### CPU 操作特定行为[](#cpu-op-specific-behavior "跳转到此标题")
许多模型在二元交叉熵层之前使用一个 sigmoid 层。在这种情况下,使用`torch.nn.functional.binary_cross_entropy_with_logits()``torch.nn.BCEWithLogitsLoss`结合这两个层。`binary_cross_entropy_with_logits``BCEWithLogits`可以安全地进行自动转换。 ### CPU 操作特定行为
以下列表描述了在启用自动转换的区域中合格操作的行为。这些操作始终经过自动转换,无论它们是作为`torch.nn.Module`的一部分、作为函数还是作为`torch.Tensor`方法调用。如果函数在多个命名空间中公开,无论命名空间如何,它们都会经过自动转换。
......@@ -592,15 +592,15 @@ update(new_scale=None)
如果一个操作未列出,我们假定它在`bfloat16`中是数值稳定的。如果您认为未列出的操作在`bfloat16`中是数值不稳定的,请提交一个问题。
#### CPU 操作可以自动转换为`bfloat16`[](#cpu-ops-that-can-autocast-to-bfloat16 "跳转到此标题")
#### CPU 操作可以自动转换为`bfloat16`
`conv1d``conv2d``conv3d``bmm``mm``baddbmm``addmm``addbmm``linear``matmul``_convolution`
#### 可以自动转换为`float32`的 CPU 操作[](#cpu-ops-that-can-autocast-to-float32 "跳转到此标题的永久链接")
#### 可以自动转换为`float32`的 CPU 操作
`conv_transpose1d``conv_transpose2d``conv_transpose3d``avg_pool3d``binary_cross_entropy``grid_sampler``grid_sampler_2d``_grid_sampler_2d_cpu_fallback``grid_sampler_3d``polar``prod``quantile``nanquantile``stft``cdist``trace``view_as_complex``cholesky``cholesky_inverse``cholesky_solve``inverse``lu_solve``orgqr``inverse``ormqr``pinverse``max_pool3d``max_unpool2d``max_unpool3d``adaptive_avg_pool3d``reflection_pad1d``reflection_pad2d``replication_pad1d``replication_pad2d``replication_pad3d``mse_loss``ctc_loss``kl_div``multilabel_margin_loss``fft_fft``fft_ifft``fft_fft2``fft_ifft2``fft_fftn``fft_ifftn``fft_rfft``fft_irfft``fft_rfft2``fft_irfft2``fft_rfftn``fft_irfftn``fft_hfft``fft_ihfft``linalg_matrix_norm``linalg_cond``linalg_matrix_rank``linalg_solve``linalg_cholesky``linalg_svdvals``linalg_eigvals``linalg_eigvalsh``linalg_inv``linalg_householder_product``linalg_tensorinv``linalg_tensorsolve``fake_quantize_per_tensor_affine``eig``geqrf``lstsq``_lu_with_info``qr``solve``svd``symeig``triangular_solve``fractional_max_pool2d``fractional_max_pool3d``adaptive_max_pool3d``multilabel_margin_loss_forward``linalg_qr``linalg_cholesky_ex``linalg_svd``linalg_eig``linalg_eigh``linalg_lstsq``linalg_inv_ex`
#### 将输入类型提升为最宽的 CPU 操作[](#cpu-ops-that-promote-to-the-widest-input-type "跳转到此标题的永久链接")
#### 将输入类型提升为最宽的 CPU 操作
这些操作不需要特定的 dtype 来保持稳定性,但需要多个输入并要求输入的 dtypes 匹配。如果所有输入都是`bfloat16`,则该操作将在`bfloat16`中运行。如果任何输入是`float32`,自动转换将将所有输入转换为`float32`并在`float32`中运行该操作。
......
......@@ -13,7 +13,7 @@
| --- | --- |
| `grad` | 计算并返回输出相对于输入的梯度之和。 |
## 前向模式自动微分[](#forward-mode-automatic-differentiation "跳转到此标题")
## 前向模式自动微分
警告
......@@ -25,7 +25,7 @@
| --- | --- |
| `forward_ad.make_dual` | 将张量值与其切线关联起来,创建一个用于前向 AD 梯度计算的“双重张量”。 |
| `forward_ad.unpack_dual` | 解包“双重张量”,获取其张量值和前向 AD 梯度。| ## 功能高级 API[](#functional-higher-level-api "跳转到此标题")
| `forward_ad.unpack_dual` | 解包“双重张量”,获取其张量值和前向 AD 梯度。| ## 功能高级 API
警告
......@@ -42,7 +42,7 @@
| `functional.jvp` | 计算给定函数在输入点处的 Jacobian 矩阵与向量 `v` 的点积。 |
| `functional.vhp` | 计算向量`v`与给定标量函数在指定点处的 Hessian 的点积。 |
| `functional.hvp` | 计算标量函数的 Hessian 和向量`v`在指定点处的点积。 |## 本地禁用梯度计算[](#locally-disabling-gradient-computation "跳转到此标题的永久链接")
| `functional.hvp` | 计算标量函数的 Hessian 和向量`v`在指定点处的点积。 |## 本地禁用梯度计算
有关无梯度和推断模式之间的区别以及可能与两者混淆的其他相关机制的更多信息,请参阅本地禁用梯度计算。还请参阅本地禁用梯度计算以获取可用于本地禁用梯度的函数列表。## 默认梯度布局
......@@ -78,11 +78,11 @@ for iterations...
如果您需要手动控制`.grad`的步幅,在第一次`backward()`之前将`param.grad =`分配为具有所需步幅的零张量,并永远不要将其重置为`None`。3 保证只要`create_graph=False`,您的布局就会被保留。4 表明即使`create_graph=True`,您的布局也*可能*会被保留。
## 张量的原地操作[](#in-place-operations-on-tensors "跳转到此标题的永久链接")
## 张量的原地操作
在 autograd 中支持原地操作是一个棘手的问题,我们不鼓励在大多数情况下使用它们。Autograd 的积极缓冲区释放和重用使其非常高效,只有在极度内存压力下,才有很少的情况下原地操作实际上会显著降低内存使用量。除非您在极度内存压力下操作,否则您可能永远不需要使用它们。
### 原地正确性检查[](#in-place-correctness-checks "跳转到此标题的永久链接")
### 原地正确性检查
所有`Tensor`都会跟踪应用于它们的原地操作,如果实现检测到一个张量在其中一个函数中保存以进行反向传播,但之后在原地进行修改,那么一旦开始反向传播,就会引发错误。这确保了如果您使用原地函数而没有看到任何错误,您可以确信计算的梯度是正确的。
......@@ -164,7 +164,7 @@ class torch.autograd.Function(*args, **kwargs)
| `function.FunctionCtx.save_for_backward` | 保存给定张量,以便将来调用`backward()`。 |
| `function.FunctionCtx.set_materialize_grads` | 设置是否实现梯度张量。 |
## 数值梯度检查[](#module-torch.autograd.gradcheck "Permalink to this heading")
## 数值梯度检查
| `gradcheck` | 检查通过小的有限差分计算的梯度与`inputs`中的浮点或复数类型张量相对于解析梯度的梯度,这些张量具有`requires_grad=True`。 |
| --- | --- |
......
......@@ -110,7 +110,7 @@ CUDA 语义有关使用 CUDA 的更多详细信息。
| `CUDAPluggableAllocator` | 从 so 文件加载的 CUDA 内存分配器。 |
| `change_current_allocator` | 将当前使用的内存分配器更改为提供的内存分配器。 |
## NVIDIA 工具扩展(NVTX)[](#nvidia-tools-extension-nvtx "跳转到此标题")
## NVIDIA 工具扩展(NVTX)
| `nvtx.mark` | 描述在某个时间点发生的瞬时事件。 |
| --- | --- |
......@@ -123,6 +123,6 @@ CUDA 语义有关使用 CUDA 的更多详细信息。
| --- | --- |
| `jiterator._create_multi_output_jit_fn` | 创建一个由 jiterator 生成的 cuda 内核,用于支持返回一个或多个输出的逐元素操作。 |
## 流消毒器(原型)[](#stream-sanitizer-prototype "跳转到此标题的永久链接")
## 流消毒器(原型)
CUDA 消毒器是一个用于检测 PyTorch 中流之间同步错误的原型工具。请查看文档以获取如何使用它的信息。
......@@ -279,7 +279,7 @@ torch.backends.cuda.sdp_kernel(enable_flash=True, enable_math=True, enable_mem_e
此标志为测试版,可能会更改。
此上下文管理器可用于临时启用或禁用缩放点积注意力的三个后端之一。退出上下文管理器时,将恢复标志的先前状态。## torch.backends.cudnn[](#module-torch.backends.cudnn "Permalink to this heading")
此上下文管理器可用于临时启用或禁用缩放点积注意力的三个后端之一。退出上下文管理器时,将恢复标志的先前状态。## torch.backends.cudnn
```py
torch.backends.cudnn.version()
......@@ -321,7 +321,7 @@ torch.backends.cudnn.benchmark
torch.backends.cudnn.benchmark_limit
```
一个[`int`](https://docs.python.org/3/library/functions.html#int "(在 Python v3.12 中)"),指定 torch.backends.cudnn.benchmark 为 True 时尝试的 cuDNN 卷积算法的最大数量。将 benchmark_limit 设置为零以尝试每个可用算法。请注意,此设置仅影响通过 cuDNN v8 API 分派的卷积。 ## torch.backends.mps[](#module-torch.backends.mps "跳转到此标题的永久链接")
一个[`int`](https://docs.python.org/3/library/functions.html#int "(在 Python v3.12 中)"),指定 torch.backends.cudnn.benchmark 为 True 时尝试的 cuDNN 卷积算法的最大数量。将 benchmark_limit 设置为零以尝试每个可用算法。请注意,此设置仅影响通过 cuDNN v8 API 分派的卷积。 ## torch.backends.mps
```py
torch.backends.mps.is_available()
......@@ -368,7 +368,7 @@ with torch.backends.mkl.verbose(torch.backends.mkl.VERBOSE_ON):
参数
**level** – 详细级别 - `VERBOSE_OFF`:禁用详细 - `VERBOSE_ON`:启用详细 ## torch.backends.mkldnn[](#module-torch.backends.mkldnn "跳转到此标题的永久链接")
**level** – 详细级别 - `VERBOSE_OFF`:禁用详细 - `VERBOSE_ON`:启用详细 ## torch.backends.mkldnn
```py
torch.backends.mkldnn.is_available()
......@@ -393,13 +393,13 @@ with torch.backends.mkldnn.verbose(torch.backends.mkldnn.VERBOSE_ON):
参数
**level** – 详细级别 - `VERBOSE_OFF`:禁用详细 - `VERBOSE_ON`:启用详细 - `VERBOSE_ON_CREATION`:启用详细,包括 oneDNN 内核创建 ## torch.backends.openmp[](#module-torch.backends.openmp "跳转到此标题的永久链接")
**level** – 详细级别 - `VERBOSE_OFF`:禁用详细 - `VERBOSE_ON`:启用详细 - `VERBOSE_ON_CREATION`:启用详细,包括 oneDNN 内核创建 ## torch.backends.openmp
```py
torch.backends.openmp.is_available()
```
返回 PyTorch 是否构建有 OpenMP 支持。 ## torch.backends.opt_einsum[](#module-torch.backends.opt_einsum "跳转到此标题")
返回 PyTorch 是否构建有 OpenMP 支持。 ## torch.backends.opt_einsum
```py
torch.backends.opt_einsum.is_available()
......
......@@ -357,7 +357,7 @@ ExportedProgram:
由于整数是专门化的,`torch.ops.aten.add.Tensor`操作都是使用内联常量`1`计算的,而不是`arg1_1`。此外,在`for`循环中使用的`times`迭代器也通过 3 个重复的`torch.ops.aten.add.Tensor`调用“内联”在图中,并且输入`arg2_1`从未被使用。
## torch.export[](#limitations-of-torch-export "此标题的永久链接")的限制
## torch.export的限制
### 图中断
......@@ -365,11 +365,11 @@ ExportedProgram:
当遇到图形中断时,ExportDB 是一个很好的资源,可以了解支持和不支持的程序类型,以及重写程序使其可追踪的方法。
### 数据/形状相关的控制流[](#data-shape-dependent-control-flow "跳转到此标题")
### 数据/形状相关的控制流
当遇到数据相关的控制流(`if x.shape[0] > 2`)时,也可能出现图形中断,因为在没有专门化形状的情况下,追踪编译器无法处理生成代码的组合爆炸路径。在这种情况下,用户需要使用特殊的控制流操作符重写他们的代码。目前,我们支持 torch.cond 来表达类似 if-else 的控制流(更多功能即将推出!)。
### 操作符缺失的元内核[](#missing-meta-kernels-for-operators "跳转到此标题")
### 操作符缺失的元内核
在追踪时,所有操作符都需要一个 META 实现(或“元内核”)来推断该操作符的输入/输出形状。
......
......@@ -31,7 +31,7 @@
| all_to_all | ✘ | ✘ | ✓ | ? | ✘ | ✓ |
| barrier | ✓ | ✘ | ✓ | ? | ✘ | ✓ |
### PyTorch 附带的后端[](#backends-that-come-with-pytorch "跳转到此标题")
### PyTorch 附带的后端
PyTorch 分布式包支持 Linux(稳定)、MacOS(稳定)和 Windows(原型)。默认情况下,对于 Linux,Gloo 和 NCCL 后端已构建并包含在 PyTorch 分布式中(仅在使用 CUDA 构建时才包括 NCCL)。MPI 是一个可选的后端,只有在从源代码构建 PyTorch 时才能包含(例如,在安装了 MPI 的主机上构建 PyTorch)。
......@@ -71,9 +71,9 @@ PyTorch 分布式包支持 Linux(稳定)、MacOS(稳定)和 Windows(
+ 除非有特定原因要使用 MPI,否则请使用 Gloo。
### 常见环境变量[](#common-environment-variables "跳转到此标题")
### 常见环境变量
#### 选择要使用的网络接口[](#choosing-the-network-interface-to-use "跳转到此标题")
#### 选择要使用的网络接口
默认情况下,NCCL 和 Gloo 后端都会尝试找到正确的网络接口。如果自动检测到的接口不正确,您可以使用以下环境变量覆盖它(适用于相应的后端):
......@@ -410,7 +410,7 @@ torch.distributed.get_world_size(group=None)
* * *
## 分布式键值存储[](#distributed-key-value-store "跳转到此标题")
## 分布式键值存储
分布式包带有一个分布式键值存储,可用于在组中的进程之间共享信息,以及在`torch.distributed.init_process_group()`中初始化分布式包(通过显式创建存储作为指定`init_method`的替代方法)。有 3 种键值存储选择:`TCPStore``FileStore``HashStore`
......@@ -1928,7 +1928,7 @@ class torch.distributed.reduce_op
建议使用`ReduceOp`
## 集合通信性能分析[](#profiling-collective-communication "跳转到此标题")
## 集合通信性能分析
请注意,您可以使用`torch.profiler`(推荐,仅在 1.8.1 之后可用)或`torch.autograd.profiler`来分析此处提到的集合通信和点对点通信 API。所有开箱即用的后端(`gloo``nccl``mpi`)都受支持,并且集合通信的使用将如预期般呈现在分析输出/跟踪中。对您的代码进行分析与任何常规 torch 运算符相同:
......@@ -1942,7 +1942,7 @@ with torch.profiler():
有关分析器功能的完整概述,请参阅[分析器文档](https://pytorch.org/docs/main/profiler.html)
## 多 GPU 集合功能[](#multi-gpu-collective-functions "跳转到此标题")
## 多 GPU 集合功能
警告
......@@ -2072,7 +2072,7 @@ Multiprocessing package - torch.multiprocessing 包还提供了一个在`torch.m
请注意,此函数要求 Python 3.4 或更高版本。
## 调试`torch.distributed`应用程序[](#debugging-torch-distributed-applications "跳转到此标题的永久链接")
## 调试`torch.distributed`应用程序
由于难以理解的挂起、崩溃或在等级之间的不一致行为,调试分布式应用程序可能具有挑战性。`torch.distributed`提供了一套工具来帮助以自助方式调试训练应用程序:
......
......@@ -3259,7 +3259,7 @@ register_kl(DerivedP, DerivedQ)(kl_version1) # Break the tie.
+ **type_p**[*type*](https://docs.python.org/3/library/functions.html#type "(in Python v3.12)")) - `Distribution` 的子类。
+ **type_q**[*type*](https://docs.python.org/3/library/functions.html#type "(in Python v3.12)")) - `Distribution` 的子类。## 转换[](#module-torch.distributions.transforms "Permalink to this heading")
+ **type_q**[*type*](https://docs.python.org/3/library/functions.html#type "(in Python v3.12)")) - `Distribution` 的子类。## 转换
```py
class torch.distributions.transforms.AbsTransform(cache_size=0)
......@@ -3512,7 +3512,7 @@ forward_shape(shape)
inverse_shape(shape)
```
推断逆计算的形状,给定输出形状。默认保留形状。 ## 约束[](#module-torch.distributions.constraints "Permalink to this heading")
推断逆计算的形状,给定输出形状。默认保留形状。 ## 约束
以下约束已实现:
......@@ -3656,7 +3656,7 @@ torch.distributions.constraints.multinomial
torch.distributions.constraints.stack
```
别名为`_Stack` ## 约束注册[](#module-torch.distributions.constraint_registry "Permalink to this heading")
别名为`_Stack` ## 约束注册
PyTorch 提供了两个全局`ConstraintRegistry`对象,将`Constraint`对象链接到`Transform`对象。这些对象都输入约束并返回变换,但它们对双射性有不同的保证。
......
......@@ -15,7 +15,7 @@ torch.func,以前称为“functorch”,是 PyTorch 的[JAX-like](https://git
如果您对 API 或用例有建议,请打开 GitHub 问题或联系我们。我们很乐意听听您如何使用库。
## 什么是可组合的函数变换?[](#what-are-composable-function-transforms "跳转到此标题")
## 什么是可组合的函数变换?
+ “函数变换”是一个高阶函数,接受一个数值函数并返回一个计算不同量的新函数。
......@@ -23,7 +23,7 @@ torch.func,以前称为“functorch”,是 PyTorch 的[JAX-like](https://git
+ 这些函数变换可以任意组合。例如,组合`vmap(grad(f))`计算一种称为每样本梯度的量,目前原始 PyTorch 无法高效计算。
## 为什么使用可组合的函数变换?[](#why-composable-function-transforms "跳转到此标题")
## 为什么使用可组合的函数变换?
目前在 PyTorch 中有一些棘手的用例:
......
......@@ -224,7 +224,7 @@ with traced.graph.inserting_after(node):
FX 还提供了另一种自动化级别,即在直接图操作之上。`replace_pattern()` API 本质上是一个用于编辑`Graph`的“查找/替换”工具。它允许您指定一个`pattern`和一个`replacement`函数,然后将跟踪这些函数,查找`pattern`图中操作组的实例,并用`replacement`图的副本替换这些实例。这可以帮助大大自动化繁琐的图操作代码,随着转换变得更复杂,这些代码可能变得难以控制。
#### 图操作示例[](#graph-manipulation-examples "跳转到此标题")
#### 图操作示例
+ [替换一个操作](https://github.com/pytorch/examples/blob/master/fx/replace_op.py)
......@@ -361,7 +361,7 @@ class ShapeProp:
除了执行操作,我们还可以通过将`Proxy`值通过解释器来生成一个新的 Graph。类似地,我们提供了`Transformer`类来包含这种模式。`Transformer`的行为类似于`Interpreter`,但是不是调用`run`方法从模块中获取具体的输出值,而是调用`Transformer.transform()`方法返回一个经过您安装的任何转换规则的新的`GraphModule`
#### 解释器模式的示例[](#examples-of-the-interpreter-pattern "跳转到此标题")
#### 解释器模式的示例
+ [形状传播](https://github.com/pytorch/pytorch/blob/master/torch/fx/passes/shape_prop.py)
......@@ -375,11 +375,11 @@ class ShapeProp:
如果您对调试器不熟悉,请参阅辅助部分可用调试器。
### 转换作者常见的陷阱[](#common-pitfalls-in-transform-authoring "跳转到此标题")
### 转换作者常见的陷阱
+ 非确定性的`set`迭代顺序。在 Python 中,`set`数据类型是无序的。例如,使用`set`来包含像`Node`这样的对象集合可能会导致意外的非确定性。一个例子是遍历一组`Node`并将它们插入到`Graph`中。因为`set`数据类型是无序的,输出程序中操作的顺序将是非确定性的,并且可能会在程序调用时发生变化。推荐的替代方案是使用`dict`数据类型,它在 Python 3.7(以及 cPython 3.6)中是[插入有序的](https://mail.python.org/pipermail/python-dev/2017-December/151283.html)。可以通过将要去重的值存储在`dict`的键中来等效地使用`dict`来代替`set`
### 检查模块正确性[](#checking-correctness-of-modules "跳转到此标题")
### 检查模块正确性
由于大多数深度学习模块的输出由浮点`torch.Tensor`实例组成,检查两个`torch.nn.Module`的结果是否等价并不像进行简单的相等性检查那样直接。为了激励这一点,让我们举个例子:
......@@ -585,7 +585,7 @@ print(transformed)
最常见的 Python 调试器是[pdb](https://docs.python.org/3/library/pdb.html)。您可以通过在命令行中键入`python -m pdb FILENAME.py`来以`pdb`的“调试模式”启动程序,其中`FILENAME`是您要调试的文件的名称。之后,您可以使用`pdb`[调试器命令](https://docs.python.org/3/library/pdb.html#debugger-commands)逐步浏览正在运行的程序。当您启动`pdb`时设置断点(`b LINE-NUMBER`)是很常见的,然后调用`c`运行程序直到那一点。这样可以避免您必须逐行执行(使用`s``n`)以到达您想要检查的代码部分。或者,您可以在要中断的行之前写入`import pdb; pdb.set_trace()`。如果添加了`pdb.set_trace()`,当您运行程序时,它将自动以调试模式启动。 (换句话说,您只需在命令行中键入`python FILENAME.py`,而不是`python -m pdb FILENAME.py`。)运行文件时,您可以通过使用特定命令逐步执行代码并检查程序的内部状态。有许多关于`pdb`的优秀教程在线,包括 RealPython 的[“使用 Pdb 进行 Python 调试”](https://realpython.com/python-debugging-pdb/)
像 PyCharm 或 VSCode 这样的 IDE 通常内置了调试器。在您的 IDE 中,您可以选择要么 a)通过在 IDE 中打开终端窗口(例如在 VSCode 中选择 View → Terminal)使用`pdb`,要么 b)使用内置调试器(通常是围绕`pdb`的图形包装器)。## 符号跟踪的限制[](#limitations-of-symbolic-tracing "跳转到此标题的永久链接")
像 PyCharm 或 VSCode 这样的 IDE 通常内置了调试器。在您的 IDE 中,您可以选择要么 a)通过在 IDE 中打开终端窗口(例如在 VSCode 中选择 View → Terminal)使用`pdb`,要么 b)使用内置调试器(通常是围绕`pdb`的图形包装器)。## 符号跟踪的限制
FX 使用一种**符号跟踪**系统(也称为[符号执行](https://en.wikipedia.org/wiki/Symbolic_execution))来以可转换/可分析的形式捕获程序的语义。该系统是**跟踪**的,因为它执行程序(实际上是一个`torch.nn.Module`或函数)以记录操作。它是**符号**的,因为在执行过程中流经程序的数据不是真实数据,而是符号(FX 术语中的`Proxy`)。
......@@ -727,7 +727,7 @@ def forward(self, x):
"""
```
### 使用`Tracer`类自定义追踪[](#customizing-tracing-with-the-tracer-class "跳转到此标题")
### 使用`Tracer`类自定义追踪
`Tracer`类是`symbolic_trace`实现的基础类。通过对 Tracer 进行子类化,可以自定义追踪的行为,如下所示:
......
......@@ -278,7 +278,7 @@ torch.hub.load_state_dict_from_url(url, model_dir=None, map_location=None, progr
为了帮助用户在不断查阅文档的情况下探索,我们强烈建议仓库所有者使函数帮助消息清晰简洁。包含一个最小工作示例也是有帮助的。
### 我的下载模型保存在哪里?[](#where-are-my-downloaded-models-saved "Permalink to this heading")
### 我的下载模型保存在哪里?
使用顺序为
......
......@@ -53,7 +53,7 @@ TorchScript 是一种从 PyTorch 代码创建可序列化和可优化模型的
想要了解如何将 PyTorch 模型转换为 TorchScript 并在 C++中运行的端到端示例,可以参考[在 C++中加载 PyTorch 模型](https://pytorch.org/tutorials/advanced/cpp_export.html)教程。
## 创建 TorchScript 代码[](#创建 TorchScript 代码 "跳转到此标题的永久链接")
## 创建 TorchScript 代码
| `script` | 对函数进行脚本化。 |
| --- | --- |
......@@ -79,7 +79,7 @@ TorchScript 是一种从 PyTorch 代码创建可序列化和可优化模型的
| `Attribute` | 此方法是一个传递函数,返回值,主要用于指示 TorchScript 编译器左侧表达式是具有类型的类实例属性。 |
| `annotate` | 用于在 TorchScript 编译器中给出 the_value 的类型。 |
## 混合跟踪和脚本化[](#mixing-tracing-and-scripting "跳转到此标题的永久链接")
## 混合跟踪和脚本化
在许多情况下,跟踪或脚本化是将模型转换为 TorchScript 的更简单方法。跟踪和脚本化可以组合以满足模型的特定要求。
......@@ -147,27 +147,27 @@ my_script_module = torch.jit.script(MyScriptModule())
TorchScript 是 Python 的静态类型子集,因此许多 Python 功能直接适用于 TorchScript。有关详细信息,请参阅完整的 TorchScript 语言参考。
## 内置函数和模块[](#built-in-functions-and-modules "跳转到此标题的永久链接")
## 内置函数和模块
TorchScript 支持大多数 PyTorch 函数和许多 Python 内置函数。查看 TorchScript 内置函数以获取支持函数的完整参考。
### PyTorch 函数和模块[](#pytorch-functions-and-modules "跳转到此标题的永久链接")
### PyTorch 函数和模块
TorchScript 支持 PyTorch 提供的张量和神经网络函数的子集。Tensor 上的大多数方法以及`torch`命名空间中的函数,`torch.nn.functional`中的所有函数以及`torch.nn`中的大多数模块都受 TorchScript 支持。
请查看 TorchScript 不支持的 PyTorch 构造以获取不支持的 PyTorch 函数和模块列表。
### Python 函数和模块[](#python-functions-and-modules "跳转到此标题的永久链接")
### Python 函数和模块
TorchScript 支持 Python 的许多[内置函数](https://docs.python.org/3/library/functions.html)[`math`](https://docs.python.org/3/library/math.html#module-math "(在 Python v3.12 中)")模块也受支持(有关详细信息,请参阅 math 模块),但不支持其他 Python 模块(内置或第三方)。
### Python 语言参考比较[](#python-language-reference-comparison "跳转到此标题的永久链接")
### Python 语言参考比较
要查看支持的 Python 功能的完整列表,请参阅 Python 语言参考覆盖范围。
## 调试
### 调试时禁用 JIT[](#disable-jit-for-debugging "跳转到此标题的永久链接")
### 调试时禁用 JIT
PYTORCH_JIT
......@@ -195,7 +195,7 @@ traced_fn(torch.rand(3, 4))
$ PYTORCH_JIT=0 python disable_jit_example.py
```
我们将能够像普通 Python 函数一样进入`@torch.jit.script`函数。要禁用特定函数的 TorchScript 编译器,请参阅`@torch.jit.ignore`。### 检查代码[](#inspecting-code "跳转到此标题的永久链接")
我们将能够像普通 Python 函数一样进入`@torch.jit.script`函数。要禁用特定函数的 TorchScript 编译器,请参阅`@torch.jit.ignore`。### 检查代码
TorchScript 为所有`ScriptModule`实例提供了代码漂亮打印机。这个漂亮打印机将脚本方法的代码解释为有效的 Python 语法。例如:
......@@ -229,7 +229,7 @@ def foo(len: int) -> Tensor:
return rv0
```
这是 TorchScript 对`forward`方法的代码编译。您可以使用此功能来确保 TorchScript(跟踪或脚本化)正确捕获了您的模型代码。### 解释图形[](#interpreting-graphs "跳转到此标题的永久链接")
这是 TorchScript 对`forward`方法的代码编译。您可以使用此功能来确保 TorchScript(跟踪或脚本化)正确捕获了您的模型代码。### 解释图形
TorchScript 还具有比代码漂亮打印机更低级别的表示形式,即 IR 图形。
......@@ -437,7 +437,7 @@ traced = torch.jit.trace(fill_row_zero, (torch.rand(3, 4),))
print(traced.graph)
```
## 常见问题[](#frequently-asked-questions "跳转到此标题的永久链接")
## 常见问题
问:我想在 GPU 上训练模型,然后在 CPU 上进行推断。有什么最佳实践吗?
......@@ -510,7 +510,7 @@ print(traced.graph)
## 附录
### 迁移到 PyTorch 1.2 递归脚本 API[](#migrating-to-pytorch-1-2-recursive-scripting-api "跳转到此标题的永久链接")
### 迁移到 PyTorch 1.2 递归脚本 API
本节详细介绍了 PyTorch 1.2 中 TorchScript 的更改。如果您是 TorchScript 的新手,可以跳过本节。PyTorch 1.2 对 TorchScript API 进行了两个主要更改。
......
......@@ -9,7 +9,7 @@
torch.signal 模块,模仿自 SciPy 的[signal](https://docs.scipy.org/doc/scipy/reference/signal.html)模块。
## torch.signal.windows[](#module-torch.signal.windows "Permalink to this heading")
## torch.signal.windows
| `bartlett` | 计算巴特利特窗口。 |
| --- | --- |
......
......@@ -162,7 +162,7 @@ importer_file_structure = importer.file_structure()
found: bool = importer_file_structure.has_file("package_a/subpackage.py")
```
### 查看为什么一个给定模块被包含为一个依赖项?[](#see-why-a-given-module-was-included-as-a-dependency "Permalink to this heading")
### 查看为什么一个给定模块被包含为一个依赖项?
假设有一个给定的模块 `foo`,您想知道为什么您的 `PackageExporter``foo` 作为一个依赖项引入。
......@@ -172,7 +172,7 @@ found: bool = importer_file_structure.has_file("package_a/subpackage.py")
如果您只想查看您的 `PackageExporter` 的整个依赖图,您可以使用 `PackageExporter.dependency_graph_string()`
### 如何在我的包中包含任意资源并以后访问它们?[](#include-arbitrary-resources-with-my-package-and-access-them-later "Permalink to this heading")
### 如何在我的包中包含任意资源并以后访问它们?
`PackageExporter` 提供了三种方法,`save_pickle``save_text``save_binary`,允许您将 Python 对象、文本和二进制数据保存到一个包中。
......@@ -193,7 +193,7 @@ text = importer.load_text("config_stuff", "words.txt")
binary = importer.load_binary("raw_data", "binary")
```
### 如何自定义类的打包方式?[](#customize-how-a-class-is-packaged "Permalink to this heading")
### 如何自定义类的打包方式?
`torch.package` 允许自定义类的打包方式。通过在一个类上定义方法 `__reduce_package__` 并定义相应的解包函数来访问这种行为。这类似于为 Python 的普通 pickling 过程定义 `__reduce__`
......@@ -294,7 +294,7 @@ foo_1 export time: 9857706.650140837
foo_1 import time: 9857706.652698385
```
### 在我的源代码中测试是否正在包内执行?[](#test-in-my-source-code-whether-or-not-it-is-executing-inside-a-package "Permalink to this heading")
### 在我的源代码中测试是否正在包内执行?
`PackageImporter`将在初始化的每个模块上添加属性`__torch_package__`。您的代码可以检查此属性的存在来确定它是否在打包上下文中执行。
......@@ -326,7 +326,7 @@ loaded_module.is_in_package() # True
**警告**:通常,根据代码是打包还是未打包而表现不同是不好的实践。这可能导致难以调试的问题,这些问题对您导入代码的方式很敏感。如果您的包打算被广泛使用,请考虑重新组织您的代码,使其无论如何加载都表现相同。
### 将代码打补丁到包中?[](#patch-code-into-a-package "跳转到此标题的永久链接")
### 将代码打补丁到包中?
`PackageExporter`提供了一个`save_source_string()`方法,允许将任意 Python 源代码保存到您选择的模块中。
......@@ -355,7 +355,7 @@ importer = PackageImporter(f)
importer.import_module("my_module.foo").my_function() # prints 'hello world'
```
### 从打包代码中访问包内容?[](#access-package-contents-from-packaged-code "跳转到此标题的永久链接")
### 从打包代码中访问包内容?
`PackageImporter`实现了[importlib.resources](https://docs.python.org/3/library/importlib.html#module-importlib.resources) API,用于从包内访问资源。
......@@ -399,7 +399,7 @@ def get_my_pickle():
return torch_package_importer.load_pickle("my_pickle", "obj.pkl")
```
### 区分打包代码和非打包代码?[](#distinguish-between-packaged-code-and-non-packaged-code "跳转到此标题的永久链接")
### 区分打包代码和非打包代码?
要确定对象的代码是否来自`torch.package`,请使用`torch.package.is_from_package()`函数。注意:如果对象来自包但其定义来自标记为`extern``stdlib`的模块,此检查将返回`False`
......@@ -414,7 +414,7 @@ assert is_from_package(obj)
assert not is_from_package(txt) # str is from stdlib, so this will return False
```
### 重新导出已导入的对象?[](#re-export-an-imported-object "跳转到此标题的永久链接")
### 重新导出已导入的对象?
重新导出之前由`PackageImporter`导入的对象,您必须让新的`PackageExporter`知道原始的`PackageImporter`,以便它可以找到您对象的依赖项的源代码。
......@@ -427,7 +427,7 @@ with PackageExporter(f2, importer=(importer, sys_importer)) as exporter:
exporter.save_pickle("model", "model.pkl", obj)
```
### 打包 TorchScript 模块?[](#package-a-torchscript-module "跳转到此标题的永久链接")
### 打包 TorchScript 模块?
要打包 TorchScript 模型,请使用与任何其他对象相同的`save_pickle``load_pickle` API。支持保存属性或子模块的 TorchScript 对象,无需额外工作。
......@@ -444,7 +444,7 @@ loaded_mixed = importer.load_pickle("res", "mixed_model.pkl"
## 解释
### `torch.package`格式概述[](#torch-package-format-overview "跳转到此标题的永久链接")
### `torch.package`格式概述
`torch.package`文件是一个 ZIP 存档,通常使用`.pt`扩展名。在 ZIP 存档中,有两种类型的文件:
......@@ -510,9 +510,9 @@ resnet
└── utils.py # torchvision.models.utils
```
### 如何`torch.package`找到您代码的依赖项[](#how-torch-package-finds-your-code-s-dependencies "跳转到此标题")
### 如何`torch.package`找到您代码的依赖项
#### 分析对象的依赖项[](#analyzing-an-object-s-dependencies "跳转到此标题")
#### 分析对象的依赖项
当您发出`save_pickle(obj, ...)`调用时,`PackageExporter`将正常对对象进行 pickle。然后,它使用`pickletools`标准库模块来解析 pickle 字节码。
......@@ -524,13 +524,13 @@ GLOBAL 'torchvision.models.resnet Resnet`
依赖解析器将收集所有`GLOBAL`操作,并将它们标记为您的 pickled 对象的依赖项。有关 pickling 和 pickle 格式的更多信息,请参考[Python 文档](https://docs.python.org/3/library/pickle.html)
#### 分析模块的依赖项[](#analyzing-a-module-s-dependencies "跳转到此标题")
#### 分析模块的依赖项
当 Python 模块被识别为依赖项时,`torch.package`会遍历模块的 Python AST 表示,并查找具有标准形式的导入语句的支持:`from x import y``import z``from w import v as u`等。当遇到这些导入语句之一时,`torch.package`会将导入的模块注册为依赖项,然后以相同的 AST 遍历方式解析它们自己。
**注意**:AST 解析对于`__import__(...)`语法有限支持,并且不支持`importlib.import_module`调用。一般来说,您不应该期望`torch.package`能够检测到动态导入。
### 依赖管理[](#dependency-management "跳转到此标题")
### 依赖管理
`torch.package`会自动找到您的代码和对象依赖的 Python 模块。这个过程称为依赖解析。对于依赖解析器找到的每个模块,您必须指定要执行的*操作*
......@@ -637,9 +637,9 @@ exporter.mock("**", exclude=["torchvision.**"])
当一个模块可能匹配多个操作时,将采取首先定义的操作。
### `torch.package`尖锐边缘[](#torch-package-sharp-edges "跳转到此标题")
### `torch.package`尖锐边缘
#### 避免在您的模块中使用全局状态[](#avoid-global-state-in-your-modules "跳转到此标题")
#### 避免在您的模块中使用全局状态
Python 使绑定对象和在模块级别范围运行代码变得非常容易。这通常没问题——毕竟,函数和类是以这种方式绑定到名称的。但是,当您在模块范围定义一个对象以进行突变时,引入可变全局状态时,情况会变得更加复杂。
......@@ -647,7 +647,7 @@ Python 使绑定对象和在模块级别范围运行代码变得非常容易。
每个`PackageImporter`为其内容创建一个独立的环境。这很好,因为这意味着我们加载多个包并确保它们彼此隔离,但是当模块以假定共享可变全局状态的方式编写时,此行为可能会导致难以调试的错误。
#### 类型不在包之间共享,并且加载环境[](#types-are-not-shared-between-packages-and-the-loading-environment "跳转到此标题")
#### 类型不在包之间共享,并且加载环境
`PackageImporter`导入的任何类都将是特定于该导入器的类的版本。例如:
......@@ -681,7 +681,7 @@ print(imported_MyClass.__name__) # prints <torch_package_0>.foo.MyClass
+ 使类型关系成为类合同的显式部分。例如,您可以添加一个属性标签`self.handler = "handle_me_this_way"`,并让客户端代码检查`handler`的值而不是直接检查类型。
### 如何使`torch.package`中的包相互隔离[](#how-torch-package-keeps-packages-isolated-from-each-other "跳转到此标题的永久链接")
### 如何使`torch.package`中的包相互隔离
每个`PackageImporter`实例为其模块和对象创建一个独立的、隔离的环境。包中的模块只能导入其他打包的模块,或标记为`extern`的模块。如果您使用多个`PackageImporter`实例来加载单个包,您将获得多个独立的环境,它们不会相互交互。
......
......@@ -265,7 +265,7 @@ torch.profiler.tensorboard_trace_handler(dir_name, worker_name=None, use_gzip=Fa
将跟踪文件输出到`dir_name`目录,然后该目录可以直接作为 logdir 传递给 tensorboard。在分布式场景中,`worker_name`应该对每个 worker 是唯一的,默认情况下将设置为‘[hostname]_[pid]’。
## 英特尔仪器和跟踪技术 APIs[](#intel-instrumentation-and-tracing-technology-apis "跳转到此标题")
## 英特尔仪器和跟踪技术 APIs
```py
torch.profiler.itt.is_available()
......
......@@ -15,7 +15,7 @@
**您可以使用以下两种 ONNX 导出器 API:**
## 基于 TorchDynamo 的 ONNX 导出器[](#torchdynamo-based-onnx-exporter "跳转到此标题")
## 基于 TorchDynamo 的 ONNX 导出器
*基于 TorchDynamo 的 ONNX 导出器是 PyTorch 2.0 及更新版本的最新(Beta)导出器*
......@@ -25,7 +25,7 @@ TorchDynamo 引擎被用来钩入 Python 的帧评估 API 并动态重写其字
了解基于 TorchDynamo 的 ONNX 导出器
## 基于 TorchScript 的 ONNX 导出器[](#torchscript-based-onnx-exporter "跳转到此标题")
## 基于 TorchScript 的 ONNX 导出器
*基于 TorchScript 的 ONNX 导出器自 PyTorch 1.2.0 起可用*
......
......@@ -45,7 +45,7 @@ optim.SGD([
这意味着`model.base`的参数将使用学习率的默认值`1e-2``model.classifier`的参数将使用学习率`1e-3`,并且所有参数将使用动量`0.9`
### 执行优化步骤[](#taking-an-optimization-step "Permalink to this heading")
### 执行优化步骤
所有优化器都实现了一个`step()`方法,用于更新参数。它可以以两种方式使用:
......@@ -147,7 +147,7 @@ class torch.optim.Optimizer(params, defaults)
| `Rprop` | foreach | yes | no |
| `SGD` | foreach | yes | no |
## 如何调整学习率[](#how-to-adjust-learning-rate "Permalink to this heading")
## 如何调整学习率
`torch.optim.lr_scheduler` 提供了几种根据周期数调整学习率的方法。`torch.optim.lr_scheduler.ReduceLROnPlateau` 允许根据一些验证测量动态减少学习率。
......@@ -220,7 +220,7 @@ for epoch in range(20):
| `lr_scheduler.OneCycleLR` | 根据 1cycle 学习率策略设置每个参数组的学习率。 |
| `lr_scheduler.CosineAnnealingWarmRestarts` | 使用余弦退火调度设置每个参数组的学习率,其中$\eta_{max}$设置为初始 lr,$T_{cur}$是自上次重启以来的时代数,$T_{i}$是 SGDR 中两次热重启之间的时代数: |
## 权重平均(SWA 和 EMA)[](#weight-averaging-swa-and-ema "跳转到此标题的永久链接")
## 权重平均(SWA 和 EMA)
`torch.optim.swa_utils`实现了随机权重平均(SWA)和指数移动平均(EMA)。特别是,`torch.optim.swa_utils.AveragedModel`类实现了 SWA 和 EMA 模型,`torch.optim.swa_utils.SWALR`实现了 SWA 学习率调度程序,`torch.optim.swa_utils.update_bn()`是一个实用函数,用于在训练结束时更新 SWA/EMA 批归一化统计数据。
......@@ -228,7 +228,7 @@ SWA 已经在[Averaging Weights Leads to Wider Optima and Better Generalization]
EMA 是一种广泛知晓的技术,通过减少所需的权重更新次数来减少训练时间。它是[Polyak 平均](https://paperswithcode.com/method/polyak-averaging)的一种变体,但是使用指数权重而不是在迭代中使用相等权重。
### 构建平均模型[](#constructing-averaged-models "跳转到此标题的永久链接")
### 构建平均模型
AveragedModel 类用于计算 SWA 或 EMA 模型的权重。
......@@ -261,7 +261,7 @@ $W^\textrm{EMA}_{t+1} = \alpha W^\textrm{EMA}_{t} + (1 - \alpha) W^\textrm{model
对于 SWA 和 EMA,这个调用通常在 optimizer `step()`之后立即执行。在 SWA 的情况下,通常在训练开始时跳过一些步骤。
### 自定义平均策略[](#custom-averaging-strategies "跳转到此标题的永久链接")
### 自定义平均策略
默认情况下,`torch.optim.swa_utils.AveragedModel`计算您提供的参数的运行平均值,但您也可以使用`avg_fn``multi_avg_fn`参数使用自定义平均函数:
......@@ -283,7 +283,7 @@ $W^\textrm{EMA}_{t+1} = \alpha W^\textrm{EMA}_{t} + (1 - \alpha) W^\textrm{model
>>> ema_model = AveragedModel(model, multi_avg_fn=get_ema_multi_avg_fn(0.9))
```
### SWA 学习率调度[](#swa-learning-rate-schedules "跳转到此标题的永久链接")
### SWA 学习率调度
通常,在 SWA 中,学习率设置为一个较高的恒定值。`SWALR`是一个学习率调度程序,它将学习率退火到一个固定值,然后保持恒定。例如,以下代码创建一个调度程序,它在每个参数组内将学习率从初始值线性退火到 0.05,共 5 个时期:
......@@ -294,7 +294,7 @@ $W^\textrm{EMA}_{t+1} = \alpha W^\textrm{EMA}_{t} + (1 - \alpha) W^\textrm{model
您还可以通过设置`anneal_strategy="cos"`来使用余弦退火到固定值,而不是线性退火。
### 处理批归一化[](#taking-care-of-batch-normalization "Permalink to this heading")
### 处理批归一化
`update_bn()`是一个实用函数,允许在训练结束时计算给定数据加载器`loader`上 SWA 模型的批归一化统计信息:
......@@ -308,7 +308,7 @@ $W^\textrm{EMA}_{t+1} = \alpha W^\textrm{EMA}_{t} + (1 - \alpha) W^\textrm{model
`update_bn()`假设数据加载器`loader`中的每个批次都是张量或张量列表,其中第一个元素是应用于网络`swa_model`的张量。如果您的数据加载器具有不同的结构,您可以通过在数据集的每个元素上使用`swa_model`进行前向传递来更新`swa_model`的批归一化统计信息。
### 将所有内容放在一起:SWA[](#putting-it-all-together-swa "Permalink to this heading")
### 将所有内容放在一起:SWA
在下面的示例中,`swa_model`是累积权重平均值的 SWA 模型。我们总共训练模型 300 个时期,并切换到 SWA 学习率计划,并开始在第 160 个时期收集参数的 SWA 平均值:
......@@ -336,7 +336,7 @@ $W^\textrm{EMA}_{t+1} = \alpha W^\textrm{EMA}_{t} + (1 - \alpha) W^\textrm{model
>>> preds = swa_model(test_input)
```
### 将所有内容放在一起:EMA[](#putting-it-all-together-ema "Permalink to this heading")
### 将所有内容放在一起:EMA
在下面的示例中,`ema_model`是 EMA 模型,它累积权重的指数衰减平均值,衰减率为 0.999。我们总共训练模型 300 个时期,并立即开始收集 EMA 平均值。
......
......@@ -35,7 +35,7 @@ tensor([[-0.4621-0.0303j, -0.2438-0.5874j],
除了`torch.linspace()``torch.logspace()``torch.arange()`之外的所有工厂函数都支持复数张量。
## 从旧表示形式过渡[](#transition-from-the-old-representation "Permalink to this heading")
## 从旧表示形式过渡
目前通过使用形状为$(..., 2)$(...,2)的实数张量绕过缺少复数张量的用户可以轻松地在其代码中使用复数张量切换,使用`torch.view_as_complex()``torch.view_as_real()`。请注意,这些函数不执行任何复制操作,返回输入张量的视图。
......
......@@ -9,13 +9,13 @@
DDP 通信钩子是一个通用接口,通过覆盖[DistributedDataParallel](https://pytorch.org/docs/stable/generated/torch.nn.parallel.DistributedDataParallel.html#torch.nn.parallel.DistributedDataParallel.)中的基本 allreduce 来控制如何在工作进程之间通信梯度。提供了一些内置的通信钩子,用户可以轻松应用其中任何一个来优化通信。此外,该钩子接口还可以支持用户定义的通信策略,以满足更高级的用例需求。
## 如何使用通信钩子?[](#how-to-use-a-communication-hook "跳转到此标题的永久链接")
## 如何使用通信钩子?
要使用通信钩子,用户只需在训练循环之前让 DDP 模型注册钩子,如下所示。
`torch.nn.parallel.DistributedDataParallel.register_comm_hook()`
## 通信钩子操作的是什么?[](#what-does-a-communication-hook-operate-on "跳转到此标题的永久链接")
## 通信钩子操作的是什么?
通信钩子提供了一种灵活的方式来 allreduce 梯度。因此,它主要在每个副本上的梯度上操作,然后进行 allreduce,这些梯度被分桶以增加通信和计算之间的重叠。特别地,`torch.distributed.GradBucket`表示要进行 allreduce 的梯度张量的一个桶。
......@@ -75,7 +75,7 @@ torch.distributed.GradBucket.parameters(self: torch._C._distributed_c10d.GradBuc
一个`torch.Tensor`列表。列表中的每个张量对应一个模型参数。
## 默认通信钩子[](#default-communication-hooks "跳转到此标题的永久链接")
## 默认通信钩子
默认通信钩子是简单的**无状态**钩子,因此`register_comm_hook`中的输入状态要么是一个进程组,要么是`None`。输入`bucket`是一个`torch.distributed.GradBucket`对象。
......@@ -171,7 +171,7 @@ torch.distributed.algorithms.ddp_comm_hooks.default_hooks.bf16_compress_wrapper(
[*Callable*](https://docs.python.org/3/library/typing.html#typing.Callable "(in Python v3.12)")[[[*Any*](https://docs.python.org/3/library/typing.html#typing.Any "(in Python v3.12)"), *GradBucket*], *Future*[*Tensor*]]
## PowerSGD 通信钩子[](#powersgd-communication-hook "跳转到此标题")
## PowerSGD 通信钩子
PowerSGD([Vogels 等人,NeurIPS 2019](https://arxiv.org/abs/1905.13727))是一种梯度压缩算法,可以提供非常高的压缩率,并加速带宽受限的分布式训练。该算法需要维护一些超参数和内部状态。因此,PowerSGD 通信钩子是一个**有状态**的钩子,用户需要提供以下定义的状态对象。
......@@ -328,7 +328,7 @@ torch.distributed.algorithms.ddp_comm_hooks.powerSGD_hook.batched_powerSGD_hook(
>>> ddp_model.register_comm_hook(state, batched_powerSGD_hook)
```
## 调试通信挂钩[](#debugging-communication-hooks "跳转到此标题")
## 调试通信挂钩
顾名思义,调试通信挂钩仅用于调试和性能优化目的。
......@@ -354,7 +354,7 @@ torch.distributed.algorithms.ddp_comm_hooks.debugging_hooks.noop_hook(_, bucket)
*Future*[*Tensor*]
## 通信挂钩的检查点[](#checkpointing-of-communication-hooks "跳转到此标题")
## 通信挂钩的检查点
作为模型检查点的一部分,可以将有状态的通信挂钩保存以启用训练器重新启动。要使挂钩可序列化,应定义`__setstate__`和`__getstate__`。
......
......@@ -13,13 +13,13 @@
管道并行是实验性的,可能会发生变化。
## 使用多个 GPU 的模型并行[](#model-parallelism-using-multiple-gpus "此标题的永久链接")
## 使用多个 GPU 的模型并行
通常对于无法放入单个 GPU 的大型模型,会采用模型并行,其中模型的某些部分被放置在不同的 GPU 上。然而,如果对于顺序模型进行简单划分,训练过程会因 GPU 的低利用率而受到影响,因为如下图所示,一次只有一个 GPU 处于活动状态:
![_images/no_pipe.png](img/b9cf9a633037f50f7bc1ebee273078d5.png)
该图表示一个具有 4 层的模型,这些层分布在 4 个不同的 GPU 上(垂直轴)。水平轴表示通过时间训练该模型,演示了每次只有 1 个 GPU 被利用([图片来源](https://arxiv.org/abs/1811.06965))。[](#id2 "此图片的永久链接")
该图表示一个具有 4 层的模型,这些层分布在 4 个不同的 GPU 上(垂直轴)。水平轴表示通过时间训练该模型,演示了每次只有 1 个 GPU 被利用([图片来源](https://arxiv.org/abs/1811.06965))。
## 管道化执行
......@@ -27,7 +27,7 @@
![_images/pipe.png](img/ef057fe1265f513c363e3e4cdc5a1cf7.png)
该图表示一个具有 4 层的模型,这些层分布在 4 个不同的 GPU 上(垂直轴)。水平轴表示通过时间训练该模型,演示了 GPU 的利用效率更高。然而,仍然存在一个气泡(如图所示),其中某些 GPU 未被利用。([图片来源](https://arxiv.org/abs/1811.06965)).[](#id3 "此图片的永久链接")
该图表示一个具有 4 层的模型,这些层分布在 4 个不同的 GPU 上(垂直轴)。水平轴表示通过时间训练该模型,演示了 GPU 的利用效率更高。然而,仍然存在一个气泡(如图所示),其中某些 GPU 未被利用。([图片来源](https://arxiv.org/abs/1811.06965)).
## PyTorch 中的 Pipe API
......
......@@ -11,7 +11,7 @@
量化处于测试阶段,可能会有变化。
## 量化简介[](#introduction-to-quantization "跳转到此标题的永久链接")
## 量化简介
量化是指在执行计算和存储张量时使用比浮点精度更低的比特宽度的技术。量化模型在张量上执行一些或所有操作时,使用降低的精度而不是完整精度(浮点)值。这样可以实现更紧凑的模型表示,并在许多硬件平台上使用高性能的矢量化操作。PyTorch 支持 INT8 量化,相比典型的 FP32 模型,可以将模型大小减小 4 倍,内存带宽需求减小 4 倍。与 FP32 计算相比,硬件对 INT8 计算的支持通常快 2 到 4 倍。量化主要是一种加速推断的技术,只支持量化操作符的前向传播。
......@@ -70,7 +70,7 @@ PyTorch 2 导出量化是新的完整图模式量化工作流程,作为 PyTorc
有关量化流程的一般介绍,包括不同类型的量化,请参阅一般量化流程。
#### 训练后动态量化[](#post-training-dynamic-quantization "跳转到此标题")
#### 训练后动态量化
这是最简单的量化形式,其中权重在预先量化,但激活在推断期间动态量化。这适用于模型执行时间主要由从内存加载权重而不是计算矩阵乘法所主导的情况。这对于批量大小较小的 LSTM 和 Transformer 类型模型是真实的。
......@@ -120,7 +120,7 @@ res = model_int8(input_fp32)
要了解更多关于动态量化的信息,请参阅我们的[动态量化教程](https://pytorch.org/tutorials/recipes/recipes/dynamic_quantization.html)
#### 后训练静态量化[](#post-training-static-quantization "跳转到此标题")
#### 后训练静态量化
后训练静态量化(PTQ 静态)量化模型的权重和激活。它将激活融合到可能的前置层中。它需要使用代表性数据集进行校准,以确定激活的最佳量化参数。后训练静态量化通常用于 CNN 是典型用例的情况下,其中内存带宽和计算节省都很重要。
......@@ -211,7 +211,7 @@ res = model_int8(input_fp32)
要了解更多关于静态量化的信息,请参阅[静态量化教程](https://pytorch.org/tutorials/advanced/static_quantization_tutorial.html)
#### 静态量化的量化感知训练[](#quantization-aware-training-for-static-quantization "跳转到此标题")
#### 静态量化的量化感知训练
量化感知训练(QAT)在训练期间模拟量化的效果,从而使准确性比其他量化方法更高。我们可以对静态、动态或仅权重量化进行 QAT。在训练期间,所有计算都是在浮点数中进行的,通过 fake_quant 模块模拟量化的效果,通过夹紧和四舍五入来模拟 INT8 的效果。在模型转换后,权重和激活被量化,并且激活被融合到可能的前置层中。它通常与 CNN 一起使用,并且与静态量化相比,准确性更高。
......@@ -305,7 +305,7 @@ res = model_int8(input_fp32)
要了解更多关于量化感知训练,请参阅[QAT 教程](https://pytorch.org/tutorials/advanced/static_quantization_tutorial.html)
#### 急切模式静态量化的模型准备[](#model-preparation-for-eager-mode-static-quantization "跳转到此标题")
#### 急切模式静态量化的模型准备
目前在进行急切模式量化之前需要对模型定义进行一些修改。这是因为目前量化是基于模块的。具体来说,对于所有量化技术,用户需要:
......@@ -617,7 +617,7 @@ PyTorch 支持对称和非对称的每个张量和每个通道量化。每个张
我们可以在同一量化流程中混合不同的量化运算符方式。例如,我们可以有后训练量化,其中既有静态量化的运算符,也有动态量化的运算符。
## 量化支持矩阵[](#quantization-support-matrix "跳转到此标题")
## 量化支持矩阵
### 量化模式支持
......@@ -669,7 +669,7 @@ FX Graph Mode Quantization 是 PyTorch 中的自动量化框架,目前是一
+ (早期原型)通过[fx2trt](https://developer.nvidia.com/tensorrt)支持 NVidia GPU
#### 本机 CPU 后端注意事项[](#note-for-native-cpu-backends "跳转到此标题")
#### 本机 CPU 后端注意事项
我们同时暴露了 x86 和 qnnpack,使用相同的本机 pytorch 量化运算符,因此我们需要额外的标志来区分它们。根据 PyTorch 构建模式自动选择 x86 和 qnnpack 的相应实现,尽管用户可以通过将 torch.backends.quantization.engine 设置为 x86 或 qnnpack 来覆盖此设置。
......@@ -714,7 +714,7 @@ torch.backends.quantized.engine = 'qnnpack'
注意:这将很快更新一些从本机 backend_config_dict 生成的信息。
## 量化 API 参考[](#quantization-api-reference "跳转到此标题")
## 量化 API 参考
量化 API 参考包含有关量化 API 的文档,例如量化传递、量化张量操作以及支持的量化模块和函数。
......@@ -858,7 +858,7 @@ mq = torch.ao.quantization.quantize_fx.convert_fx(
2. 如果选择了`onednn`后端,将在默认的 qconfig 映射`torch.ao.quantization.get_default_qconfig_mapping('onednn')`和默认的 qconfig`torch.ao.quantization.get_default_qconfig('onednn')`中使用 8 位激活。建议在支持向量神经网络指令(VNNI)的 CPU 上使用。否则,将激活的观察者的`reduce_range`设置为 True,以在没有 VNNI 支持的 CPU 上获得更好的准确性。
## 常见问题[](#frequently-asked-questions "跳转到此标题的永久链接")
## 常见问题
1. 如何在 GPU 上进行量化推断?:
......@@ -876,7 +876,7 @@ mq = torch.ao.quantization.quantize_fx.convert_fx(
## 常见错误
### 将一个非量化的张量传递给一个量化的内核[](#passing-a-non-quantized-tensor-into-a-quantized-kernel "跳转到此标题的永久链接")
### 将一个非量化的张量传递给一个量化的内核
如果您看到类似以下错误:
......@@ -901,7 +901,7 @@ class M(torch.nn.Module):
return x
```
### 将一个量化的张量传递给一个非量化的内核[](#passing-a-quantized-tensor-into-a-non-quantized-kernel "跳转到此标题的永久链接")
### 将一个量化的张量传递给一个非量化的内核
如果您看到类似以下错误:
......@@ -938,7 +938,7 @@ m.qconfig = some_qconfig
m.conv2.qconfig = None
```
### 保存和加载量化模型[](#saving-and-loading-quantized-models "跳转到此标题的永久链接")
### 保存和加载量化模型
在对一个量化模型调用`torch.load`时,如果出现类似以下错误:
......@@ -999,7 +999,7 @@ b.seek(0)
scripted_quantized = torch.jit.load(b)
```
### 在使用 FX 图模式量化时出现符号跟踪错误[](#symbolic-trace-error-when-using-fx-graph-mode-quantization "跳转到此标题的永久链接")
### 在使用 FX 图模式量化时出现符号跟踪错误
符号跟踪是(原型-维护模式) FX 图模式量化的要求,因此如果您传递一个不能被符号跟踪的 PyTorch 模型到 torch.ao.quantization.prepare_fx 或 torch.ao.quantization.prepare_qat_fx,我们可能会看到以下类似的错误:
......
......@@ -889,7 +889,7 @@ to_here(self: torch._C._distributed_rpc.PyRRef, timeout: float = -1.0) → objec
+ 所有者与用户共享 RRef
+ 用户与用户共享 RRef ## RemoteModule[](#remotemodule "Permalink to this heading")
+ 用户与用户共享 RRef ## RemoteModule
警告
......@@ -997,7 +997,7 @@ remote_parameters(recurse=True)
[*List*](https://docs.python.org/3/library/typing.html#typing.List "(在 Python v3.12 中)")*RRef*[[*Parameter*]]
## 分布式自动求导框架[](#distributed-autograd-framework "跳转到此标题")
## 分布式自动求导框架
警告
......
......@@ -159,7 +159,7 @@ nested_tensor([
请注意,`nt.unbind()[0]`不是一个副本,而是底层内存的一个切片,表示嵌套张量的第一个条目或组成部分。
## 嵌套张量构造函数和转换函数[](#nested-tensor-constructor-and-conversion-functions "跳转到此标题")
## 嵌套张量构造函数和转换函数
以下函数与嵌套张量相关:
......@@ -292,7 +292,7 @@ tensor([[[ 1.6862, -1.1282, 1.1031, 0.0464, -1.3276, 1.0000],
[ 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000]]])
>>> pt_small = torch.nested.to_padded_tensor(nt, 2.0, (2, 2, 2))
RuntimeError: Value in output_size is less than NestedTensor padded size. Truncation is not supported.
``` ## 支持的操作[](#supported-operations "跳转到此标题")
``` ## 支持的操作
在本节中,我们总结了当前在 NestedTensor 上支持的操作以及它们的任何约束。
......
......@@ -11,7 +11,7 @@
PyTorch 稀疏张量的 API 处于测试阶段,可能会在不久的将来发生变化。我们非常欢迎功能请求、错误报告和一般建议作为 GitHub 问题。
## 何时以及为什么使用稀疏性[](#why-and-when-to-use-sparsity "跳转到此标题的永久链接")
## 何时以及为什么使用稀疏性
默认情况下,PyTorch 将`torch.Tensor`元素存储在连续的物理内存中。这导致了对需要快速访问元素的各种数组处理算法的高效实现。
......@@ -310,7 +310,7 @@ tensor(indices=tensor([], size=(2, 0)),
size=(2, 3), nnz=0, layout=torch.sparse_coo)
```
### 稀疏混合 COO 张量[](#sparse-hybrid-coo-tensors "跳转到此标题的永久链接")
### 稀疏混合 COO 张量
PyTorch 实现了将标量值的稀疏张量扩展为具有(连续)张量值的稀疏张量。这样的张量被称为混合张量。
......@@ -502,7 +502,7 @@ tensor(6)
tensor([6])
```
在 PyTorch 中,稀疏张量的填充值不能被明确指定,一般假定为零。然而,存在一些操作可能会以不同方式解释填充值。例如,`torch.sparse.softmax()` 计算 softmax 时假定填充值为负无穷。## 稀疏压缩张量[](#sparse-compressed-tensors "跳转到此标题的永久链接")
在 PyTorch 中,稀疏张量的填充值不能被明确指定,一般假定为零。然而,存在一些操作可能会以不同方式解释填充值。例如,`torch.sparse.softmax()` 计算 softmax 时假定填充值为负无穷。## 稀疏压缩张量
稀疏压缩张量代表一类稀疏张量,其共同特征是使用编码压缩某个维度的索引,从而在稀疏压缩张量的线性代数核上实现某些优化。这种编码基于[压缩稀疏行(CSR)](https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_row_(CSR,_CRS_or_Yale_format))格式,PyTorch 稀疏压缩张量扩展了对稀疏张量批次的支持,允许多维张量值,并将稀疏张量值存储在密集块中。
......@@ -570,7 +570,7 @@ CSR 格式相对于 COO 格式的主要优势是更好地利用存储和更快
使用稀疏 COO 格式介绍中的示例数据相同,一个包含 100 000 个非零 32 位浮点数的 10 000 x 10 000 张量的内存消耗至少为`(10000 * 8 + (8 + 4 * 1) * 100 000) * 1 = 1 280 000`字节,使用 CSR 张量布局。请注意,与使用 COO 和分步格式相比,使用 CSR 存储格式可以节省 1.6 倍和 310 倍的存储空间。
#### 构造 CSR 张量[](#construction-of-csr-tensors "跳转到此标题")
#### 构造 CSR 张量
可以直接使用`torch.sparse_csr_tensor()`函数构造稀疏 CSR 张量。用户必须分别提供行索引和列索引以及值张量,其中行索引必须使用 CSR 压缩编码指定。如果没有提供`size`参数,则将从`crow_indices``col_indices`中推断出`size`
......@@ -630,7 +630,7 @@ tensor([[0.9078],
> +
> + `values`张量包含 CSC 张量元素的值。这是一个形状为`(nse, *densesize)`的(1 + K)-D 张量。
#### CSC 张量的构造[](#construction-of-csc-tensors "跳转到此标题")
#### CSC 张量的构造
可以直接使用`torch.sparse_csc_tensor()`函数构造稀疏 CSC 张量。用户必须分别提供行索引和列索引以及值张量,其中列索引必须使用 CSR 压缩编码指定。如果没有提供`size`参数,则将从`row_indices``ccol_indices`张量中推断出`size`
......@@ -675,7 +675,7 @@ tensor(ccol_indices=tensor([0, 1, 2, 3, 3]),
> +
> + `values`张量包含稀疏的 BSR 张量元素的值,收集到二维块中。这是一个形状为`(nse, nrowblocks, ncolblocks, *densesize)`的(1 + 2 + K)-D 张量。
#### 构建 BSR 张量[](#construction-of-bsr-tensors "跳转到此标题的永久链接")
#### 构建 BSR 张量
稀疏的 BSR 张量可以直接通过使用`torch.sparse_bsr_tensor()`函数来构建。用户必须分别提供行和列块索引以及数值张量,其中行块索引必须使用 CSR 压缩编码指定。如果没有提供`size`参数,它将从`crow_indices``col_indices`张量中推断出来。
......@@ -738,7 +738,7 @@ tensor(crow_indices=tensor([0, 2, 4]),
> +
> + `values`张量包含稀疏的 BSC 张量元素的值,收集到二维块中。这是一个形状为`(nse, nrowblocks, ncolblocks, *densesize)`的(1 + 2 + K)-D 张量。
#### 构建 BSC 张量[](#construction-of-bsc-tensors "跳转到此标题的永久链接")
#### 构建 BSC 张量
稀疏的 BSC 张量可以直接通过使用`torch.sparse_bsc_tensor()`函数来构建。用户必须分别提供行和列块索引以及数值张量,其中列块索引必须使用 CSR 压缩编码指定。如果没有提供`size`参数,它将从`ccol_indices``row_indices`张量中推断出来。
......@@ -764,11 +764,11 @@ tensor(ccol_indices=tensor([0, 2, 4]),
dtype=torch.float64, layout=torch.sparse_bsc)
```
### 用于处理稀疏压缩张量的工具[](#tools-for-working-with-sparse-compressed-tensors "跳转到此标题的永久链接")
### 用于处理稀疏压缩张量的工具
所有稀疏压缩张量 — CSR、CSC、BSR 和 BSC 张量 — 在概念上非常相似,它们的索引数据分为两部分:所谓的压缩索引使用 CSR 编码,而所谓的普通索引与压缩索引正交。这使得这些张量上的各种工具可以共享相同的实现,这些实现由张量布局参数化。
#### 稀疏压缩张量的构造[](#construction-of-sparse-compressed-tensors "Permalink to this heading")
#### 稀疏压缩张量的构造
CSR、CSC、BSR 和 CSC 张量可以通过使用 `torch.sparse_compressed_tensor()` 函数构建,该函数具有与上述讨论的构造函数 `torch.sparse_csr_tensor()``torch.sparse_csc_tensor()``torch.sparse_bsr_tensor()``torch.sparse_bsc_tensor()` 相同的接口,但需要额外的 `layout` 参数。以下示例说明了使用相同输入数据通过指定相应的布局参数来构建 CSR 和 CSC 张量的方法,该参数传递给 `torch.sparse_compressed_tensor()` 函数:
......@@ -790,7 +790,7 @@ tensor(ccol_indices=tensor([0, 2, 4]),
layout=torch.sparse_csc)
>>> (csr.transpose(0, 1).to_dense() == csc.to_dense()).all()
tensor(True)
``` ## 支持的操作[](#supported-operations "Permalink to this heading")
``` ## 支持的操作
### 线性代数操作
......@@ -870,7 +870,7 @@ tensor(True)
`add()` `add_()` `addmm()` `addmm_()` `any()` `asin()` `asin_()` `arcsin()` `arcsin_()` `bmm()` `clone()` `deg2rad()` `deg2rad_()` `detach()` `detach_()` `dim()` `div()` `div_()` `floor_divide()` `floor_divide_()` `get_device()` `index_select()` `isnan()` `log1p()` `log1p_()` `mm()` `mul()` `mul_()` `mv()` `narrow_copy()` `neg()` `neg_()` `negative()` `negative_()` `numel()` `rad2deg()` `rad2deg_()` `resize_as_()` `size()` `pow()` `sqrt()` `square()` `smm()` `sspaddmm()` `sub()` `sub_()` `t()` `t_()` `transpose()` `transpose_()` `zero_()`
### 针对稀疏张量的 Torch 函数[](#torch-functions-specific-to-sparse-tensors "跳转到此标题")
### 针对稀疏张量的 Torch 函数
| `sparse_coo_tensor` | 使用给定的`indices`构造一个 COO(坐标)格式的稀疏张量,其中包含指定的值。 |
| --- | --- |
......
......@@ -59,7 +59,7 @@ DataLoader(dataset, batch_size=1, shuffle=False, sampler=None,
当使用带有多进程数据加载的`IterableDataset`时。相同的数据集对象在每个工作进程上复制,因此必须对副本进行不同配置以避免重复数据。请参阅`IterableDataset`文档以了解如何实现此目的。
## 数据加载顺序和`Sampler`[](#data-loading-order-and-sampler "跳转到此标题")
## 数据加载顺序和`Sampler`
对于可迭代风格数据集,数据加载顺序完全由用户定义的可迭代对象控制。这允许更容易实现分块读取和动态批量大小(例如,每次产生一个批量样本)。
......@@ -134,7 +134,7 @@ for data in iter(dataset):
查看关于`collate_fn`的更多信息此部分。
### 使用`collate_fn`[](#working-with-collate-fn "跳转到此标题")
### 使用`collate_fn`
当启用或禁用自动批处理时,使用`collate_fn`略有不同。
......@@ -154,17 +154,17 @@ for data in iter(dataset):
如果您发现`DataLoader`的输出维度或类型与您的期望不同,您可能需要检查您的`collate_fn`
## 单进程和多进程数据加载[](#single-and-multi-process-data-loading "跳转到此标题")
## 单进程和多进程数据加载
`DataLoader`默认使用单进程数据加载。
在 Python 进程中,[全局解释器锁(GIL)](https://wiki.python.org/moin/GlobalInterpreterLock)阻止了真正将 Python 代码在线程间完全并行化。为了避免用数据加载阻塞计算代码,PyTorch 提供了一个简单的开关,通过将参数`num_workers`设置为正整数来执行多进程数据加载。
### 单进程数据加载(默认)[](#single-process-data-loading-default "跳转到此标题的永久链接")
### 单进程数据加载(默认)
在此模式下,数据获取是在初始化`DataLoader`的同一进程中完成的。因此,数据加载可能会阻塞计算。但是,当用于在进程之间共享数据的资源(例如共享内存、文件描述符)有限时,或者整个数据集很小且可以完全加载到内存中时,可能更喜欢此模式。此外,单进程加载通常显示更易读的错误跟踪,因此对于调试很有用。
### 多进程数据加载[](#multi-process-data-loading "跳转到此标题的永久链接")
### 多进程数据加载
将参数`num_workers`设置为正整数将打开具有指定数量的加载器工作进程的多进程数据加载。
......@@ -186,7 +186,7 @@ for data in iter(dataset):
通常不建议在多进程加载中返回 CUDA 张量,因为在使用 CUDA 和在多进程中共享 CUDA 张量时存在许多微妙之处(请参阅 CUDA 在多进程中的使用)。相反,我们建议使用自动内存固定(即设置`pin_memory=True`),这样可以实现快速数据传输到支持 CUDA 的 GPU。
#### 平台特定行为[](#platform-specific-behaviors "跳转到此标题")
#### 平台特定行为
由于工作人员依赖于 Python [`multiprocessing`](https://docs.python.org/3/library/multiprocessing.html#module-multiprocessing "(在 Python v3.12 中)"),与 Unix 相比,在 Windows 上工作启动行为是不同的。
......@@ -200,7 +200,7 @@ for data in iter(dataset):
+ 确保任何自定义的`collate_fn``worker_init_fn``dataset`代码被声明为顶层定义,放在`__main__`检查之外。这样可以确保它们在工作进程中可用。(这是因为函数只被序列化为引用,而不是`bytecode`。)
#### 多进程数据加载中的随机性[](#randomness-in-multi-process-data-loading "跳转到此标题")
#### 多进程数据加载中的随机性
默认情况下,每个工作进程的 PyTorch 种子将设置为`base_seed + worker_id`,其中`base_seed`是由主进程使用其 RNG 生成的长整型(因此,强制消耗 RNG 状态)或指定的`generator`。然而,初始化工作进程时,其他库的种子可能会重复,导致每个工作进程返回相同的随机数。(请参阅 FAQ 中的此部分。)
......
......@@ -127,7 +127,7 @@ Error when attempting to broadcast dims ['X'] and dims ['Z']: dim 'X' and dim 'Z
+ 矩阵乘法运算:消除维度
## 通过名称进行显式对齐[](#explicit-alignment-by-names "跳转到此标题")
## 通过名称进行显式对齐
使用`align_as()``align_to()`按名称对齐张量维度到指定的顺序。这对执行“按名称广播”很有用。
......@@ -201,7 +201,7 @@ tensor([-1.8107, -0.6357, 0.0783])
tensor([-1.8107, -0.6357, 0.0783])
```
## 当前支持的操作和子系统[](#currently-supported-operations-and-subsystems "跳转到此标题")
## 当前支持的操作和子系统
### 运算符
......@@ -249,7 +249,7 @@ NN 模块目前不受支持。当使用具有命名张量输入的模块时,
如果其中任何一个对您的用例有帮助,请[搜索是否已经提交了问题](https://github.com/pytorch/pytorch/issues?q=is%3Aopen+is%3Aissue+label%3A%22module%3A+named+tensor%22),如果没有,请[提交一个](https://github.com/pytorch/pytorch/issues/new/choose)
## 命名张量 API 参考[](#named-tensor-api-reference "跳转到此标题")
## 命名张量 API 参考
在本节中,请查找命名张量特定 API 的文档。有关如何通过其他 PyTorch 运算符传播名称的全面参考,请参见命名张量运算符覆盖。
......
......@@ -280,7 +280,7 @@
>>> x = torch.randn(3, 3, 3, 3, names=('N', 'C', 'H', 'W'))
>>> x.sum(['N', 'C'], keepdim=True).names
('N', 'C', 'H', 'W')
``` ## 统一输入的名称[](#unifies-names-from-inputs "Permalink to this heading")
``` ## 统一输入的名称
所有二元算术运算都遵循此规则。广播操作仍然从右侧按位置广播,以保持与未命名张量的兼容性。要通过名称执行显式广播,请使用`Tensor.align_as()`
......@@ -406,7 +406,7 @@ across both lists.
>>> torch.zeros(2, 3, names=('N', 'C'))
tensor([[0., 0., 0.],
[0., 0., 0.]], names=('N', 'C'))
```##输出函数和就地变体[](#out-function-and-in-place-variants "跳转到此标题")
```##输出函数和就地变体
指定为`out=`张量的张量具有以下行为:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册