网站设计费用多少,刷赞网站推广软件,wordpress 数据库乱码,省级门户网站建设自动混合精度 
torch. amp为混合精度提供了方便的方法#xff0c;其中一些操作使用torch.float32#xff08;浮点#xff09;数据类型#xff0c;而其他操作使用精度较低的浮点数据类型#xff08;lower_precision_fp#xff09;#xff1a;torch.float16(half)或torch.…自动混合精度 
torch. amp为混合精度提供了方便的方法其中一些操作使用torch.float32浮点数据类型而其他操作使用精度较低的浮点数据类型lower_precision_fptorch.float16(half)或torch.bfloat16。一些操作如线性层和卷积在lower_precision_fp中要快得多。其他操作如缩减通常需要float32的动态范围。混合精度试图将每个操作与其适当的数据类型相匹配。 
通常数据类型为torch. float16的“自动混合精度训练”一起使用torch.autocast和torch.cuda.amp.GradScaler。并且torch.autocast和torch.cuda.amp.GradScaler是模块化的如果需要可以单独使用。 
对于CUDA和CPUAPI也单独提供 
torch.autocast(“cuda”args…)等价于torch.cuda.amp.autocast(args…)。 
torch.autocast(“cpu”args…)等价于torch.cpu.amp.autocast(args…)。对于CPU目前仅支持torch.bfloat16的较低精度浮点数据类型。 
自动转换autocast 
torch.autocast(device_type, dtypeNone, enabledTrue, cache_enabledNone) 
参数 device_type (str, required) - 使用’cuda’或’cpu’设备 enabled (bool, optional) - 是否在区域中启用autocasting。默认值True dtype (torch_dtype, optional) - 是否使用torch.float16或torch.bfloat16。 cache_enabled (bool, optional) - 是否启用autocast内部的权重缓存。默认值True 
autocast可以用作上下文管理器或装饰器允许脚本作用区域以混合精度运行。 
在这些区域中数据操作会以autocast选择的特定于该操作的dtype进行运行以提高性能同时保持准确性。 
进入启用autocast的区域时张量可以是任何类型。使用autocast时您不应在模型或输入上调用half()或bfloat16()。 autocast应仅包装网络的前向传递forward包括loss计算。不建议在autocast下进行后向传递。后向操作以与autocast用于相应前向操作的运行类型相同。 
CUDA示例 
# Creates model and optimizer in default precision
model  Net().cuda()
optimizer  optim.SGD(model.parameters(), ...)for input, target in data:optimizer.zero_grad()# Enables autocasting for the forward pass (model  loss)with autocast():output  model(input)loss  loss_fn(output, target)# Exits the context manager before backward()loss.backward()optimizer.step()在启用自动转换的区域中生成的浮点张量可能是float16。返回到禁用自动转换的区域后将它们与不同dtype的浮点张量一起使用可能会导致类型不匹配错误。如果是这样请将自动转换区域中生成的张量转换回float32或其他dtype如果需要。如果来自自动转换区域的张量已经是float32则转换是无操作的并且不会产生额外的开销。 
CUDA示例 
# Creates some tensors in default dtype (here assumed to be float32)
a_float32  torch.rand((8, 8), devicecuda)
b_float32  torch.rand((8, 8), devicecuda)
c_float32  torch.rand((8, 8), devicecuda)
d_float32  torch.rand((8, 8), devicecuda)with autocast():# torch.mm is on autocasts list of ops that should run in float16.# Inputs are float32, but the op runs in float16 and produces float16 output.# No manual casts are required.e_float16  torch.mm(a_float32, b_float32)# Also handles mixed input typesf_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 训练示例: 
# Creates model and optimizer in default precision
model  Net()
optimizer  optim.SGD(model.parameters(), ...)for epoch in epochs:for input, target in data:optimizer.zero_grad()# Runs the forward pass with autocasting.with torch.autocast(device_typecpu, dtypetorch.bfloat16):output  model(input)loss  loss_fn(output, target)loss.backward()optimizer.step()CPU 推理示例: 
# Creates model in default precision
model  Net().eval()with torch.autocast(device_typecpu, dtypetorch.bfloat16):for input in data:# Runs the forward pass with autocasting.output  model(input)CPU 使用jit trace的推理示例: 
class TestModel(nn.Module):def __init__(self, input_size, num_classes):super().__init__()self.fc1  nn.Linear(input_size, num_classes)def forward(self, x):return self.fc1(x)input_size  2
num_classes  2
model  TestModel(input_size, num_classes).eval()# For now, we suggest to disable the Jit Autocast Pass,
# As the issue: https://github.com/pytorch/pytorch/issues/75956
torch._C._jit_set_autocast_mode(False)with torch.cpu.amp.autocast(cache_enabledFalse):model  torch.jit.trace(model, torch.randn(1, input_size))
model  torch.jit.freeze(model)
# Models Run
for _ in range(3):model(torch.randn(1, input_size))autocast(enabledFalse)子区域可以嵌套在启用autocast的区域中。在特定的数据类型中强制运行子区域时局部禁用autocast是有用的。禁用autocast可以明确控制执行类型。在子区域中来自周围区域的输入在使用之前应该被转换为指定的数据类型。 
# 在默认数据类型这里假设为float32中创建一些张量
a_float32  torch.rand((8, 8), devicecuda)
b_float32  torch.rand((8, 8), devicecuda)
c_float32  torch.rand((8, 8), devicecuda)
d_float32  torch.rand((8, 8), devicecuda)with autocast():e_float16  torch.mm(a_float32, b_float32)with autocast(enabledFalse):# 调用e_float16.float()以确保使用float32执行# 这是必需的因为e_float16是在autocast区域中创建的f_float32  torch.mm(c_float32, e_float16.float())# 当重新进入启用autocast的区域时无需手动转换类型。# torch.mm仍然以float16运行并产生float16的输出不受输入类型的影响。g_float16  torch.mm(d_float32, f_float32) 
autocast状态是线程本地的。如果要在新线程中启用它必须在该线程中调用上下文管理器或装饰器。 
torch.cuda.amp.autocast(enabledTrue, dtypetorch.float16, cache_enabledTrue) torch.cuda.amp.autocast(args…)等同于torch.autocast(“cuda”, args…) 
*torch.cuda.amp.custom_fwd(fwdNone, , cast_inputsNone) 用于自定义自动求导函数torch.autograd.Function的子类的forward方法的辅助装饰器。 
参数 cast_inputs (torch.dtype或None, optional, defaultNone) - 如果不为None在autocast-enabled区域中运行forward时将传入的浮点数CUDA张量转换为目标数据类型非浮点数张量不受影响然后以禁用autocast的方式执行forward。如果为None则forward的内部操作将根据当前的autocast状态执行 
梯度缩放Gradient Scaling 
如果某个操作的前向传递具有float16输入则该操作的反向传递将产生float16梯度。具有较小幅度的梯度值可能无法表示为float16。这些值将被置零“underflow”因此相应参数的更新将丢失。 
为了防止underflow梯度缩放通过将网络的损失乘以一个缩放因子并在缩放后的损失上进行反向传递来进行。通过网络向后传播的梯度也会按照相同的因子进行缩放。换句话说梯度值具有较大的幅度因此它们不会被置零。 
每个参数的梯度.grad属性在优化器更新参数之前应进行还原以确保缩放因子不会干扰学习率的设置。 
torch.cuda.amp.GradScaler(init_scale65536.0, growth_factor2.0, backoff_factor0.5, growth_interval2000, enabledTrue) 
get_backoff_factor() 返回一个包含缩放回退因子的Python浮点数。 
get_growth_factor() 返回一个包含缩放增长因子的Python浮点数。 
get_growth_interval() 返回一个包含增长间隔的Python整数。 
get_scale() 返回一个包含当前缩放因子的Python浮点数如果禁用缩放则返回1.0。 
**警告**get_scale()会产生CPU-GPU同步。 
is_enabled() 返回一个布尔值指示此实例是否已启用。 
load_state_dict(state_dict) 加载缩放器状态。如果此实例已禁用则load_state_dict()不执行任何操作。 
参数 state_dict (dict) – 缩放器状态。应为调用state_dict()返回的对象。 
scale(outputs) 将张量或张量列表按比例因子进行缩放。 
返回缩放后的输出。如果未启用GradScaler的实例则返回未修改的输出。 
参数 outputs (Tensor或Tensor的可迭代对象) – 要进行缩放的输出。 
set_backoff_factor(new_factor) 参数 new_factor (float) – 用作新缩放回退因子的值。 
set_growth_factor(new_factor) 参数 new_factor (float) – 用作新缩放增长因子的值。 
set_growth_interval(new_interval) 参数 new_interval (int) – 用作新增长间隔的值。 
state_dict() 以字典形式返回缩放器的状态。它包含五个条目 
“scale” - 一个包含当前缩放的Python浮点数 
“growth_factor” - 一个包含当前增长因子的Python浮点数 
“backoff_factor” - 一个包含当前回退因子的Python浮点数 
“growth_interval” - 一个包含当前增长间隔的Python整数 
“_growth_tracker” - 一个包含最近连续未跳过步骤的数量的Python整数。 
如果此实例未启用则返回一个空字典。 
注意:如果要在特定迭代之后检查点缩放器的状态则应在update()之后调用state_dict()。 
step(optimizer, *args, **kwargs) 
step()执行以下两个操作 
1在内部调用unscale_(optimizer)除非在迭代中之前显式调用了unscale_()。在unscale_()的一部分会检查梯度是否包含inf/NaN。 
2如果未发现inf/NaN梯度则使用未缩放的梯度调用optimizer.step()。否则将跳过optimizer.step()以避免破坏参数。 
*args和**kwargs会被传递给optimizer.step()。 
返回optimizer.step(*args, **kwargs)的返回值。 
参数 optimizer (torch.optim.Optimizer) – 应用梯度的优化器。 
args –任何参数。 
kwargs – 任何关键字参数。 
警告 
目前不支持闭包使用。 
unscale_(optimizer) 将优化器的梯度张量通过缩放因子进行除法“取消缩放”。 
unscale_()是可选的适用于在反向传播和步骤step()之间修改或检查梯度的情况。如果未显式调用unscale_()则梯度将在步骤step()期间自动取消缩放。 
简单示例使用unscale_()来启用未缩放梯度的剪裁 
… scaler.scale(loss).backward() scaler.unscale_(optimizer) torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm) scaler.step(optimizer) scaler.update() 参数 optimizer (torch.optim.Optimizer) – 拥有待取消缩放梯度的优化器。 
注意 
unscale_()不会产生CPU-GPU同步。 
警告 
每次调用unscale_()时应对于每个优化器在每个step()调用中仅调用一次并且只在为该优化器的分配参数累积了所有梯度之后才调用。在每个step()之间对于给定优化器连续调用unscale_()两次会触发RuntimeError。 
警告 
unscale_()可能会以不可恢复的方式取消缩放稀疏梯度替换.grad属性。 
update(new_scaleNone)[SOURCE] 更新缩放因子。 
如果跳过了任何优化器步骤则通过backoff_factor乘以缩放因子来减小它。如果连续出现growth_interval个未跳过的迭代则通过growth_factor乘以缩放因子来增加它。 
传递new_scale会手动设置新的缩放值。new_scale不会直接使用而是用于填充GradScaler的内部缩放张量。因此如果new_scale是一个张量对该张量的原地更改将不会进一步影响GradScaler内部使用的缩放。 
参数 new_scalefloat或torch.cuda.FloatTensor可选默认为None – 新的缩放因子。 
警告 
update()应仅在迭代结束时调用在该迭代中为所有使用的优化器调用了scaler.step(optimizer)。 
Autocast Op 相关参考 
Autocast Op 资格 
无论是否启用自动转换在float64或非float类型中运行的操作不被autocast转换操作它们都将在原本类型中运行。 autocast只会对out-of-place 操作和张量方法产生影响。在启用autocast的区域中允许显式提供out…tensor的in-place操作以及调用但他们不会通过autocast。例如在启用自动转换的区域中a. addmmbc可以自动转换但a.addmm_bcoutd不能。为了获得最佳性能和稳定性请在启用autocast的区域中优先使用 out-of-place 操作。 显式调用dtype…的操作不符合autocast使用资格并且将生成dtype参数的输出。 
CUDA Op 特定行为 
下面的列表描述了在启用自动转换的区域中具备资格的操作的行为。这些操作始终经过自动转换无论它们作为 torch.nn.Module 的一部分被调用作为函数被调用还是作为 torch.Tensor 方法被调用。如果函数在多个命名空间中公开无论命名空间如何它们都经过自动转换。 
下面未列出的操作不经过自动转换。它们根据其输入定义的类型运行。然而如果它们是自动转换的操作的下游自动转换仍然可能更改未列出的操作运行的类型。 
如果一个操作未列出我们假设它在 float16 中是数值稳定的。如果您认为未列出的操作在 float16 中数值不稳定请提出问题。 
可以自动转换为 float16 的 CUDA Ops 
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 Ops 
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 Ops 
这些操作对于稳定性不需要特定的数据类型但需要多个输入并要求输入的数据类型匹配。如果所有输入都是 float16则该操作在 float16 中运行。如果输入中有任何一个是 float32则自动转换将所有输入转换为 float32并在 float32 中运行该操作。 
addcdiv、addcmul、atan2、bilinear、cross、dot、grid_sample、index_put、scatter_add、tensordot 
这里未列出的一些操作例如add 等二元操作在没有自动转换的干预下本身就可以提升输入。如果输入是 bfloat16 和 float32 的混合这些操作将在 float32 中运行并产生 float32 输出无论是否启用自动转换。 
优先使用 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 Op 特定行为 
下面的列表描述了在启用自动转换的区域中具备资格的操作的行为。这些操作始终经过自动转换无论它们作为 torch.nn.Module 的一部分被调用作为函数被调用还是作为 torch.Tensor 方法被调用。如果函数在多个命名空间中公开无论命名空间如何它们都经过自动转换。 
下面未列出的操作不经过自动转换。它们根据其输入定义的类型运行。然而如果它们是自动转换的操作的下游自动转换仍然可能更改未列出的操作运行的类型。 
如果一个操作未列出我们假设它在 bfloat16 中是数值稳定的。如果您认为未列出的操作在 bfloat16 中数值不稳定请提出问题。 
可以自动转换为 bfloat16 的 CPU Ops 
conv1d、conv2d、conv3d、bmm、mm、baddbmm、addmm、addbmm、linear、matmul、_convolution 
可以自动转换为 float32 的 CPU 
Ops 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 Ops 
这些操作不需要特定的数据类型来保持稳定性但需要多个输入并要求输入的数据类型匹配。如果所有输入都是 bfloat16则该操作在 bfloat16 中运行。如果任何一个输入是 float32则自动转换将所有输入转换为 float32并在 float32 中运行该操作。 
cat、stack、index_copy 
这里未列出的一些操作例如add 等二元操作在没有自动转换的干预下本身就可以提升输入。如果输入是 bfloat16 和 float32 的混合这些操作将在 float32 中运行并产生 float32 输出无论是否启用自动转换。 
补充关于inplace 和 out of inplace的理解理解inplace就明白了 
inplaceTrue指的是进行原地操作选择进行原地覆盖运算。 比如 x1则是对原值x进行操作然后将得到的结果又直接覆盖该值。yx5,xy则不是对x的原地操作。 inplaceTrue操作的好处就是可以节省运算内存不用多储存其他无关变量。 注意当使用 inplaceTrue后对于上层网络传递下来的tensor会直接进行修改改变输入数据具体意思如下面例子所示 
import torch
import torch.nn as nnrelu  nn.ReLU(inplaceTrue)
input  torch.randn(7)print(输入数据,input)output  relu(input)
print(ReLU输出, output)print(ReLU处理后输入数据)
print(input)torch.autograd.grad函数是PyTorch中用于计算梯度的函数之一。它用于计算一个或多个标量函数相对于一组变量的梯度。 
函数签名如下 
mathematicaCopy code
torch.autograd.grad(outputs, inputs, grad_outputsNone, retain_graphNone, create_graphFalse, only_inputsTrue, allow_unusedFalse)参数说明 
outputs包含需要计算梯度的标量函数的张量或张量列表。inputs需要计算梯度的变量的张量或张量列表。grad_outputs与outputs具有相同形状的张量或张量列表用于指定在计算梯度时的外部梯度。默认为None表示使用单位梯度即1。retain_graph布尔值指定在计算完梯度后是否保留计算图以进行后续计算。默认为None表示自动判断是否需要保留计算图。create_graph布尔值指定是否创建一个新的计算图用于计算高阶导数。默认为False。only_inputs布尔值指定是否只计算输入的梯度。默认为True表示仅计算输入的梯度。allow_unused布尔值指定是否允许在计算梯度时存在未使用的输入。默认为False表示不允许存在未使用的输入。 
函数返回一个与inputs具有相同形状的张量或张量列表表示相对于inputs的梯度。如果某个输入不需要梯度对应位置的梯度将为None。 
以下是一个示例用法 
pythonCopy codeimport torchx  torch.tensor([2.0], requires_gradTrue)
y  x ** 2
grads  torch.autograd.grad(y, x)print(grads)  # 输出 [tensor([4.])]上述示例中我们计算了y  x ** 2相对于x的梯度并通过torch.autograd.grad函数获取了结果。在这个例子中grads的值为4.0表示y相对于x的梯度为4.0。