• 文档 >
  • 模块代码 >
  • torch >
  • torch.amp.autocast_mode
快捷键

torch.amp.autocast_mode 源代码

# mypy: 允许未类型化定义
导入 集合
导入 functools
导入 警告
来自 打字 导入 任何, 可选

导入 火炬
来自 torch 的类型 导入 _dtype


尝试:
    导入 numpy as np

    HAS_NUMPY = 真实
除了 模块未找到错误:
    HAS_NUMPY = 
    np =   # 类型:忽略[赋值]

全部 = [
    autocast 装饰器,
    "自动转换",
    是否支持 autocast,
    "custom_fwd",
    "custom_bwd",
]


[文档]def is_autocast_available(device_type: str) -> bool: r""" 返回一个布尔值,指示是否在 :attr:`device_type` 上可用自动类型转换。 Args: device_type(str): 要使用的设备类型。可能的值有:'cuda'、'cpu'、'mtia'、'xpu' 等。 类型与 :class:`torch.device` 的 `type` 属性相同。 因此,您可以使用 `Tensor.device.type` 获取张量的设备类型。 """ 返回是否支持自动铸造成就可用(device_type)
def autocast_decorator(自动铸件实例
, 函数): @functools.包装(函数) def 装饰自动铸件(*参数, **kwargs): 替换为 自动铸件实例: 返回 函数(*参数, **kwargs) 装饰自动铸件.支持脚本 = 在脚本模式下不支持 @autocast() 装饰器 # 类型:忽略[已定义] 返回 装饰_autocast
[文档] 自动播: r"" class:`autocast` 的实例作为上下文管理器或装饰器 允许您的脚本中的某些区域以混合精度运行。 在这些区域,操作以由 autocast 选择的操作特定数据类型运行 以提高性能的同时保持精度。 有关详细信息,请参阅::ref:`Autocast 操作参考`。 当进入自动类型转换区域时,张量可以是任何类型。 在使用自动类型转换时,不应在您的模型或输入上调用 `half()` 或 `bfloat16()`。 `:class:`autocast` 应仅包装您网络的正向传递(传递),包括损失 计算过程。在自动类型转换下不建议进行反向传递。 后向操作运行与 autocast 用于对应前向操作相同的类型。 CUDA 设备示例: 默认精度下创建模型和优化器 model = Net().cuda() 优化器 = optim.SGD(model.parameters(), ...) for input, target in data: optimizer.zero_grad() # 启用前向传递(模型 + 损失)的自动类型转换 with torch.autocast(device_type="cuda"): output = 模型(input) loss = 损失函数(output, target) # 在 backward() 之前退出上下文管理器 loss.backward() optimizer.step() 请参阅:ref:`自动混合精度示例`了解用法(包括梯度缩放) 在更复杂的情况下(例如,梯度惩罚、多个模型/损失、自定义自动微分函数)。 class:`autocast` 也可以用作装饰器,例如,在您的模型的 ``forward`` 方法上使用: class AutocastModel(nn.Module): ... @torch.autocast(device_type="cuda") def forward(self, input): ... 在启用自动铸造的区域产生的浮点张量可能是 ``float16``。 返回到禁用自动铸造的区域后,使用它们进行浮点操作 不同数据类型的张量可能会导致类型不匹配错误。如果是这样,请将自动转换区域产生的张量(或多个张量)转换回 `float32`(或所需的其它数据类型)。 如果自动转换区域的张量已经是 `float32` 类型,则转换操作不会执行,也不会产生额外的开销。 如果自动转换区域的张量已经是 `float32`,则转换操作不会执行, 也不会产生额外的开销。 CUDA 示例:: # 创建一些默认数据类型(此处假设为 float32)的张量 a_float32 = torch.rand((8, 8), device="cuda") b_float32 = torch.rand((8, 8), device="cuda") c_float32 = torch.rand((8, 8), device="cuda") d_float32 = torch.rand((8, 8), device="cuda") with torch.autocast(device_type="cuda"): # torch.mm 在 autocast 的操作列表中,应运行在 float16 格式。 输入是 float32,但操作在 float16 上运行并产生 float16 输出。 无需手动转换。 e_float16 = torch.mm(a_float32, b_float32) 同样处理混合输入类型。 f_float16 = torch.mm(d_float32, e_float16) # After exiting autocast, calls f_float16.float() to use with d_float32 g_float32 = torch.mm(d_float32, f_float16.float()) CPU 训练示例:: 默认精度下创建模型和优化器 创建 Net 模型 优化器 = optim.SGD(model.parameters(), ...) for 循环遍历 epochs for input, target in data: optimizer.zero_grad() # 运行带有自动转换的前向传递。 with torch.autocast(device_type="cpu", dtype=torch.bfloat16): output = 模型(input) loss = 损失函数(output, target) loss.backward() optimizer.step() CPU 推理示例:: 创建默认精度模型 model = Net().eval() with torch.autocast(device_type="cpu", dtype=torch.bfloat16): for input in data: # 运行带有自动转换的前向传递。 output = 模型(input) 使用 Jit Trace 的 CPU 推理示例: class TestModel(nn.Module): def __init__(self, 输入大小, 类别数): super().__init__() self.fc1 = nn.Linear(输入大小, 类别数) def forward(self, x): return self.fc1(x) 输入大小 = 2 num_classes = 2 model = TestModel(input_size, num_classes).eval() # 目前建议禁用 Jit Autocast Pass, # 因为问题:https://github.com/pytorch/pytorch/issues/75956 torch._C._jit_set_autocast_mode(False) with torch.cpu.amp.autocast(cache_enabled=False): model = torch.jit.trace(model, torch.randn(1, input_size)) model = torch.jit.freeze(model) 模型运行 for _ in range(3): model(torch.randn(1, 输入大小)) 在自动转换区域中出现的类型不匹配错误是一个错误;如果您观察到这种情况, 请提交一个问题。 ``autocast(enabled=False)`` 子区域可以嵌套在启用 autocast 的区域中。 局部禁用 autocast 可能很有用,例如,如果您想强制子区域 在特定的 ``dtype`` 中运行。禁用 autocast 可以让您拥有显式的控制权, 执行类型。在子区域中,来自周边区域的输入在使用前应转换为 ``dtype`` 应在使用前将输入转换为 ``dtype`` 类型:: # 创建一些默认数据类型(此处假设为 float32)的张量 a_float32 = torch.rand((8, 8), device="cuda") b_float32 = torch.rand((8, 8), device="cuda") c_float32 = torch.rand((8, 8), device="cuda") d_float32 = torch.rand((8, 8), device="cuda") with torch.autocast(device_type="cuda"): e_float16 = torch.mm(a_float32, b_float32) with torch.autocast(device_type="cuda", enabled=False): # 调用 e_float16.float() 确保执行为 float32 # (因为 e_float16 是在 autocasted 区域创建的,所以有必要) f_float32 = torch.mm(c_float32, e_float16.float()) 在重新进入自动类型转换开启区域时,无需手动转换。 无论输入类型如何,torch.mm 再次以 float16 运行并产生 float16 输出。 g_float16 = torch.mm(d_float32, f_float32) 自动铸态是线程局部的。如果你想在新的线程中启用它,请使用上下文管理器或装饰器 必须在那个线程中调用。这影响::class:`torch.nn.DataParallel`和 `:class:`torch.nn.parallel.DistributedDataParallel` 在每个进程使用超过一个 GPU 时 (参见::ref:`使用多个 GPU》) 参数: device_type(str, required): 使用设备类型。可能的值有:'cuda', 'cpu', 'mtia', 'xpu', 和 'hpu'。 类型与 :class:`torch.device` 的 `type` 属性相同。 因此,您可以使用 `Tensor.device.type` 获取张量的设备类型。 enabled(bool, optional): 是否在该区域启用自动类型转换。 默认:``True`` dtype(torch_dtype, optional): 自动类型转换中操作的数值类型。它使用默认值 (对于 CUDA 为 ``torch.float16``,对于 CPU 为 ``torch.bfloat16``),由 `torch.get_autocast_dtype`,如果 `dtype` 为 `None`。 默认:`None` cache_enabled(bool, 可选): 在 autocast 内部的权重缓存是否启用。 默认:``True`` """ def __init__( self, 设备类型: str, 数据类型: 可选[数据类型] = , 启用: 布尔值 = True, cache_enabled: 可选[bool] = , ): 如果 isinstance(设备类型, str): 抛出 值错误( f预期 `device_type` 为 `str` 类型,实际得到:`{类型(设备类型)} ) 如果 dtype : dtype = PyTorch.获取自动类型转换(设备类型) 如果 PyTorch._jit_internal.是否正在脚本化(): self.启用 = 启用 self.设备 = 设备类型 self.快速数据类型 = dtype 断言 dtype 返回 self.设备 = 设备类型 如果 自动广播是否可用(self.设备): 抛出 运行时错误( f"用户指定了一个不支持的自动转换设备类型"{self.设备} ) self.自定义后端名称 = PyTorch._C._get_privateuse1_backend_name() self.快速数据类型 = PyTorch.获取自动类型转换(self.设备) 如果 self.设备 == self.自定义后端名称: 必要的函数 = [ "获取支持自动放大(AMP)的数据类型", ] 消息 = f尝试使用 AMP 与`{self.自定义后端名称}后端,但后端还没有“ 消息 += 注册了一个模块或该模块缺少一些必要的功能。后端应该注册 消息 += 一个由 `torch._register_device_module` 定义的模块,并且该模块必须具有以下函数:输入文本翻译为简体中文为: \n" 消息 += `get_amp_supported_dtype() -> List[torch.dtype]`. 翻译为:`获取支持自动混合精度的数据类型() -> torch.dtype 列表`.输入文本翻译为简体中文为: \n" 断言 有属性(PyTorch, self.自定义后端名称), 消息 self.自定义设备模块 = getattr(PyTorch, self.自定义后端名称) for 函数 必要的函数: 断言 有属性(self.自定义设备模块, 函数), ( 消息 + f但是函数 `{函数}缺少。输入文本翻译为简体中文为: \n" ) self.缓存已启用 = PyTorch.is_autocast_cache_enabled() 如果 ( 启用 PyTorch.cuda.转换.常见.AMP 绝对不可用() self.设备 == "cuda" ): 警告.警告( "用户提供的设备类型为'cuda',但 CUDA 不可用。禁用" ) 启用 = 如果 dtype : self.快速数据类型 = dtype 如果 缓存已启用 : self.缓存已启用 = cache_enabled 如果 self.设备 == "cpu": 支持的数据类型 = [PyTorch.bfloat16, PyTorch.float16] 如果 self.快速数据类型 支持的数据类型 启用: 错误信息 = 在 CPU 自动类型转换中,但目标数据类型不受支持。禁用自动转换。输入文本翻译为简体中文为:\n" 错误信息 += CPU 自动类型转换仅支持数据类型为 错误信息 += ( “,”.连接(str(数据类型) for dtype 支持的数据类型) + "目前。" ) 警告.警告(错误信息) 启用 = 如果...否则 self.设备 == 翻译: 支持的数据类型 = [PyTorch.bfloat16, PyTorch.float16] 如果 self.快速数据类型 支持的数据类型: 错误信息 = "在 MTIA autocast 中,但目标数据类型不受支持。禁用 autocast。输入文本翻译为简体中文为:\n" 错误信息 += "MTIA Autocast 目前仅支持 torch.bfloat16 和 torch.float16 数据类型。" 警告.警告(错误信息) 启用 = 如果...否则 self.设备 == XPU: 支持的数据类型 = [PyTorch.bfloat16, PyTorch.float16] 如果 self.快速数据类型 支持的数据类型: 错误信息 = "在 XPU autocast 中,但目标数据类型不受支持。禁用 autocast。输入文本翻译为简体中文为:\n" 错误信息 += "XPU Autocast 目前仅支持 torch.bfloat16 和 torch.float16 数据类型。" 警告.警告(错误信息) 启用 = 如果...否则 self.设备 == 知识产权: 支持的数据类型 = [PyTorch.bfloat16, PyTorch.float16] 如果 self.快速数据类型 支持的数据类型: 错误信息 = 在 IPU autocast 中,但目标数据类型不受支持。禁用 autocast。输入文本翻译为简体中文为:\n" 错误信息 += 目前 IPU Autocast 仅支持 torch.bfloat16 和 torch.float16 数据类型。 警告.警告(错误信息) 启用 = 如果...否则 self.设备 == hpu: 支持的数据类型 = [PyTorch.bfloat16, PyTorch.float16] 如果 self.快速数据类型 支持的数据类型: 错误信息 = "在 HPU autocast 中,但目标数据类型不受支持。禁用 autocast。输入文本翻译为简体中文为:\n" 错误信息 += "HPU Autocast 目前仅支持 torch.bfloat16 和 torch.float16 数据类型。" 警告.警告(错误信息) 启用 = 如果...否则 self.设备 == self.自定义后端名称: 支持的数据类型 = self.自定义设备模块.获取支持的放大数据类型() 如果 self.快速数据类型 支持的数据类型: 错误信息 = f{self.自定义后端名称}autocast 中,但目标数据类型不受支持。 错误信息 += f禁用自动转换。输入文本翻译为简体中文为:\n {self.自定义后端名称}自动转换仅支持以下数据类型 " 错误信息 += ( “,”.连接(str(数据类型) for dtype 支持的数据类型) + "目前。" ) 警告.警告(错误信息) 启用 = 如果...否则 self.设备 == cuda: 如果 ( 启用 self.快速数据类型 == PyTorch.bfloat16 PyTorch.cuda.支持 BF16() ): 抛出 运行时错误( "当前 CUDA 设备不支持 bfloat16 数据类型。请将数据类型切换为 float16。" ) 如果...否则 self.设备 == 国会议员: 支持的数据类型 = [PyTorch.bfloat16, PyTorch.float16] 如果 self.快速数据类型 支持的数据类型: 错误信息 = ( 在 MPS autocast 中,但目标数据类型不受支持。禁用 autocast。输入文本翻译为简体中文为:\n" "MPS Autocast 目前仅支持 torch.bfloat16 和 torch.float16 数据类型。" ) 警告.警告(错误信息) 启用 = 如果...否则 self.快速数据类型 == PyTorch.bfloat16: 如果 PyTorch.后端.会员.macOS 或更高版本(14, 0): 错误信息 = ( 在 MPS autocast 中,但目标数据类型 torch.bfloat16 不受支持 在低于 14 的 macOS 版本上。禁用 autocast。 ) 警告.警告(错误信息) 启用 = 如果...否则 self.设备 == "xla": 支持的数据类型 = [PyTorch.float16, PyTorch.bfloat16] 如果 self.快速数据类型 支持的数据类型: 错误信息 = 在 XLA autocast 中,但目标数据类型不受支持。禁用 autocast。输入文本翻译为简体中文为:\n" 错误信息 += ( "XLA Autocast 目前仅支持 torch.bfloat16 数据类型。" ) 警告.警告(错误信息) 启用 = self.启用 = 启用 def __进入__(self): 如果 PyTorch._jit_internal.是否正在脚本化(): 断言 self.快速数据类型 返回 self self.之前缓存启用 = PyTorch.is_autocast_cache_enabled() self.上一个 = PyTorch.是否启用自动转换(self.设备) self.之前快速数据类型 = PyTorch.获取自动类型转换(self.设备) PyTorch.设置自动转换启用(self.设备, self.启用) PyTorch.设置自动类型转换(self.设备, self.快速数据类型) # type: ignore[arg-type] PyTorch.自动转换增加嵌套层级() PyTorch.set_autocast_cache_enabled(self._缓存启用) 仅派发到 PreDispatchTorchFunctionMode 以避免暴露此 # API 至其他功能模式。我们仅暴露给 PreDispatchTorchFunctionMode # 用于在 torch.export.export 中保留 autocast 如果 PyTorch._C.火炬功能模式是否启用(): = PyTorch.覆盖._获取当前功能模式栈() for 模式 : 如果 isinstance( 模式, PyTorch.fx.试验性的.代理张量.预分发火炬函数模式, ): args = ( self.设备, self.快速数据类型, self.启用, self._缓存启用, ) 返回 模式.__torch_function__(PyTorch.转换._自动播放入口, (), 参数) def __退出__(self, 异常类型: 任何, 异常值: 任何, 异常堆栈: 任何): # 类型:忽略[重写] 如果 PyTorch._jit_internal.是否正在脚本化(): 返回 # 当我们退出到任何自动转换实例之外的外部嵌套级别时,删除缓存。 如果 PyTorch.autocast_decrement_nesting() == 0: PyTorch.清除自动类型转换缓存() PyTorch.设置自动转换启用(self.设备, self.上一页) PyTorch.设置自动类型转换(self.设备, self.prev_fastdtype) PyTorch.set_autocast_cache_enabled(self.prev_cache_enabled) 仅派发到 PreDispatchTorchFunctionMode 以避免暴露此 # API 至其他功能模式。我们仅暴露给 PreDispatchTorchFunctionMode # 用于在 torch.export.export 中保留 autocast 如果 PyTorch._C.火炬功能模式是否启用(): = PyTorch.覆盖._获取当前功能模式栈() for 模式 : 如果 isinstance( 模式, PyTorch.fx.试验性的.代理张量.预分发火炬函数模式, ): 返回 模式.__torch_function__(PyTorch.转换._自动播出版本退出, (), ()) 返回 def __调用__(self, 函数): 如果 PyTorch._jit_internal.是否正在脚本化(): 返回 函数 返回 autocast_decorator(self, 函数)
# 这些函数不打算供公共使用。 # 它们是我们预分发跟踪期间追踪到图中的函数。 当遇到自动类型转换上下文管理器时。 def _自动播放入口(*vals): 对于预调度跟踪,如果激活了 TorchFunction 模式,我们希望将其跟踪到图中。 如果 PyTorch._C.火炬功能模式是否启用(): 返回 PyTorch.覆盖.handle_torch_function( PyTorch.转换._自动播放入口, [] *vals ) 模式 = PyTorch.转换.自动播(*vals) 模式.__进入__() 返回 模式 def _自动播出版本退出(模式): 如果 PyTorch._C.火炬功能模式是否启用(): 返回 PyTorch.覆盖.handle_torch_function(PyTorch.转换._自动播出版本退出, [] 模式) 模式.__退出__(, , ) # 将张量和张量容器进行转换。对于字符串和 np.ndarrays 的特殊情况,可以直通,可能错误地检测为“可迭代对象”。 # 可能被错误地检测为“可迭代对象”。 def _类型转换(value, 设备类型: str, 数据类型: 数据类型): 如果 isinstance(value, PyTorch.张量): 是否符合资格 = ( value.is_floating_point() value.设备.类型 == 设备类型 (value.dtype PyTorch.float64) ) 返回 value.(数据类型) 如果 是否符合资格 否则 如果...否则 isinstance(value, (str, 字节)): 返回 如果...否则 HAS_NUMPY isinstance(value, numpy.纳维数组): 返回 如果...否则 isinstance(value, 集合.abc.映射): 返回 { _类型转换(k, 设备类型, 数据类型): _类型转换(v, 设备类型, 数据类型) for k, v value.项目() } 如果...否则 isinstance(value, 集合.abc.迭代器): 可迭代的 = (_类型转换(v, 设备类型, 数据类型) for v value) 如果 isinstance(value, (列表, 元组)): 返回 类型(value)(可迭代对象) 否则: 返回 可迭代的 否则: 返回
[文档]def 自定义前向( 前端=, *, 设备类型: str, 输入设备: 可选[数据类型] = , ): "" 为自定义自动微分函数的 `forward` 方法创建一个辅助装饰器。 自动微分函数是 :class:`torch.autograd.Function` 的子类。 更多详情请参阅 :ref:`示例页面`。 参数: device_type(str): 要使用的设备类型。'cuda'、'cpu'、'mtia'、'xpu' 等等。 类型与 :class:`torch.device` 的 `type` 属性相同。 因此,您可以使用 `Tensor.device.type` 获取张量的设备类型。 cast_inputs (:class:`torch.dtype` 或 None, 可选, 默认=None): 如果不是 ``None``, 当在自动类型转换启用的区域中运行 `forward` 时, 将浮点张量转换为目标数据类型(非浮点张量不受影响), 然后以自动类型转换禁用状态执行 `forward`。 如果为 `None`,则 `forward` 的内部操作以当前自动类型转换状态执行。 .. 注意:: 如果装饰的 `forward` 在自动铸造成能区域外被调用, func:`custom_fwd` 是一个空操作,`cast_inputs` 没有作用。 """ 如果 isinstance(设备类型, str): 抛出 值错误( f预期 `device_type` 为 `str` 类型,实际得到:`{类型(设备类型)} ) 如果 fwd : 返回 functools.偏函数( 自定义前向, 设备类型=设备类型, 输入设备=设置输入 ) @functools.包装(前端) def 装饰前向(*参数, **kwargs): 参数[0]._dtype = PyTorch.获取自动类型转换(设备类型) 如果 设置输入 : 参数[0]._fwd_used_autocast = PyTorch.是否启用自动转换(设备类型) 返回 前端(*参数, **kwargs) 否则: 自动上下文 = PyTorch.是否启用自动转换(设备类型) 参数[0]._fwd_used_autocast = 如果 autocast_context: 替换为 自动播(设备类型=设备类型, 启用=False): 返回 前端( *_类型转换(参数, 设备类型, 输入设备), **_类型转换(kwargs, 设备类型, 输入设备), ) 否则: 返回 前端(*参数, **kwargs) 返回 装饰前向
# 自动微分确保传入的梯度与前向输出类型相同。允许在 custom_bwd 上使用单独的 # cast_inputs 参数,如果它不匹配则可能导致错误 # cast_inputs 供给 custom_fwd 使用
[文档]def custom_bwd(bwd=None, *, device_type: str): """创建自定义自动微分函数的向后方法的辅助装饰器。 自动微分函数是 :class:`torch.autograd.Function` 的子类。 确保使用与 ``forward`` 相同的 autocast 状态执行 ``backward``。 查看更多详情,请参阅::ref:`示例页面`. Args: device_type(str): 要使用的设备类型。'cuda'、'cpu'、'mtia'、'xpu'等。 类型与 :class:`torch.device` 的 `type` 属性相同。 因此,您可以使用 `Tensor.device.type` 获取张量的设备类型。 """ 如果 device_type 不是字符串类型: raise ValueError( 期望 `device_type` 为 `str` 类型,实际得到:`{type(device_type)}` ) 如果 bwd 为 None: 返回 functools.partial(custom_bwd, device_type=device_type) @functools.wraps(bwd) def decorate_bwd(*args, **kwargs): with autocast( device_type=device_type, enabled=args[0]._fwd_used_autocast dtype=args[0]._dtype ): return bwd(*args, **kwargs) 返回装饰_bwd

© 版权所有 PyTorch 贡献者。

使用 Sphinx 构建,并使用 Read the Docs 提供的主题。

文档

查看 PyTorch 的全面开发者文档

查看文档

教程

深入了解初学者和高级开发者的教程

查看教程

资源

查找开发资源,获取您的疑问解答

查看资源