自动微分包 - torch.autograd#
创建于: 2016年12月23日 | 最后更新于: 2025年11月01日
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 阶段。尽管函数签名发生更改的可能性极小,但在我们认为其稳定之前,计划将对其进行重大性能改进。
本节包含 autograd 的高级 API,它构建在上述基本 API 之上,允许您计算雅可比矩阵、海森矩阵等。
此 API 可与仅以张量作为输入并仅返回张量的用户提供函数配合使用。如果您的函数接受非张量参数或未设置 requires_grad 的张量,您可以使用 lambda 来捕获它们。例如,对于一个接受三个输入(一个我们想要雅可比矩阵的张量,另一个应视为常量的张量,以及一个布尔标志)的函数 f,即 f(input, constant, flag=flag),您可以使用如下方式调用:functional.jacobian(lambda x: f(x, constant, flag=flag), input)。
计算给定函数的雅可比矩阵。 |
|
计算给定标量函数的海森矩阵。 |
|
计算向量 |
|
计算给定函数在输入点处雅可比矩阵与向量 |
|
计算向量 |
|
计算标量函数的海森矩阵与指定点处的向量 |
局部禁用梯度计算#
有关 no-grad 和 inference 模式之间的区别以及其他可能与两者混淆的相关机制的更多信息,请参阅 局部禁用梯度计算。另请参阅 局部禁用梯度计算 以获取可用于局部禁用梯度的函数列表。
默认梯度布局#
当一个非稀疏 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的步幅。
建议采用默认行为(让 .grad 在第一次 backward() 调用前为 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。3 保证您的布局在 create_graph=False 的情况下得以保留。4 指出即使 create_graph=True,您的布局也 *可能* 会保留。
张量的原地操作#
在 autograd 中支持原地操作是一个棘手的问题,并且我们不鼓励在大多数情况下使用它们。Autograd 的积极缓冲区释放和重用使其非常高效,并且很少有原地操作能真正显著地降低内存使用量。除非您处于内存压力很大的情况下,否则您可能永远不需要使用它们。
原地操作正确性检查#
所有 Tensor 都会跟踪应用于它们的原地操作,如果实现检测到某个张量已被用于反向传播,但随后在其上进行了原地修改,则在反向传播开始时会引发错误。这确保了如果您使用原地函数但未看到任何错误,您可以确信计算出的梯度是正确的。
Variable (已弃用)#
警告
Variable API 已被弃用:使用张量进行 autograd 已不再需要 Variable。Autograd 自动支持 requires_grad 设置为 True 的张量。以下是更改内容的快速指南:
Variable(tensor)和Variable(tensor, requires_grad)仍然按预期工作,但它们返回张量而不是 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)
张量自动微分函数#
|
此属性默认情况下为 |
|
如果需要为此张量计算梯度,则为 |
|
所有 |
|
计算当前张量相对于图叶的梯度。 |
|
返回一个从当前图分离的新张量。 |
|
从创建它的图中分离张量,使其成为叶节点。 |
|
注册一个反向钩子。 |
|
注册一个在梯度累积后运行的反向钩子。 |
|
在 |
Function#
- class torch.autograd.Function(*args, **kwargs)[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)
定义自定义自动微分函数的前向传播。 |
|
定义使用反向模式自动微分来区分操作的公式。 |
|
定义使用前向模式自动微分来区分操作的公式。 |
|
定义此 autograd.Function 在 |
上下文方法混合#
创建新的 Function 时,以下方法可供 ctx 使用。
将给定张量标记为在就地操作中已修改。 |
|
将输出标记为不可微分。 |
|
保存给定张量以供将来调用 |
|
设置是否具体化梯度张量。 |
自定义函数实用工具#
反向传播方法的装饰器。
用于构建 PyTorch 工具的基类自定义 Function。
此类用于内部 autograd 工作。 |
|
此类仅为向后兼容性原因而存在。 |
|
此类仅为向后兼容性原因而存在。 |
数值梯度检查#
检查通过小有限差分计算出的梯度与 |
|
检查通过小有限差分计算出的梯度的梯度与 |
|
由 |
性能分析器#
Autograd 提供了一个性能分析器,可以检查模型中不同操作(CPU 和 GPU)的开销。目前实现了三种模式:仅 CPU 的 profile。基于 nvprof(记录 CPU 和 GPU 活动)的 emit_nvtx。以及基于 vtune 性能分析器的 emit_itt。
- class 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]#
上下文管理器,用于管理 autograd 性能分析器状态并保存结果摘要。
注意
这是后端,大多数人应该使用
torch.profiler。它只是记录 C++ 中执行的函数事件,并将这些事件暴露给 Python。您可以将任何代码包装其中,它只会报告 PyTorch 函数的运行时。注意:性能分析器是线程本地的,并且会自动传播到异步任务中。
- 参数:
enabled (bool, optional) – 将此设置为 False 使此上下文管理器无效。
use_cuda (bool, optional) – 使用 cudaEvent API 启用 CUDA 事件计时。(将被弃用)
use_device (str, optional) – 启用设备事件计时。当使用 CUDA 时,每个张量操作会增加约 4us 的开销。有效的设备选项是 'cuda'、'xpu'、'mtia' 和 'privateuseone'。
record_shapes (bool, optional) – 如果设置了形状记录,将收集有关输入维度信息。这使您可以查看在底层使用了哪些维度,并使用 prof.key_averages(group_by_input_shape=True) 按它们进行分组。请注意,形状记录可能会影响您的性能分析数据。建议使用单独的运行(带或不带形状记录)来验证计时。最底层事件(在嵌套函数调用的情况下)的形状记录偏差最可能可以忽略。但对于更高级别的函数,由于形状收集,总的 CPU 自我时间可能会被人为地增加。
with_flops (bool, optional) – 如果设置了 with_flops,性能分析器将使用操作的输入形状来估算 FLOPs(浮点运算)值。这使您可以估算硬件性能。目前,此选项仅适用于矩阵乘法和二维卷积运算符。
profile_memory (bool, optional) – 跟踪张量内存分配/取消分配。
with_stack (bool, optional) – 记录操作的源信息(文件和行号)。
with_modules (bool) – 记录与操作的调用栈对应的模块层次结构(包括函数名)。例如,如果模块 A 的 forward 调用模块 B 的 forward,而模块 B 包含一个 aten::add 操作,则 aten::add 的模块层次结构是 A.B。请注意,目前此支持仅适用于 TorchScript 模型,而不适用于 eager 模式模型。
use_kineto (bool, optional) – 实验性功能,使用 Kineto 性能分析器启用性能分析。
use_cpu (bool, optional) – 分析 CPU 事件;将其设置为
False需要use_kineto=True,并且可以用于降低仅 GPU 性能分析的开销。experimental_config (_ExperimentalConfig) – Kineto 等性能分析库使用的实验性选项集合。注意,不保证向后兼容性。
acc_events (bool) – 启用多个性能分析周期之间 FunctionEvents 的累加。
警告
启用内存分析或源属性会增加额外的性能分析开销。
警告
不应递归调用此上下文管理器,即不允许嵌套实例。
警告
由于一些 CUDA 多进程限制(参见 多进程中的 CUDA),不能使用
use_device = 'cuda'的性能分析器来基准测试num_workers > 0的 DataLoaders。如果您想基准测试数据加载,请使用use_device = None或num_workers = 0。示例
>>> 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 Tracing 工具文件。 |
|
按键对所有函数事件进行平均。 |
|
返回在 CPU 上花费的总时间。 |
|
计算所有事件的聚合统计信息。 |
|
如果一个键被看到多次,则引发错误。 |
|
提供了一个全局增加步数的抽象。 |
|
上下文管理器/函数装饰器,可在运行 autograd 性能分析器时为代码块/函数添加标签。 |
|
用于访问间隔中 mem_records 的加速结构。 |
|
- class torch.autograd.profiler.emit_nvtx(enabled=True, record_shapes=False)[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设置为使此上下文管理器无效。默认值:True。record_shapes (bool, optional) – 如果
record_shapes=True,则包装每个 autograd op 的 nvtx 范围将附加该 op 接收的 Tensor 参数的大小信息,格式如下:[[arg0.size(0), arg0.size(1), ...], [arg1.size(0), arg1.size(1), ...], ...]非 Tensor 参数将用[]表示。参数将按后端 op 接收的顺序排列。请注意,此顺序可能与这些参数在 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创建的配置文件时,将每个后向传播 op 与相应的前向传播 op 进行关联可能很困难。为了简化此任务,emit_nvtx会将序列号信息附加到它生成的范围。在正向传播过程中,每个函数范围都用
seq=<N>进行修饰。seq是一个运行计数器,每次创建并隐藏一个用于后向传播的新的后向 Function 对象时递增。因此,与每个前向函数范围关联的seq=<N>注释会告诉您,如果此前向函数创建了一个后向 Function 对象,则该后向对象将接收序列号 N。在后向传播过程中,包装每个 C++ 后向 Function 的apply()调用的顶级范围用stashed seq=<M>进行修饰。M是后向对象创建时使用的序列号。通过比较后向传播中的stashed seq编号与前向传播中的seq编号,您可以追溯是哪个前向 op 创建了每个后向 Function。在后向传播过程中执行的任何函数也用
seq=<N>进行修饰。在默认的后向传播(create_graph=False)中,此信息无关紧要,事实上,对于所有此类函数,N可能只是 0。只有与后向 Function 对象的apply()方法关联的顶级范围才有用,因为它们可以与之前的正向传播进行关联。双后向
另一方面,如果正在进行带有
create_graph=True的后向传播(换句话说,如果您正在为双后向传播做准备),那么后向传播过程中执行的每个函数都会获得一个非零且有用的seq=<N>。这些函数本身可能会创建 Function 对象供以后在双后向传播中使用,就像正向传播中的原始函数一样。后向传播与双后向传播之间的关系概念上与前向传播与后向传播之间的关系相同:函数仍然发出带有当前序列号标记的范围,它们创建的 Function 对象仍然会隐藏这些序列号,并且在最终的双后向传播过程中,Function 对象的apply()范围仍然用stashed seq编号进行标记,这些编号可以与后向传播中的 seq 编号进行比较。
- class torch.autograd.profiler.emit_itt(enabled=True, record_shapes=False)[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设置为使此上下文管理器无效。默认值:True。record_shapes (bool, optional) – 如果
record_shapes=True,则包装每个 autograd op 的 itt 范围将附加该 op 接收的 Tensor 参数的大小信息,格式如下:[[arg0.size(0), arg0.size(1), ...], [arg1.size(0), arg1.size(1), ...], ...]非 Tensor 参数将用[]表示。参数将按后端 op 接收的顺序排列。请注意,此顺序可能与这些参数在 Python 端传递的顺序不匹配。另请注意,形状记录可能会增加 itt 范围创建的开销。默认值:False
示例
>>> with torch.autograd.profiler.emit_itt(): ... model(x)
打开一个 nvprof 跟踪文件并解析 autograd 注释。 |
调试和异常检测#
- class torch.autograd.detect_anomaly(check_nan=True)[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]#
用于打开或关闭 autograd 引擎异常检测的上下文管理器。
set_detect_anomaly将根据其参数mode来启用或禁用 autograd 异常检测。它可以作为上下文管理器或函数使用。有关异常检测行为的详细信息,请参阅上面的
detect_anomaly。
用于打开或关闭多线程后向传播的上下文管理器。 |
Autograd 图#
Autograd 提供方法,允许检查图并在后向传播过程中插入行为。
如果张量是 autograd 记录的操作的输出(即,启用了 grad_mode 并且至少一个输入需要梯度),则 torch.Tensor 的 grad_fn 属性将保存一个 torch.autograd.graph.Node,否则为 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
您还可以使用钩子定义如何打包/解包这些保存的张量。一个常见的应用是通过将这些中间结果保存到磁盘或 CPU 来用计算换取内存,而不是将它们留在 GPU 上。如果您发现模型在评估时适合 GPU,但在训练时则不适合,这尤其有用。另请参阅 保存张量的钩子。
- class torch.autograd.graph.saved_tensors_hooks(pack_hook, unpack_hook)[source]#
设置已保存张量的一对打包/解包钩子的上下文管理器。
使用此上下文管理器来定义操作的中间结果在保存前如何打包,以及在检索时如何解包。
在此上下文中,每次操作保存张量以供后向传播时(这包括使用
save_for_backward()保存的中间结果,以及 PyTorch 定义的操作记录的中间结果),都会调用pack_hook函数。pack_hook的输出将存储在计算图中,而不是原始张量。当需要访问已保存张量时(即执行
torch.Tensor.backward()或torch.autograd.grad()时),将调用unpack_hook。它接收pack_hook返回的 *打包* 对象作为参数,并应返回一个与原始张量(传递给相应的pack_hook)具有相同内容的张量。钩子应具有以下签名
pack_hook(tensor: Tensor) -> Any
unpack_hook(Any) -> Tensor
其中
pack_hook的返回值是unpack_hook的有效输入。通常,您希望
unpack_hook(pack_hook(t))在值、大小、dtype 和设备方面等于t。示例
>>> def pack_hook(x): ... print("Packing", x) ... return x.detach() >>> >>> 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>)
警告
对任一钩子的输入执行就地操作可能会导致未定义行为。
警告
一次只允许一对钩子。当递归嵌套此上下文管理器时,只有最内层的一对钩子将被应用。
警告
为了避免引用循环,
pack_hook的返回值不能持有对输入张量的引用。例如,使用 lambda x: x.detach() 而不是 lambda x: x 作为 pack 钩子。
- class torch.autograd.graph.save_on_cpu(pin_memory=False, device_type='cuda')[source]#
在此上下文管理器下,正向传播保存的张量将被存储在 CPU 上,然后在后向传播时检索。
当在此上下文管理器下执行操作时,正向传播期间在图中保存的中间结果将被移动到 CPU,然后在后向传播需要时复制回原始设备。如果图已在 CPU 上,则不会执行张量复制。
使用此上下文管理器来用 GPU 内存使用率换取计算(例如,当您的模型在训练期间不适合 GPU 内存时)。
示例
>>> 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]#
禁用已保存张量默认钩子功能的上下文管理器。
如果您正在创建一项不适用于已保存张量默认钩子的功能,则此功能很有用。
- 参数:
error_message (str) – 当使用已禁用但已使用的已保存张量默认钩子时,将引发带有此错误消息的 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]#
注册一个多梯度后向钩子。
支持两种模式:“
all”和“any”。在“
all”模式下,钩子将在计算完tensors中每个张量的梯度后被调用。如果一个张量在tensors中但不是图的一部分,或者一个张量不需要用于计算当前.backward()或.grad()调用指定的inputs的梯度,则该张量将被忽略,钩子将不等待其梯度被计算。在计算完所有非忽略张量的梯度后,
fn将用这些梯度被调用。None将传递给未计算其梯度的张量。在“
any”模式下,钩子将在计算完tensors中第一个张量的梯度后被调用。钩子将用该梯度作为其参数被调用。钩子不应修改其参数。
此函数返回一个带有
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]#
允许修改为后向传播保存的张量的上下文管理器。
在此上下文管理器下,为后向传播保存的张量在修改时将被克隆,以便原始版本仍可在后向传播中使用。正常情况下,修改为后向传播保存的张量将在后向传播期间使用时引发错误。
为确保正确行为,前向和后向传播都应在同一上下文管理器下运行。
- 返回:
一个 _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, ownership_token=None)[source]#
表示 autograd 图中给定梯度边的对象。
要获取将计算给定张量梯度的梯度边,可以执行
edge = autograd.graph.get_gradient_edge(tensor)。
- torch.autograd.graph.get_gradient_edge(tensor)[source]#
获取计算给定张量梯度的梯度边。
特别是,调用
g = autograd.grad(loss, input)和g = autograd.grad(loss, get_gradient_edge(input))是等效的。- 返回类型:
- torch.autograd.graph.set_warn_on_accumulate_grad_stream_mismatch(enabled)[source]#
当 AccumulateGrad 节点的流与产生传入梯度的节点的流不匹配时是否发出警告。