自动微分包 - torch.autograd¶
torch.autograd
提供了实现任意标量值函数自动微分的类和函数。
它对现有代码的改动最小 - 你只需要用 requires_grad=True
关键字声明需要计算梯度的 Tensor
。目前,我们仅支持浮点 Tensor
类型( half, float, double 和 bfloat16)和复数 Tensor
类型(cfloat, cdouble)的自动微分。
计算给定张量相对于图叶节点的梯度之和。 |
|
计算并返回输出相对于输入的梯度之和。 |
前向模式自动微分¶
警告
此 API 处于 Beta 阶段。尽管函数签名极不可能改变,但在被认为是稳定版本之前,计划改进算子覆盖率。
有关如何使用此 API 的详细步骤,请参阅前向模式 AD 教程。
用于前向 AD 的上下文管理器,所有前向 AD 计算必须在 |
|
将张量值与其切线相关联,以创建用于前向 AD 梯度计算的“对偶张量”。 |
|
解包“对偶张量”,获取其张量值和前向 AD 梯度。 |
|
进入新的前向梯度级别。 |
|
退出前向梯度级别。 |
|
由 |
函数式高级 API¶
警告
此 API 处于 Beta 阶段。尽管函数签名极不可能改变,但在被认为是稳定版本之前,计划进行重大的性能改进。
本节包含基于上述基本 API 构建的自动微分高级 API,允许您计算雅可比矩阵、海森矩阵等。
此 API 适用于用户提供的函数,这些函数仅将 Tensor 作为输入并仅返回 Tensor。如果您的函数接受非 Tensor 的其他参数或未设置 requires_grad 的 Tensor,您可以使用 lambda 表达式捕获它们。例如,对于一个函数 f
,它接受三个输入:一个需要计算雅可比矩阵的 Tensor,一个应视为常量的 Tensor,以及一个布尔标志 f(input, constant, flag=flag)
,您可以将其用作 functional.jacobian(lambda x: f(x, constant, flag=flag), input)
。
计算给定函数的雅可比矩阵。 |
|
计算给定标量函数的海森矩阵。 |
|
计算向量 |
|
计算给定函数在输入点处的雅可比矩阵与向量 |
|
计算向量 |
|
计算标量函数的海森矩阵与向量 |
默认梯度布局¶
当非稀疏 param
在 torch.autograd.backward()
或 torch.Tensor.backward()
期间接收到非稀疏梯度时,param.grad
按如下方式累积。
如果 param.grad
最初是 None
如果
param
的内存是不重叠且稠密的,则创建的.grad
的跨步与param
匹配(因此与param
的布局匹配)。否则,创建的
.grad
的跨步是按行主序连续的。
如果 param
已经有一个非稀疏的 .grad
属性
如果
create_graph=False
,backward()
会就地累积到.grad
中,从而保留其跨步。如果
create_graph=True
,backward()
会用一个新的张量.grad + new grad
替换.grad
,该张量试图(但不保证)匹配已存在的.grad
的跨步。
默认行为(在第一次 backward()
之前让 .grad
为 None
,以便其布局根据第 1 或第 2 条创建,并根据第 3 或第 4 条随时间保留)推荐用于获得最佳性能。调用 model.zero_grad()
或 optimizer.zero_grad()
不会影响 .grad
布局。
事实上,在每个累积阶段之前将所有 .grad
重置为 None
,例如:
for iterations...
...
for param in model.parameters():
param.grad = None
loss.backward()
这样它们每次都会根据第 1 或第 2 条重新创建,是 model.zero_grad()
或 optimizer.zero_grad()
的一个有效替代方案,可能会改善某些网络的性能。
手动梯度布局¶
如果您需要手动控制 .grad
的跨步,请在第一次 backward()
之前将一个具有所需跨步的零张量赋值给 param.grad =
,并且永远不要将其重置为 None
。只要 create_graph=False
,第 3 条就保证您的布局得到保留。第 4 条表明即使 create_graph=True
,您的布局也可能得到保留。
张量的就地操作¶
在自动微分中支持就地操作是一个难题,在大多数情况下我们不鼓励使用它们。自动微分的激进缓冲区释放和重用使其非常高效,就地操作实际上显著降低内存使用的情况非常少。除非您处于内存压力很大的情况下,否则可能永远不需要使用它们。
就地操作正确性检查¶
所有 Tensor
都跟踪应用到其上的就地操作,如果实现检测到某个张量在一个函数中被保存用于反向传播,但之后被就地修改,一旦反向传播开始,就会引发错误。这确保了如果您使用就地函数且没有看到任何错误,您可以确信计算出的梯度是正确的。
Variable (已弃用)¶
警告
Variable API 已被弃用:使用张量进行自动微分不再需要 Variable。自动微分自动支持设置了 requires_grad
为 True
的 Tensor。下面是关于已更改内容的快速指南。
Variable(tensor)
和Variable(tensor, requires_grad)
仍然按预期工作,但它们返回的是 Tensor 而不是 Variable。var.data
与tensor.data
相同。现在
var.backward(), var.detach(), var.register_hook()
等方法也可用于张量,方法名相同。
此外,现在可以使用工厂方法(如 torch.randn()
、torch.zeros()
、torch.ones()
等)创建 requires_grad=True
的张量,如下所示:
autograd_tensor = torch.randn((2, 3, 4), requires_grad=True)
Tensor 自动微分函数¶
|
此属性默认为 |
|
如果此 Tensor 需要计算梯度,则为 |
|
按照惯例,所有 |
|
计算当前张量相对于图叶节点的梯度。 |
|
返回一个新 Tensor,与当前计算图分离。 |
|
将 Tensor 与创建它的计算图分离,使其成为叶节点。 |
|
注册一个反向钩子。 |
|
注册一个在梯度累积后运行的反向钩子。 |
|
使此 Tensor 的 |
Function¶
- 类 torch.autograd.Function(*args, **kwargs)[source][source]¶
创建自定义 autograd.Function 的基类。
要创建自定义 autograd.Function,请从此类继承并实现
forward()
和backward()
静态方法。然后,要在前向传播中使用您的自定义算子,请调用类方法apply
。不要直接调用forward()
。为了确保正确性和最佳性能,请确保您调用了
ctx
上的正确方法,并使用torch.autograd.gradcheck()
验证了您的反向函数。有关如何使用此类的更多详细信息,请参阅扩展 torch.autograd。
示例
>>> class Exp(Function): >>> @staticmethod >>> def forward(ctx, i): >>> result = i.exp() >>> ctx.save_for_backward(result) >>> return result >>> >>> @staticmethod >>> def backward(ctx, grad_output): >>> result, = ctx.saved_tensors >>> return grad_output * result >>> >>> # Use it by calling the apply method: >>> output = Exp.apply(input)
定义自定义自动微分 Function 的前向计算。 |
|
定义使用反向模式自动微分进行操作求导的公式。 |
|
定义使用前向模式自动微分进行操作求导的公式。 |
|
定义此 autograd.Function 在 |
上下文方法混合¶
创建新的 Function
时,ctx 可使用以下方法。
将给定的张量标记为在就地操作中已修改。 |
|
将输出标记为不可微分。 |
|
保存给定的张量以供将来调用 |
|
设置是否具体化梯度张量。 |
自定义 Function 工具类¶
用于 backward 方法的装饰器。
用于构建 PyTorch 工具的基础自定义 Function
。
此类用于内部自动微分工作。 |
|
此类仅为向后兼容而存在。 |
|
此类仅为向后兼容而存在。 |
数值梯度检查¶
检查通过小有限差分计算的梯度与 |
|
检查通过小有限差分计算的梯度之梯度与 |
|
由 |
分析器¶
自动微分包含一个分析器,允许您检查模型中不同算子的成本 - 包括在 CPU 和 GPU 上。目前实现了三种模式:仅限 CPU 使用 profile
;基于 nvprof(同时记录 CPU 和 GPU 活动)使用 emit_nvtx
;以及基于 vtune 分析器使用 emit_itt
。
- 类 torch.autograd.profiler.profile(enabled=True, *, use_cuda=False, use_device=None, record_shapes=False, with_flops=False, profile_memory=False, with_stack=False, with_modules=False, use_kineto=False, use_cpu=True, experimental_config=None, acc_events=False, custom_trace_id_callback=None)[source][source]¶
管理自动微分分析器状态并保存结果摘要的上下文管理器。
在底层,它只是记录 C++ 中执行的函数事件,并将这些事件暴露给 Python。您可以将任何代码包装在其中,它将只报告 PyTorch 函数的运行时。注意:分析器是线程本地的,并自动传播到异步任务中。
- 参数
enabled (bool, 可选) – 将此设置为 False 会使此上下文管理器成为空操作。
use_cuda (bool, 可选) – 使用 cudaEvent API 同时启用 CUDA 事件的计时。(将被弃用)
use_device (str, 可选) – 启用设备事件的计时。使用 cuda 时,每张量操作会增加大约 4us 的开销。有效的设备选项是 ‘cuda’、‘xpu’、‘mtia’ 和 ‘privateuseone’。
record_shapes (bool, 可选) – 如果设置了形状记录,将收集关于输入维度的信息。这使得用户可以看到底层使用了哪些维度,并可以使用 prof.key_averages(group_by_input_shape=True) 进一步按维度分组。请注意,形状记录可能会扭曲您的分析数据。建议分别进行开启和关闭形状记录的运行来验证计时。对于最底层事件(在嵌套函数调用的情况下),扭曲很可能是微不足道的。但对于更高级别的函数,由于形状收集,总的自身 CPU 时间可能会人为增加。
with_flops (bool, 可选) – 如果设置了 with_flops,分析器将使用算子的输入形状估算 FLOPs(浮点运算)值。这使得用户可以估算硬件性能。目前,此选项仅适用于矩阵乘法和二维卷积算子。
profile_memory (bool, 可选) – 跟踪张量内存分配/释放。
with_stack (bool, 可选) – 记录算子的源信息(文件和行号)。
with_modules (bool) – 记录与算子调用栈对应的模块层次结构(包括函数名)。例如,如果模块 A 的 forward 调用了模块 B 的 forward,其中包含一个 aten::add 算子,则 aten::add 的模块层次结构是 A.B。注意,目前此支持仅适用于 TorchScript 模型而非即时模式模型。
use_kineto (bool, 可选) – 实验性功能,启用 Kineto 分析器进行性能分析。
use_cpu (bool, optional) – 分析 CPU 事件;设置为
False
需要use_kineto=True
,可用于降低纯 GPU 分析的开销。experimental_config (_ExperimentalConfig) – 由 Kineto 等分析库使用的一组实验性选项。注意,不保证向后兼容性。
acc_events (bool) – 启用跨多个分析周期的 FunctionEvents 累积
示例
>>> x = torch.randn((1, 1), requires_grad=True) >>> with torch.autograd.profiler.profile() as prof: >>> for _ in range(100): # any normal python code, really! >>> y = x ** 2 >>> y.backward() >>> # NOTE: some columns were removed for brevity >>> print(prof.key_averages().table(sort_by="self_cpu_time_total")) ----------------------------------- --------------- --------------- --------------- Name Self CPU total CPU time avg Number of Calls ----------------------------------- --------------- --------------- --------------- mul 32.048ms 32.048ms 200 pow 27.041ms 27.041ms 200 PowBackward0 9.727ms 55.483ms 100 torch::autograd::AccumulateGrad 9.148ms 9.148ms 100 torch::autograd::GraphRoot 691.816us 691.816us 100 ----------------------------------- --------------- --------------- ---------------
将 EventList 导出为 Chrome 追踪工具文件。 |
|
按键对所有函数事件求平均。 |
|
返回在 CPU 上花费的总时间。 |
|
对所有事件求平均。 |
|
如果一个键出现多次则抛出错误。 |
|
提供了一个抽象,用于全局增加步数计数。 |
|
上下文管理器/函数装饰器,在运行 autograd 分析器时为代码块/函数添加标签。 |
|
用于在间隔内访问 mem_records 的加速结构。 |
|
- class torch.autograd.profiler.emit_nvtx(enabled=True, record_shapes=False)[source][source]¶
上下文管理器,使每个 autograd 操作发出一个 NVTX 范围。
在 nvprof 下运行程序时非常有用
nvprof --profile-from-start off -o trace_name.prof -- <regular command here>
遗憾的是,无法强制 nvprof 将其收集的数据刷新到磁盘,因此对于 CUDA 分析,必须使用此上下文管理器来标注 nvprof 追踪,并在进程退出后才能检查它们。然后,可以使用 NVIDIA Visual Profiler (nvvp) 来可视化时间线,或者
torch.autograd.profiler.load_nvprof()
可以加载结果以供检查,例如在 Python REPL 中。- 参数
enabled (bool, optional) – 设置
enabled=False
会使此上下文管理器成为一个无操作(no-op)。默认值:True
。record_shapes (bool, optional) – 如果
record_shapes=True
,包裹每个 autograd 操作的 nvtx 范围将附加关于该操作接收到的 Tensor 参数尺寸的信息,格式如下:[[arg0.size(0), arg0.size(1), ...], [arg1.size(0), arg1.size(1), ...], ...]
非 Tensor 参数将用[]
表示。参数将按照后端操作接收它们的顺序进行列表。请注意,此顺序可能与这些参数在 Python 端传递的顺序不匹配。另请注意,形状记录可能会增加 nvtx 范围创建的开销。默认值:False
示例
>>> with torch.cuda.profiler.profile(): ... model(x) # Warmup CUDA memory allocator and profiler ... with torch.autograd.profiler.emit_nvtx(): ... model(x)
前向-后向关联
在 Nvidia Visual Profiler 中查看使用
emit_nvtx
创建的分析结果时,将每个后向传播操作与相应的前向传播操作关联起来可能会很困难。为了简化这项任务,emit_nvtx
会将序列号信息附加到其生成的范围内。在前向传播过程中,每个函数范围都用
seq=<N>
进行了标注。seq
是一个运行计数器,每次创建一个新的后向 Function 对象并为其后向传播而存储时递增。因此,与每个前向函数范围关联的seq=<N>
标注告诉您,如果此函数创建了一个后向 Function 对象,则该后向对象将接收序列号 N。在后向传播过程中,包裹每个 C++ 后向 Function 的apply()
调用的顶层范围用stashed seq=<M>
进行了标注。M 是创建后向对象时使用的序列号。通过比较后向传播中的stashed seq
数字与前向传播中的seq
数字,您可以追踪到哪个前向操作创建了哪个后向 Function。在后向传播期间执行的任何函数也用
seq=<N>
进行了标注。在默认后向传播(`create_graph=False` 时)期间,此信息不相关,实际上,对于所有此类函数,N
可能只是 0。只有与后向 Function 对象的apply()
方法关联的顶层范围有用,作为将这些 Function 对象与之前的正向传播关联起来的一种方式。二阶后向传播
另一方面,如果正在进行一个 `create_graph=True` 的后向传播(换句话说,如果您正在准备进行二阶后向传播),后向传播期间每个函数的执行都会被赋予一个非零且有用的
seq=<N>
。这些函数本身可能会创建 Function 对象,以便稍后在二阶后向传播期间执行,就像前向传播中的原始函数所做的那样。后向传播和二阶后向传播之间的关系在概念上与前向传播和后向传播之间的关系是相同的:这些函数仍然发出带有当前序列号标记的范围,它们创建的 Function 对象仍然存储这些序列号,并且在最终的二阶后向传播期间,Function 对象的apply()
范围仍然用stashed seq
数字进行标记,这些数字可以与后向传播中的 `seq` 数字进行比较。
- class torch.autograd.profiler.emit_itt(enabled=True, record_shapes=False)[source][source]¶
上下文管理器,使每个 autograd 操作发出一个 ITT 范围。
在 Intel(R) VTune Profiler 下运行程序时非常有用
vtune <--vtune-flags> <regular command here>
Instrumentation and Tracing Technology (ITT) API 使您的应用程序能够在执行期间跨不同的 Intel 工具生成和控制追踪数据的收集。此上下文管理器用于标注 Intel(R) VTune Profiling 追踪。借助此上下文管理器,您将能够在 Intel(R) VTune Profiler GUI 中看到带标签的范围。
- 参数
enabled (bool, optional) – 设置
enabled=False
会使此上下文管理器成为一个无操作(no-op)。默认值:True
。record_shapes (bool, optional) – 如果
record_shapes=True
,包裹每个 autograd 操作的 itt 范围将附加关于该操作接收到的 Tensor 参数尺寸的信息,格式如下:[[arg0.size(0), arg0.size(1), ...], [arg1.size(0), arg1.size(1), ...], ...]
非 Tensor 参数将用[]
表示。参数将按照后端操作接收它们的顺序进行列表。请注意,此顺序可能与这些参数在 Python 端传递的顺序不匹配。另请注意,形状记录可能会增加 itt 范围创建的开销。默认值:False
示例
>>> with torch.autograd.profiler.emit_itt(): ... model(x)
打开 nvprof 追踪文件并解析 autograd 标注。 |
调试和异常检测¶
- class torch.autograd.detect_anomaly(check_nan=True)[source][source]¶
启用 autograd 引擎异常检测的上下文管理器。
这做了两件事
在启用检测的情况下运行前向传播将允许后向传播打印创建失败后向函数的前向操作的追溯信息。
如果
check_nan
为True
,任何生成“nan”(非数字)值的后向计算将抛出错误。默认值True
。
警告
此模式应仅用于调试,因为不同的测试会减慢程序执行速度。
示例
>>> import torch >>> from torch import autograd >>> class MyFunc(autograd.Function): ... @staticmethod ... def forward(ctx, inp): ... return inp.clone() ... @staticmethod ... def backward(ctx, gO): ... # Error during the backward pass ... raise RuntimeError("Some error in backward") ... return gO.clone() >>> def run_fn(a): ... out = MyFunc.apply(a) ... return out.sum() >>> inp = torch.rand(10, 10, requires_grad=True) >>> out = run_fn(inp) >>> out.backward() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/your/pytorch/install/torch/_tensor.py", line 93, in backward torch.autograd.backward(self, gradient, retain_graph, create_graph) File "/your/pytorch/install/torch/autograd/__init__.py", line 90, in backward allow_unreachable=True) # allow_unreachable flag File "/your/pytorch/install/torch/autograd/function.py", line 76, in apply return self._forward_cls.backward(self, *args) File "<stdin>", line 8, in backward RuntimeError: Some error in backward >>> with autograd.detect_anomaly(): ... inp = torch.rand(10, 10, requires_grad=True) ... out = run_fn(inp) ... out.backward() Traceback of forward call that caused the error: File "tmp.py", line 53, in <module> out = run_fn(inp) File "tmp.py", line 44, in run_fn out = MyFunc.apply(a) Traceback (most recent call last): File "<stdin>", line 4, in <module> File "/your/pytorch/install/torch/_tensor.py", line 93, in backward torch.autograd.backward(self, gradient, retain_graph, create_graph) File "/your/pytorch/install/torch/autograd/__init__.py", line 90, in backward allow_unreachable=True) # allow_unreachable flag File "/your/pytorch/install/torch/autograd/function.py", line 76, in apply return self._forward_cls.backward(self, *args) File "<stdin>", line 8, in backward RuntimeError: Some error in backward
- class torch.autograd.set_detect_anomaly(mode, check_nan=True)[source][source]¶
上下文管理器,用于开启或关闭 autograd 引擎的异常检测。
set_detect_anomaly
将根据其参数mode
启用或禁用 autograd 异常检测。它可以作为上下文管理器或函数使用。有关异常检测行为的详细信息,请参阅上文的
detect_anomaly
。
上下文管理器,用于开启或关闭多线程后向传播。 |
Autograd 计算图¶
Autograd 提供了一些方法,允许检查计算图并在后向传播期间介入行为。
一个 torch.Tensor
的 grad_fn
属性持有一个 torch.autograd.graph.Node
,如果该 tensor 是一个被 autograd 记录的操作的输出(即,autograd 模式已启用并且至少有一个输入需要梯度),否则为 None
。
返回名称。 |
|
返回元数据。 |
|
注册一个后向钩子。 |
|
注册一个后向预钩子。 |
|
更新 autograd 元数据跟踪,跟踪给定的 Tensor 是否进行了原地修改。 |
一些操作需要在前向传播期间保存中间结果,以便执行后向传播。这些中间结果被保存为 grad_fn
上的属性,并且可以访问。例如
>>> a = torch.tensor([0., 0., 0.], requires_grad=True)
>>> b = a.exp()
>>> print(isinstance(b.grad_fn, torch.autograd.graph.Node))
True
>>> print(dir(b.grad_fn))
['__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_raw_saved_result', '_register_hook_dict', '_saved_result', 'metadata', 'name', 'next_functions', 'register_hook', 'register_prehook', 'requires_grad']
>>> print(torch.allclose(b.grad_fn._saved_result, b))
True
您还可以使用钩子定义这些保存的 tensor 如何打包/解包。一个常见的应用是牺牲计算来换取内存,方法是将这些中间结果保存到磁盘或 CPU,而不是将其留在 GPU 上。如果您的模型在评估期间适合 GPU,但在训练期间不适合,这尤其有用。另请参阅 保存的 tensor 的钩子。
- class torch.autograd.graph.saved_tensors_hooks(pack_hook, unpack_hook)[source][source]¶
上下文管理器,用于设置保存的 tensor 的一对打包/解包钩子。
使用此上下文管理器,定义一个操作的中间结果在保存前应如何打包,并在检索时如何解包。
在此上下文中,`pack_hook` 函数将在每次一个操作为后向传播保存一个 tensor 时被调用(这包括使用
save_for_backward()
保存的中间结果,以及由 PyTorch 定义的操作记录的结果)。然后,`pack_hook` 的输出被存储在计算图中,而不是原始 tensor。当保存的 tensor 需要被访问时,即在执行
torch.Tensor.backward()
或torch.autograd.grad()
时,`unpack_hook` 被调用。它以 `pack_hook` 返回的*打包*对象作为参数,并应返回一个 tensor,其内容与原始 tensor 相同(作为输入传递给相应的 `pack_hook`)。这些钩子应具有以下签名
pack_hook(tensor: Tensor) -> Any
unpack_hook(Any) -> Tensor
其中 `pack_hook` 的返回值是 `unpack_hook` 的有效输入。
通常,您希望 `unpack_hook(pack_hook(t))` 在值、尺寸、数据类型和设备方面等于 `t`。
示例
>>> def pack_hook(x): ... print("Packing", x) ... return x >>> >>> def unpack_hook(x): ... print("Unpacking", x) ... return x >>> >>> a = torch.ones(5, requires_grad=True) >>> b = torch.ones(5, requires_grad=True) * 2 >>> with torch.autograd.graph.saved_tensors_hooks(pack_hook, unpack_hook): ... y = a * b Packing tensor([1., 1., 1., 1., 1.], requires_grad=True) Packing tensor([2., 2., 2., 2., 2.], grad_fn=<MulBackward0>) >>> y.sum().backward() Unpacking tensor([1., 1., 1., 1., 1.], requires_grad=True) Unpacking tensor([2., 2., 2., 2., 2.], grad_fn=<MulBackward0>)
警告
在任意一个钩子的输入上执行原地操作可能会导致未定义的行为。
警告
一次只允许一对钩子。当递归嵌套此上下文管理器时,只有最内层的钩子对会被应用。
- class torch.autograd.graph.save_on_cpu(pin_memory=False, device_type='cuda')[source][source]¶
上下文管理器,在此管理器下,前向传播保存的 tensor 将存储在 CPU 上,然后为后向传播进行检索。
在此上下文管理器中执行操作时,在前向传播期间保存在计算图中的中间结果将被移动到 CPU,然后在后向传播需要时复制回原始设备。如果计算图已经在 CPU 上,则不执行 tensor 复制。
使用此上下文管理器,用计算换取 GPU 内存使用(例如,当您的模型在训练期间不适合 GPU 内存时)。
- 参数
pin_memory (bool) – 如果
True
,tensor 将在打包期间保存到 CPU 锁页内存(pinned memory),并在解包期间异步复制到 GPU。默认值为False
。另请参阅 使用锁页内存缓冲区。
示例
>>> a = torch.randn(5, requires_grad=True, device="cuda") >>> b = torch.randn(5, requires_grad=True, device="cuda") >>> c = torch.randn(5, requires_grad=True, device="cuda") >>> >>> def f(a, b, c): ... prod_1 = a * b # a and b are saved on GPU ... with torch.autograd.graph.save_on_cpu(): ... prod_2 = prod_1 * c # prod_1 and c are saved on CPU ... y = prod_2 * a # prod_2 and a are saved on GPU ... return y >>> >>> y = f(a, b, c) >>> del a, b, c # for illustration only >>> # the content of a, b, and prod_2 are still alive on GPU >>> # the content of prod_1 and c only live on CPU >>> y.sum().backward() # all CPU tensors are moved back to GPU, for backward >>> # all intermediary tensors are released (deleted) after the call to backward
- class torch.autograd.graph.disable_saved_tensors_hooks(error_message)[source][source]¶
上下文管理器,禁用保存的 tensor 默认钩子功能。
当您正在创建一个功能,但该功能与保存的 tensor 默认钩子不兼容时很有用。
- 参数
error_message (str) – 当保存的 tensor 默认钩子已被禁用但仍被使用时,将抛出一个带有此错误消息的 RuntimeError。
- 返回类型
Generator[None, None, None]
示例
>>> message = "saved tensors default hooks are disabled" >>> with torch.autograd.graph.disable_saved_tensors_hooks(message): ... # Raises RuntimeError: saved tensors default hooks are disabled ... with torch.autograd.graph.save_on_cpu(): ... pass
- class torch.autograd.graph.register_multi_grad_hook(tensors, fn, *, mode='all')[source][source]¶
注册一个多梯度后向钩子。
支持两种模式:
"all"
和"any"
。在
"all"
模式下,在计算完关于tensors
中每个 tensor 的梯度后将调用该钩子。如果一个 tensor 在tensors
中但不属于计算图的一部分,或者如果对于当前.backward()
或.grad()
调用指定的任何inputs
不需要一个 tensor 来计算梯度,这个 tensor 将被忽略,并且钩子不会等待其梯度被计算。在计算完所有非忽略 tensor 的梯度后,将使用这些梯度调用
fn
。对于未计算其梯度的 tensor 将传递None
。在
"any"
模式下,在计算完关于tensors
中某个 tensor 的第一个梯度后将调用钩子。将使用该梯度作为参数调用钩子。钩子不应修改其参数。
此函数返回一个带有方法
handle.remove()
的句柄,用于移除钩子。注意
有关此钩子何时执行以及其执行相对于其他钩子的顺序的更多信息,请参阅 后向钩子执行。
示例
>>> import torch >>> >>> a = torch.rand(2, 3, requires_grad=True) >>> b = torch.rand(2, 3, requires_grad=True) >>> c = a * b >>> d = a * b >>> >>> def fn(grads): ... print([g is not None for g in grads]) ... >>> torch.autograd.graph.register_multi_grad_hook((a, b, c, d), fn) >>> >>> c.sum().backward(retain_graph=True) [True, True, True, False] >>> c.sum().backward(inputs=(a,), retain_graph=True) [True, False, True, False] >>>
- 返回类型
RemovableHandle
- class torch.autograd.graph.allow_mutation_on_saved_tensors[source][source]¶
上下文管理器,在此管理器下允许修改为后向传播保存的 tensor。
在此上下文管理器下,为后向传播保存的 tensor 在修改时会被克隆,因此原始版本在后向传播期间仍然可以使用。通常,修改为后向传播保存的 tensor 将导致在后向传播期间使用它时抛出错误。
为了确保正确的行为,前向和后向传播都应在相同的上下文管理器下运行。
- 返回
一个
_AllowMutationOnSavedContext
对象,存储此上下文管理器管理的状态。此对象可用于调试目的。上下文管理器管理的状态在退出时自动清除。- 返回类型
Generator[_AllowMutationOnSavedContext, None, None]
示例
>>> import torch >>> with torch.autograd.graph.allow_mutation_on_saved_tensors(): ... # forward ... a = torch.ones(2, 3, requires_grad=True) ... b = a.clone() ... out = (b**2).sum() ... b.sin_() ... # backward ... out.sum().backward() ... tensor([[0.8415, 0.8415, 0.8415], [0.8415, 0.8415, 0.8415]], grad_fn=<SinBackward0>)
- class torch.autograd.graph.GradientEdge(node, output_nr)[source][source]¶
表示 autograd 计算图中给定梯度边的对象。
要获取将计算给定 Tensor 梯度的梯度边,您可以执行
edge = autograd.graph.get_gradient_edge(tensor)
。