文章目录
torch
torch.nn
torch.nn.functional
torch.Tensor
张量属性
张量视图
[自动混合精度包 - torch.amp](#自动混合精度包 - torch.amp)
自动类型转换
梯度缩放
自动转换操作符参考
操作符适用性
[CUDA 操作特定行为](#CUDA 操作特定行为)
[可自动转换为 `float16` 的 CUDA 运算](#可自动转换为 float16
的 CUDA 运算)
[可自动转换为 `float32` 的 CUDA 运算](#可自动转换为 float32
的 CUDA 运算)
[提升至最宽输入类型的 CUDA 操作](#提升至最宽输入类型的 CUDA 操作)
[优先使用 `binary_cross_entropy_with_logits` 而非 `binary_cross_entropy`](#优先使用 binary_cross_entropy_with_logits
而非 binary_cross_entropy
)
[XPU 算子特定行为(实验性功能)](#XPU 算子特定行为(实验性功能))
[可自动转换为 `float16` 的 XPU 运算](#可自动转换为 float16
的 XPU 运算)
可自动转换为`float32`的XPU运算
[提升至最宽输入类型的 XPU 运算](#提升至最宽输入类型的 XPU 运算)
[CPU 操作特定行为](#CPU 操作特定行为)
[可自动转换为 `bfloat16` 的 CPU 运算操作](#可自动转换为 bfloat16
的 CPU 运算操作)
[可自动转换为 `float32` 的 CPU 运算](#可自动转换为 float32
的 CPU 运算)
提升至最宽输入类型的CPU运算
torch
https://docs.pytorch.org/docs/stable/torch.html
torch 包提供了多维张量的数据结构,并定义了针对这些张量的数学运算。此外,它还包含许多实用工具,可实现张量及任意类型的高效序列化,以及其他实用功能。
该包还配有 CUDA 版本,支持在计算能力 >= 3.0 的 NVIDIA GPU 上运行张量计算。
张量
创建操作
随机采样创建操作列在随机采样 下,包括:torch.rand()
、torch.rand_like()
、torch.randn()
、torch.randn_like()
、torch.randint()
、torch.randint_like()
、torch.randperm()
。
你也可以使用torch.empty()
结合原地随机采样 方法来创建torch.Tensor
,其值从更广泛的分布中采样。
索引、切片、连接与变异操作
加速器
在 PyTorch 代码库中,我们将"加速器"定义为与 CPU 协同工作以加速计算的 torch.device
。这些设备采用异步执行方案,使用 torch.Stream
和 torch.Event
作为主要的同步机制。我们假设在给定主机上一次只能使用一个这样的加速器,这使得我们可以将当前加速器作为默认设备,用于固定内存、流设备类型、FSDP 等相关概念。
目前支持的加速器设备包括(无特定顺序):"CUDA" 、"MTIA" 、"XPU" 、"MPS" 、"HPU"以及 PrivateUse1(许多设备不在 PyTorch 代码库本身中)。
PyTorch 生态系统中的许多工具使用 fork 创建子进程(例如数据加载或操作内并行),因此应尽可能延迟任何会阻止后续 fork 的操作。这一点尤为重要,因为大多数加速器的初始化都会产生这种影响。实际应用中需注意,默认情况下检查 torch.accelerator.current_accelerator()
是编译时检查,因此始终是 fork 安全的。相反,向此函数传递 check_available=True
标志或调用 torch.accelerator.is_available()
通常会阻止后续 fork。
某些后端提供实验性的可选选项,使运行时可用性检查成为 fork 安全的。例如,使用 CUDA 设备时可以使用 PYTORCH_NVML_BASED_CUDA_CHECK=1
。
Stream
按先进先出(FIFO)顺序异步执行相应任务的有序队列。
Event
查询和记录流状态,以识别或控制跨流的依赖关系并测量时间。
生成器
随机采样
torch.default_generator 返回默认的CPU torch.Generator
原地随机采样
张量上还定义了一些原地随机采样函数。点击以下链接查看它们的文档:
准随机采样
序列化
并行计算
局部禁用梯度计算
上下文管理器 torch.no_grad()
、torch.enable_grad()
和 torch.set_grad_enabled()
可用于在局部范围内禁用或启用梯度计算。具体用法详见局部禁用梯度计算 文档。这些上下文管理器是线程局部的,因此如果通过threading
模块等将工作发送到其他线程,它们将不会生效。
示例:
python
复制代码
>>> x = torch.zeros(1, requires_grad=True)
>>> with torch.no_grad():
... y = x * 2
>>> y.requires_grad
False
>>> is_train = False
>>> with torch.set_grad_enabled(is_train):
... y = x * 2
>>> y.requires_grad
False
>>> torch.set_grad_enabled(True) # 也可以作为函数使用
>>> y = x * 2
>>> y.requires_grad
True
>>> torch.set_grad_enabled(False)
>>> y = x * 2
>>> y.requires_grad
False
数学运算
常量
inf
浮点正无穷大。math.inf
的别名。
nan
浮点"非数字"值。该值不是一个合法的数字。math.nan
的别名。
逐点运算
归约操作
比较运算
allclose
检查 input
和 other
是否满足条件:
argsort
返回按值升序排列张量沿指定维度的索引。
eq
逐元素计算相等性
equal
如果两个张量大小和元素相同返回 True
,否则返回 False
。
ge
逐元素计算 input≥other\text{input} \geq \text{other}input≥other。
greater_equal
torch.ge()
的别名。
gt
逐元素计算 input>other\text{input} \text{other}input>other。
greater
torch.gt()
的别名。
isclose
返回一个新张量,其布尔元素表示 input
的每个元素是否与 other
的对应元素"接近"。
isfinite
返回一个新张量,其布尔元素表示每个元素是否为有限值。
isin
测试 elements
的每个元素是否在 test_elements
中。
isinf
测试 input
的每个元素是否为无穷大(正无穷或负无穷)。
isposinf
测试 input
的每个元素是否为正无穷。
isneginf
测试 input
的每个元素是否为负无穷。
isnan
返回一个新张量,其布尔元素表示 input
的每个元素是否为 NaN。
isreal
返回一个新张量,其布尔元素表示 input
的每个元素是否为实数值。
kthvalue
返回一个命名元组 (values, indices)
,其中 values
是 input
张量在给定维度 dim
上每行的第 k
个最小元素。
le
逐元素计算 input≤other\text{input} \leq \text{other}input≤other。
less_equal
torch.le()
的别名。
lt
逐元素计算 input<other\text{input} < \text{other}input<other。
less
torch.lt()
的别名。
maximum
计算 input
和 other
的逐元素最大值。
minimum
计算 input
和 other
的逐元素最小值。
fmax
计算 input
和 other
的逐元素最大值。
fmin
计算 input
和 other
的逐元素最小值。
ne
逐元素计算 input≠other\text{input} \neq \text{other}input=other。
not_equal
torch.ne()
的别名。
sort
按值升序排列 input
张量沿指定维度的元素。
topk
返回 input
张量沿给定维度的前 k
个最大元素。
msort
按值升序排列 input
张量沿其第一维度的元素。
频谱操作
其他操作
BLAS 和 LAPACK 运算
遍历操作
警告:此API处于测试阶段,未来可能会有变更。
不支持前向模式自动微分。
实用工具
符号数字
python
复制代码
class torch.SymInt(node)[source]
类似于整型(包括魔术方法),但会重定向所有对封装节点的操作。这尤其用于在符号化形状工作流中记录符号化操作。
python
复制代码
as_integer_ratio()
将该整数表示为精确的整数比例
返回类型 tuple[SymInt', int]
python
复制代码
class torch.SymFloat(node)
像一个浮点数(包括魔术方法),但会重定向所有对包装节点的操作。这尤其用于在符号化形状工作流中象征性地记录操作。
python
复制代码
as_integer_ratio()
将这个浮点数表示为精确的整数比例
返回类型:tuple[int, int]
python
复制代码
conjugate()
返回该浮点数的复共轭值。
返回类型:SymFloat
python
复制代码
hex()
返回浮点数的十六进制表示形式。
返回类型 str
python
复制代码
is_integer()
如果浮点数是整数,则返回 True。
python
复制代码
class torch.SymBool(node)
类似于布尔类型(包括魔术方法),但会重定向所有对包装节点的操作。这尤其用于在符号化形状工作流中符号化记录操作。
与常规布尔类型不同,常规布尔运算符会强制生成额外的保护条件,而不是进行符号化求值。应改用位运算符来处理这种情况。
导出路径
警告:此功能为原型阶段,未来可能包含不兼容的变更。
export generated/exportdb/index
控制流
警告:此功能为原型阶段,未来可能存在破坏性变更。
cond
根据条件选择执行 true_fn 或 false_fn
优化方法
compile
使用TorchDynamo和指定后端优化给定模型/函数
torch.compile文档
操作符标签
python
复制代码
class torch.Tag
成员:
core
data_dependent_output
dynamic_output_shape
flexible_layout
generated
inplace_view
maybe_aliasing_or_mutating
needs_fixed_stride_order
nondeterministic_bitwise
nondeterministic_seeded
pointwise
pt2_compliant_tag
view_copy
torch.nn
https://docs.pytorch.org/docs/stable/nn.html
以下是构建图模型的基本组件:
torch.nn
容器模块
模块全局钩子
卷积层
池化层
填充层
非线性激活函数(加权求和与非线性变换)
非线性激活函数(其他)
归一化层
循环神经网络层
线性层
Dropout 层
稀疏层
距离函数
损失函数
视觉层
通道混洗层
数据并行层(多GPU,分布式)
实用工具
来自 torch.nn.utils
模块的实用函数:
参数梯度裁剪工具
模块参数扁平化与反扁平化工具
模块与批归一化融合工具
模块参数内存格式转换工具
权重归一化应用与移除工具
模块参数初始化工具
| skip_init
| 给定模块类对象和参数,实例化模块但不初始化参数/缓冲区 |
模块参数剪枝工具类与函数
使用torch.nn.utils.parameterize.register_parametrization()
新参数化功能实现的参数化
为现有模块上的张量参数化的实用函数
注意:这些函数可用于通过特定函数将给定参数或缓冲区从输入空间映射到参数化空间。它们不是将对象转换为参数的参数化。有关如何实现自定义参数化的更多信息,请参阅参数化教程 。
以无状态方式调用给定模块的实用函数
| stateless.functional_call
| 通过用提供的参数和缓冲区替换模块参数和缓冲区来执行功能调用 |
其他模块中的实用函数
量化函数
量化是指以低于浮点精度的位宽执行计算和存储张量的技术。PyTorch 同时支持逐张量和逐通道的非对称线性量化。要了解更多关于如何在 PyTorch 中使用量化函数的信息,请参阅量化 文档。
惰性模块初始化
别名
以下是 torch.nn
中对应模块的别名:
torch.nn.functional
卷积函数
池化函数
注意力机制
torch.nn.attention.bias
模块包含专为 scaled_dot_product_attention 设计的注意力偏置项。
非线性激活函数
threshold
对输入张量的每个元素应用阈值处理
threshold_
threshold()
的原位操作版本
relu
逐元素应用修正线性单元函数
relu_
relu()
的原位操作版本
hardtanh
逐元素应用 HardTanh 函数
hardtanh_
hardtanh()
的原位操作版本
hardswish
逐元素应用 hardswish 函数
relu6
逐元素应用 ReLU6(x)=min(max(0,x),6)\text{ReLU6}(x) = \min(\max(0,x), 6)ReLU6(x)=min(max(0,x),6) 函数
elu
逐元素应用指数线性单元(ELU)函数
elu_
elu()
的原位操作版本
selu
逐元素应用 SELU(x)=scale∗(max(0,x)+min(0,α∗(exp(x)−1)))\text{SELU}(x) = scale * (\max(0,x) + \min(0, \alpha * (\exp(x) - 1)))SELU(x)=scale∗(max(0,x)+min(0,α∗(exp(x)−1))) 函数,其中 α=1.6732632423543772848170429916717\alpha=1.6732632423543772848170429916717α=1.6732632423543772848170429916717,scale=1.0507009873554804934193349852946scale=1.0507009873554804934193349852946scale=1.0507009873554804934193349852946
celu
逐元素应用 CELU(x)=max(0,x)+min(0,α∗(exp(x/α)−1))\text{CELU}(x) = \max(0,x) + \min(0, \alpha * (\exp(x/\alpha) - 1))CELU(x)=max(0,x)+min(0,α∗(exp(x/α)−1)) 函数
leaky_relu
逐元素应用 LeakyReLU(x)=max(0,x)+negative_slope∗min(0,x)\text{LeakyReLU}(x) = \max(0, x) + \text{negative_slope} * \min(0, x)LeakyReLU(x)=max(0,x)+negative_slope∗min(0,x) 函数
leaky_relu_
leaky_relu()
的原位操作版本
prelu
逐元素应用 PReLU(x)=max(0,x)+weight∗min(0,x)\text{PReLU}(x) = \max(0,x) + \text{weight} * \min(0,x)PReLU(x)=max(0,x)+weight∗min(0,x) 函数,其中 weight 是可学习参数
rrelu
随机泄漏 ReLU
rrelu_
rrelu()
的原位操作版本
glu
门控线性单元
gelu
当 approximate 参数为 'none' 时,逐元素应用 GELU(x)=x∗Φ(x)\text{GELU}(x) = x * \Phi(x)GELU(x)=x∗Φ(x) 函数
logsigmoid
逐元素应用 LogSigmoid(xi)=log(11+exp(−xi))\text{LogSigmoid}(x_i) = \log \left(\frac{1}{1 + \exp(-x_i)}\right)LogSigmoid(xi)=log(1+exp(−xi)1) 函数
hardshrink
逐元素应用硬收缩函数
tanhshrink
逐元素应用 Tanhshrink(x)=x−Tanh(x)\text{Tanhshrink}(x) = x - \text{Tanh}(x)Tanhshrink(x)=x−Tanh(x) 函数
softsign
逐元素应用 SoftSign(x)=x1+∣x∣\text{SoftSign}(x) = \frac{x}{1 +
softplus
逐元素应用 Softplus(x)=1β∗log(1+exp(β∗x))\text{Softplus}(x) = \frac{1}{\beta} * \log(1 + \exp(\beta * x))Softplus(x)=β1∗log(1+exp(β∗x)) 函数
softmin
应用 softmin 函数
softmax
应用 softmax 函数
softshrink
逐元素应用软收缩函数
gumbel_softmax
从 Gumbel-Softmax 分布(链接1 链接2 )采样并可选离散化
log_softmax
应用 softmax 后接对数运算
tanh
逐元素应用 Tanh(x)=tanh(x)=exp(x)−exp(−x)exp(x)+exp(−x)\text{Tanh}(极x) = \tanh(x) = \frac{\exp(x) - \exp(-x)}{\exp(x) + \exp(-x)}Tanh(x)=tanh(x)=exp(x)+exp(−x)exp(x)−exp(−x) 函数
sigmoid
逐元素应用 Sigmoid(x)=11+exp(−x)\text{Sigmoid}(x) = \frac{1}{1 + \exp(-x)}Sigmoid(x)=1+exp(−x)1 函数
hardsigmoid
逐元素应用 Hardsigmoid 函数
silu
逐元素应用 Sigmoid 线性单元(SiLU)函数
mish
逐元素应用 Mish 函数
batch_norm
对批量数据中的每个通道应用批量归一化
group_norm
对最后若干维度应用组归一化
instance_norm
对批量中每个数据样本的每个通道独立应用实例归一化
layer_norm
对最后若干维度应用层归一化
local_response_norm
对输入信号应用局部响应归一化
rms_norm
应用均方根层归一化
normalize
对指定维度执行 LpL_pLp 归一化
线性函数
linear
对输入数据应用线性变换:y=xAT+by = xA^T + by=xAT+b
bilinear
对输入数据应用双线性变换:y=x1TAx2+by = x_1^T A x_2 + by=x1TAx2+b
Dropout 函数
稀疏函数
embedding
生成一个简单的查找表,用于在固定字典和尺寸中查找嵌入向量。
embedding_bag
计算嵌入向量包的和、平均值或最大值。
one_hot
接收形状为()
的LongTensor索引值,返回形状为(, num_classes)
的张量,该张量除最后一维索引与输入张量对应值匹配的位置为1外,其余位置均为0。
距离函数
损失函数
视觉函数
pixel_shuffle
将形状为 ( ∗ , C × r 2 , H , W ) (∗,C×r^2,H,W) (∗,C×r2,H,W)的张量元素重新排列为形状 ( ∗ , C , H × r , W × r ) (∗,C, H × r, W × r) (∗,C,H×r,W×r)的张量,其中r为upscale_factor
。
pixel_unshuffle
通过将形状为 ( ∗ , C , H × r , W × r ) (∗,C, H × r, W × r) (∗,C,H×r,W×r)的张量元素重新排列为形状 ( ∗ , C × r 2 , H , W ) (∗,C×r^2,H,W) (∗,C×r2,H,W)的张量,来逆转PixelShuffle
操作,其中r为downscale_factor
。
pad
对张量进行填充。
interpolate
对输入进行下采样/上采样。
upsample
对输入进行上采样。
upsample_nearest
使用最近邻像素值对输入进行上采样。
upsample_bilinear
使用双线性上采样对输入进行上采样。
grid_sample
计算网格采样。
affine_grid
给定一批仿射矩阵theta
,生成2D或3D流场(采样网格)。
DataParallel 功能(多GPU,分布式)
data_parallel
torch.nn.parallel.data_parallel
在指定设备ID列表(device_ids)中的多个GPU上并行评估模块(input)。
torch.Tensor
torch.Tensor
是一个包含单一数据类型元素的多维矩阵。
数据类型
Torch 定义了以下数据类型的张量:
数据类型
dtype
32位浮点数
torch.float32
或 torch.float
64位浮点数
torch.float64
或 torch.double
16位浮点数 [1
torch.float16
或 torch.half
16位浮点数 [2
torch.bfloat16
32位复数
torch.complex32
或 torch.chalf
64位复数
torch.complex64
或 torch.cfloat
128位复数
torch.complex128
或 torch.cdouble
8位整数(无符号)
torch.uint8
16位整数(无符号)
torch.uint16
(有限支持)[4
32位整数(无符号)
torch.uint32
(有限支持)[4
64位整数(无符号)
torch.uint64
(有限支持)[4
8位整数(有符号)
torch.int8
16位整数(有符号)
torch.int16
或 torch.short
32位整数(有符号)
torch.int32
或 torch.int
64位整数(有符号)
torch.int64
或 torch.long
布尔值
torch.bool
量化8位整数(无符号)
torch.quint8
量化8位整数(有符号)
torch.qint8
量化32位整数(有符号)
torch.qint32
量化4位整数(无符号)[3
torch.quint4x2
8位浮点数,e4m3 [5
torch.float8_e4m3fn
(有限支持)
8位浮点数,e5m2 [5
torch.float8_e5m2
(有限支持)
1
有时称为 binary16:使用1位符号、5位指数和10位尾数。在精度比范围更重要时很有用。
\[2
有时称为 Brain Floating Point:使用1位符号、8位指数和7位尾数。在范围更重要时很有用,因为它与 `float32` 具有相同数量的指数位。
\[3
量化4位整数存储为8位有符号整数。目前仅在 EmbeddingBag 操作符中支持。
4(\[1 ,\[2 ,\[3 )
除 `uint8` 外的无符号类型目前计划仅在 eager 模式下提供有限支持(它们主要用于辅助 torch.compile 的使用);如果需要 eager 支持且不需要额外的范围,建议使用其有符号变体。详情请参阅 。
5(\[1 ,\[2 )
`torch.float8_e4m3fn` 和 `torch.float8_e5m2` 实现了来自 的8位浮点数规范。操作支持非常有限。
为了向后兼容,我们支持以下这些数据类型的替代类名:
| 数据类型 | CPU 张量 | GPU 张量 |
|------------|------------------------|-----------------------------|
| 32位浮点数 | `torch.FloatTensor` | `torch.cuda.FloatTensor` |
| 64位浮点数 | `torch.DoubleTensor` | `torch.cuda.DoubleTensor` |
| 16位浮点数 | `torch.HalfTensor` | `torch.cuda.HalfTensor` |
| 16位浮点数 | `torch.BFloat16Tensor` | `torch.cuda.BFloat16Tensor` |
| 8位整数(无符号) | `torch.ByteTensor` | `torch.cuda.ByteTensor` |
| 8位整数(有符号) | `torch.CharTensor` | `torch.cuda.CharTensor` |
| 16位整数(有符号) | `torch.ShortTensor` | `torch.cuda.ShortTensor` |
| 32位整数(有符号) | `torch.IntTensor` | `torch.cuda.IntTensor` |
| 64位整数(有符号) | `torch.LongTensor` | `torch.cuda.LongTensor` |
| 布尔值 | `torch.BoolTensor` | `torch.cuda.BoolTensor` |
然而,为了构造张量,我们建议使用工厂函数如 [`torch.empty()`](https://docs.pytorch.org/docs/stable/generated/torch.empty.html#torch.empty "torch.empty") 并指定 `dtype` 参数。[`torch.Tensor`](https://pytorch.org/docs/stable/data.html#torch.Tensor "torch.Tensor") 构造函数是默认张量类型(`torch.FloatTensor`)的别名。
*** ** * ** ***
### 初始化与基础操作
可以通过 Python 的 `list` 或序列使用 [`torch.tensor()`](https://docs.pytorch.org/docs/stable/generated/torch.tensor.html#torch.tensor "torch.tensor") 构造函数来构建张量:
```python
>>> torch.tensor([[1., -1.], [1., -1.]])
tensor([[1.0000, -1.0000], [1.0000, -1.0000]])
>>> torch.tensor(np.array([[1, 2, 3], [4, 5, 6]]))
tensor([[1, 2, 3], [4, 5, 6]])
```
*** ** * ** ***
警告:[`torch.tensor()`](https://docs.pytorch.org/docs/stable/generated/torch.tensor.html#torch.tensor "torch.tensor") 总是会复制 `data`。如果你已经有一个 Tensor `data` 并且只想修改它的 `requires_grad` 标志,请使用 [`requires_grad_()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.requires_grad_.html#torch.Tensor.requires_grad_ "torch.Tensor.requires_grad_") 或 [`detach()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.detach.html#torch.Tensor.detach "torch.Tensor.detach") 来避免复制操作。
如果你有一个 numpy 数组并且希望避免复制,请使用 [`torch.as_tensor()`](https://docs.pytorch.org/docs/stable/generated/torch.as_tensor.html#torch.as_tensor "torch.as_tensor")。
可以通过向构造函数或张量创建操作传递 `torch.dtype` 和/或 [`torch.device`](tensor_attributes.html#torch.device "torch.device") 来构造特定数据类型的张量:
```python
>>> torch.zeros([2, 4], dtype=torch.int32)
tensor([[0, 0, 0, 0], [0, 0, 0, 0]], dtype=torch.int32)
>>> cuda0 = torch.device('cuda:0')
>>> torch.ones([2, 4], dtype=torch.float64, device=cuda0)
tensor([[1.0000, 1.0000, 1.0000, 1.0000], [1.0000, 1.0000, 1.0000, 1.0000]], dtype=torch.float64, device='cuda:0')
```
*** ** * ** ***
有关构建张量的更多信息,请参阅[创建操作](torch.html#tensor-creation-ops)。
可以使用Python的索引和切片符号来访问和修改张量的内容:
```python
>>> x = torch.tensor([[1, 2, 3], [4, 5, 6]])
>>> print(x[1][2])
tensor(6)
>>> x[0][1] = 8
>>> print(x)
tensor([[1, 8, 3], [4, 5, 6]])
```
*** ** * ** ***
使用 [`torch.Tensor.item()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.item.html#torch.Tensor.item "torch.Tensor.item") 从包含单个值的张量中获取 Python 数值:
```python
>>> x = torch.tensor([[1]])
>>> x
tensor([[1]])
>>> x.item()
1
>>> x = torch.tensor(2.5)
>>> x
tensor(2.5000)
>>> x.item()
2.5
```
*** ** * ** ***
有关索引的更多信息,请参阅[索引、切片、连接和变异操作](torch.html#indexing-slicing-joining)
可以通过设置`requires_grad=True`来创建张量,这样[`torch.autograd`](autograd.html#module-torch.autograd "torch.autograd")会记录对其的操作以实现自动微分。
*** ** * ** ***
```python
>>> x = torch.tensor([[1., -1.], [1., 1.]], requires_grad=True)
>>> out = x.pow(2).sum()
>>> out.backward()
>>> x.grad
tensor([[2.0000, -2.0000], [2.0000, 2.0000]])
```
*** ** * ** ***
每个张量都有一个关联的 `torch.Storage`,用于存储其数据。
张量类还提供了存储的多维[跨步视图](https://en.wikipedia.org/wiki/Stride_of_an_array),并定义了基于它的数值运算。
注意:有关张量视图的更多信息,请参阅[张量视图](tensor_view.html#tensor-view-doc)。
注意:关于 [`torch.Tensor`](https://pytorch.org/docs/stable/data.html#torch.Tensor "torch.Tensor") 的 `torch.dtype`、[`torch.device`](tensor_attributes.html#torch.device "torch.device") 和 [`torch.layout`](tensor_attributes.html#torch.layout "torch.layout") 属性的更多信息,请参阅[张量属性](tensor_attributes.html#tensor-attributes-doc)。
注意:会改变张量的方法以下划线后缀标记。例如,`torch.FloatTensor.abs_()` 会就地计算绝对值并返回修改后的张量,而 `torch.FloatTensor.abs()` 则会在新张量中计算结果。
注意:要更改现有张量的 [`torch.device`](tensor_attributes.html#torch.device "torch.device") 和/或 `torch.dtype`,可以考虑使用张量的 [`to()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.to.html#torch.Tensor.to "torch.Tensor.to") 方法。
警告:当前 [`torch.Tensor`](https://pytorch.org/docs/stable/data.html#torch.Tensor "torch.Tensor") 的实现引入了内存开销,因此在处理大量小张量的应用中可能导致意外的高内存使用。如果遇到这种情况,建议使用单个大型结构。
*** ** * ** ***
### Tensor 类参考
*** ** * ** ***
```python
class torch.Tensor
```
*** ** * ** ***
根据不同的使用场景,创建张量主要有以下几种方式:
* 若要从现有数据创建张量,请使用 [`torch.tensor()`](https://docs.pytorch.org/docs/stable/generated/torch.tensor.html#torch.tensor "torch.tensor")。
* 若要创建指定大小的张量,请使用 `torch.*` 张量创建操作(参见[创建操作](torch.html#tensor-creation-ops))。
* 若要创建与另一个张量大小相同(且类型相似)的张量,请使用 `torch.*_like` 张量创建操作(参见[创建操作](torch.html#tensor-creation-ops))。
* 若要创建类型相似但大小不同的张量,请使用 `tensor.new_*` 创建操作。
* 存在一个遗留构造函数 `torch.Tensor`,不建议继续使用。请改用 [`torch.tensor()`](https://docs.pytorch.org/docs/stable/generated/torch.tensor.html#torch.tensor "torch.tensor")。
*** ** * ** ***
```python
Tensor.__init__(self, data)
```
*** ** * ** ***
该构造函数已弃用,建议改用 [`torch.tensor()`](https://docs.pytorch.org/docs/stable/generated/torch.tensor.html#torch.tensor "torch.tensor")。
此构造函数的行为取决于 `data` 的类型:
* 如果 `data` 是 Tensor,则返回原始 Tensor 的别名。与 [`torch.tensor()`](https://docs.pytorch.org/docs/stable/generated/torch.tensor.html#torch.tensor "torch.tensor") 不同,此操作会跟踪自动微分并将梯度传播到原始 Tensor。对于这种 `data` 类型不支持 `device` 关键字参数。
* 如果 `data` 是序列或嵌套序列,则创建一个默认数据类型(通常是 `torch.float32`)的张量,其数据为序列中的值,必要时执行类型转换。值得注意的是,此构造函数与 [`torch.tensor()`](https://docs.pytorch.org/docs/stable/generated/torch.tensor.html#torch.tensor "torch.tensor") 的区别在于,即使输入全是整数,此构造函数也会始终构造浮点张量。
* 如果 `data` 是 [`torch.Size`](size.html#torch.Size "torch.Size"),则返回一个该大小的空张量。
此构造函数不支持显式指定返回张量的 `dtype` 或 `device`。建议使用 [`torch.tensor()`](https://docs.pytorch.org/docs/stable/generated/torch.tensor.html#torch.tensor "torch.tensor"),它提供了此功能。
**参数:**
data (array_like): 用于构造张量的数据。
**关键字参数:**
device (torch.device, 可选): 返回张量的目标设备。默认值:如果为 None,则与此张量相同的 torch.device。
**`Tensor.T`**
返回此张量的维度反转视图。
如果 `x` 的维度数为 `n`,则 `x.T` 等价于 `x.permute(n-1, n-2, ..., 0)`。
**警告:** 在非二维张量上使用 `Tensor.T()` 来反转形状的做法已弃用,未来版本中将抛出错误。对于矩阵批量的转置,请考虑使用 `mT`;对于张量维度的反转,请使用 `x.permute(torch.arange(x.ndim - 1, -1, -1))`。
**`Tensor.H`**
返回矩阵(二维张量)的共轭转置视图。
对于复数矩阵,`x.H` 等价于 `x.transpose(0, 1).conj()`;对于实数矩阵,等价于 `x.transpose(0, 1)`。
另请参阅
`mH`: 同样适用于矩阵批量的属性。
**`Tensor.mT`**
返回此张量最后两个维度转置的视图。
`x.mT` 等价于 `x.transpose(-2, -1)`。
**`Tensor.mH`**
访问此属性等价于调用 `adjoint()`。
**方法表**
| [`Tensor.new_tensor`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.new_tensor.html#torch.Tensor.new_tensor "torch.Tensor.new_tensor") | 返回以 `data` 为张量数据的新 Tensor。 |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [`Tensor.new_full`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.new_full.html#torch.Tensor.new_full "torch.Tensor.new_full") | 返回大小为 `size` 且填充 `fill_value` 的 Tensor。 |
| [`Tensor.new_empty`](https://docs.pytorch.org/docs/stable/generated/ttorch.Tensor.new_empty.html#torch.Tensor.new_empty "torch.Tensor.new_empty") | 返回大小为 `size` 且填充未初始化数据的 Tensor。 |
| [`Tensor.new_ones`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.new_ones.html#torch.Tensor.new_ones "torch.Tensor.new_ones") | 返回大小为 `size` 且填充 `1` 的 Tensor。 |
| [`Tensor.new_zeros`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.new_zeros.html#torch.Tensor.new_zeros "torch.Tensor.new_zeros") | 返回大小为 `size` 且填充 `0` 的 Tensor。 |
| [`Tensor.is_cuda`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.is_cuda.html#torch.Tensor.is_cuda "torch.Tensor.is_cuda") | 如果 Tensor 存储在 GPU 上则为 `True`,否则为 `False`。 |
| [`Tensor.is_quantized`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.is_quantized.html#torch.Tensor.is_quantized "torch.Tensor.is_quantized") | 如果 Tensor 是量化张量则为 `True`,否则为 `False`。 |
| [`Tensor.is_meta`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.is_meta.html#torch.Tensor.is_meta "torch.Tensor.is_meta") | 如果 Tensor 是元张量则为 `True`,否则为 `False`。 |
| `Tensor.device` | 返回此 Tensor 所在的 [`torch.device`](tensor_attributes.html#torch.device "torch.device")。 |
| [`Tensor.grad`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.grad.html#torch.Tensor.grad "torch.Tensor.grad") | 此属性默认为 `None`,在首次调用 `backward()` 计算 `self` 的梯度时会变为 Tensor。 |
| [`Tensor.ndim`](https://docs.pytorch.org/docs/stable/generated/ttorch.Tensor.ndim.html#torch.Tensor.ndim "torch.Tensor.ndim") | [`dim()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.dim.html#torch.Tensor.dim "torch.Tensor.dim") 的别名 |
| [`Tensor.real`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.real.html#torch.Tensor.real "torch.Tensor.real") | 对于复数输入张量,返回包含 `self` 张量实部值的新张量。 |
| [`Tensor.imag`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.imag.html#torch.Tensor.imag "torch.Tensor.imag") | 返回包含 `self` 张量虚部值的新张量。 |
| [`Tensor.nbytes`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.nbytes.html#torch.Tensor.nbytes "torch.Tensor.nbytes") | 如果张量不使用稀疏存储布局,则返回张量元素视图占用的字节数。 |
| [`Tensor.itemsize`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.itemsize.html#torch.Tensor.itemsize "torch.Tensor.itemsize") | [`element_size()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.element_size.html#torch.Tensor.element_size "torch.Tensor.element_size") 的别名 |
| [`Tensor.abs`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.abs.html#torch.Tensor.abs "torch.Tensor.abs") | 参见 [`torch.abs()`](https://docs.pytorch.org/docs/stable/generated/torch.abs.html#torch.abs "torch.abs") |
| [`Tensor.abs_`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.abs_.html#torch.Tensor.abs_ "torch.TTensor.abs_") | [`abs()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.abs.html#torch.Tensor.abs "torch.Tensor.abs") 的原位版本 |
| [`Tensor.absolute`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.absolute.html#torch.Tensor.absolute "torch.Tensor.absolute") | [`abs()`](https://docs.pytorch.org/docs/stable/generated/torch.abs.html#torch.abs "torch.abs") 的别名 |
| [`Tensor.absolute_`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.absolute_.html#torch.TTensor.absolute_ "torch.Tensor.absolute_") | [`absolute()`](https://docs.pytorch.org/docs/stable/generated/torch.TTensor.absolute.html#torch.Tensor.absolute "torch.Tensor.absolute") 的原位版本,`abs_()` 的别名 |
| [`Tensor.acos`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.acos.html#torch.Tensor.acos "torch.Tensor.acos") | 参见 [`torch.acos()`](https://docs.pytorch.org/docs/stable/generated/torch.acos.html#torch.acos "torch.acos") |
| [`Tensor.acos_`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.acos_.html#torch.Tensor.acos_ "torch.Tensor.acos_") | [`acos()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.acos.html#torch.Tensor.acos "torch.Tensor.acos") 的原位版本 |
| [`Tensor.arccos`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.arccos.html#torch.Tensor.arccos "torch.Tensor.arccos") | 参见 [`torch.arccos()`](https://docs.pytorch.org/docs/stable/generated/torch.arccos.html#torch.arccos "torch.arccos") |
| [`Tensor.arccos_`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.arccos_.html#torch.Tensor.arccos_ "torch.Tensor.arccos_") | [`arccos()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.arccos.html#torch.Tensor.arccos "torch.Tensor.arccos") 的原位版本 |
| [`Tensor.add`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.add.html#torch.Tensor.add "torch.Tensor.add") | 将标量或张量加到 `self` 张量上。 |
| [`Tensor.add_`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.add_.html#torch.Tensor.add_ "torch.Tensor.add_") | [`add()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.add.html#torch.Tensor.add "torch.Tensor.add") 的原位版本 |
| [`Tensor.addbmm`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.addbmm.html#torch.Tensor.addbmm "torch.Tensor.addbmm") | 参见 [`torch.addbmm()`](https://docs.pytorch.org/docs/stable/generated/torch.addbmm.html#torch.addbmm "torch.addbmm") |
| [`Tensor.addbmm_`](https://docs.pytorch.org/docs/stable/generated/torch.TTensor.addbmm_.html#torch.Tensor.addbmm_ "torch.Tensor.addbmm_") | [`addbmm()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.addbmm.html#torch.Tensor.addbmm "torch.Tensor.addbmm") 的原位版本 |
| [`Tensor.addcdiv`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.addcdiv.html#torch.Tensor.addcdiv "torch.Tensor.addcdiv") | 参见 [`torch.addcdiv()`](https://docs.pytorch.org/docs/stable/generated/torch.addcdiv.html#torch.addcdiv "torch.addcdiv") |
| [`Tensor.addcdiv_`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.addcdiv_.html#torch.Tensor.addcdiv_ "torch.Tensor.addcdiv_") | [`addcdiv()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.addcdiv.html#torch.Tensor.addcdiv "torch.Tensor.addcdiv") 的原位版本 |
| [`Tensor.addcmul`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.addcmul.html#torch.TTensor.addcmul "torch.Tensor.addcmul") | 参见 [`torch.addcmul()`](https://docs.pytorch.org/docs/stable/generated/torch.addcmul.html#torch.addcmul "torch.addcmul") |
| [`Tensor.addcmul_`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.addcmul_.html#torch.Tensor.addcmul_ "torch.Tensor.addcmul_") | [`addcmul()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.addcmul.html#torch.Tensor.addcmul "torch.Tensor.addcmul") 的原位版本 |
| [`Tensor.addmm`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.addmm.html#torch.Tensor.addmm "torch.Tensor.addmm") | 参见 [`torch.addmm()`](https://docs.pytorch.org/docs/stable/generated/torch.addmm.html#torch.addmm "torch.addmm") |
| [`Tensor.addmm_`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.addmm_.html#torch.Tensor.addmm_ "torch.Tensor.addmm_") | [`addmm()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.addmm.html#torch.Tensor.addmm "torch.TTensor.addmm") 的原位版本 |
| [`Tensor.sspaddmm`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.sspaddmm.html#torch.Tensor.sspaddmm "torch.Tensor.sspaddmm") | 参见 [`torch.sspaddmm()`](https://docs.pytorch.org/docs/stable/generated/torch.sspaddmm.html#torch.sspaddmm "torch.sspaddmm") |
| [`Tensor.addmv`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.addmv.html#torch.Tensor.addmv "torch.Tensor.addmv") | 参见 [`torch.addmv()`](https://docs.pytorch.org/docs/stable/generated/torch.addmv.html#torch.addmv "torch.addmv") |
| [`Tensor.addmv_`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.addmv_.html#torch.Tensor.addmv_ "torch.Tensor.addmv_") | [`addmv()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.addmv.html#torch.Tensor.addmv "torch.Tensor.addmv") 的原位版本 |
| [`Tensor.addr`](https://docs.pytorch.org/docs/stable/generated/torch.TTensor.addr.html#torch.Tensor.addr "torch.Tensor.addr") | 参见 [`torch.addr()`](https://docs.pytorch.org/docs/stable/generated/torch.addr.html#torch.addr "torch.addr") |
| [`Tensor.addr_`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.addr_.html#torch.Tensor.addr_ "torch.Tensor.addr_") | [`addr()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.addr.html#torch.Tensor.addr "torch.Tensor.addr") 的原位版本 |
| [`Tensor.adjoint`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.adjoint.html#torch.Tensor.adjoint "torch.Tensor.adjoint") | [`adjoint()`](https://docs.pytorch.org/docs/stable/generated/torch.adjoint.html#torch.adjoint "torch.adjoint") 的别名 |
| [`Tensor.allclose`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.allclose.html#torch.Tensor.allclose "torch.Tensor.allclose") | 参见 [`torch.allclose()`](https://docs.pytorch.org/docs/stable/generated/torch.allclose.html#torch.allclose "torch.allclose") |
| [`Tensor.amax`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.amax.html#torch.Tensor.amax "torch.Tensor.amax") | 参见 [`torch.amax()`](https://docs.pytorch.org/docs/stable/generated/torch.amax.html#torch.amax "torch.amax") |
| [`Tensor.amin`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.amin.html#torch.Tensor.amin "torch.Tensor.amin") | 参见 [`torch.amin()`](https://docs.pytorch.org/docs/stable/generated/torch.amin.html#torch.amin "torch.amin") |
| [`Tensor.aminmax`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.aminmax.html#torch.TTensor.aminmax "torch.Tensor.aminmax") | 参见 [`torch.aminmax()`](https://docs.pytorch.org/docs/stable/generated/torch.aminmax.html#torch.aminmax "torch.aminmax") |
| [`Tensor.angle`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.angle.html#torch.Tensor.angle "torch.Tensor.angle") | 参见 \[`torch.angle()`\](https://docs.pytorch.org/docs/stable/generated |
*** ** * ** ***
*** ** * ** ***
## 张量属性
每个 `torch.Tensor` 都拥有 `torch.dtype`、`torch.device` 和 `torch.layout` 属性。
*** ** * ** ***
### torch.dtype
*** ** * ** ***
```python
class torch.dtype
```
*** ** * ** ***
`torch.dtype` 是一个表示 `torch.Tensor` 数据类型的对象。PyTorch 提供了十二种不同的数据类型:
| 数据类型 | dtype | 旧版构造函数 |
|--------------|--------------------------------------|--------------------------|
| 32位浮点数 | `torch.float32` 或 `torch.float` | `torch.*.FloatTensor` |
| 64位浮点数 | `torch.float64` 或 `torch.double` | `torch.*.DoubleTensor` |
| 64位复数 | `torch.complex64` 或 `torch.cfloat` | |
| 128位复数 | `torch.complex128` 或 `torch.cdouble` | |
| 16位浮点数 \[1\] | `torch.float16` 或 `torch.half` | `torch.*.HalfTensor` |
| 16位浮点数 \[2\] | `torch.bfloat16` | `torch.*.BFloat16Tensor` |
| 8位无符号整数 | `torch.uint8` | `torch.*.ByteTensor` |
| 8位有符号整数 | `torch.int8` | `torch.*.CharTensor` |
| 16位有符号整数 | `torch.int16` 或 `torch.short` | `torch.*.ShortTensor` |
| 32位有符号整数 | `torch.int32` 或 `torch.int` | `torch.*.IntTensor` |
| 64位有符号整数 | `torch.int64` 或 `torch.long` | `torch.*.LongTensor` |
| 布尔型 | `torch.bool` | `torch.*.BoolTensor` |
\[1\] 有时称为 binary16:使用 1 位符号、5 位指数和 10 位尾数。适用于需要高精度的场景。
\[2\] 有时称为 Brain 浮点数:使用 1 位符号、8 位指数和 7 位尾数。由于与 `float32` 具有相同的指数位数,适用于需要大范围的场景。
要判断 `torch.dtype` 是否为浮点数据类型,可以使用属性 `is_floating_point`,如果数据类型是浮点类型,则返回 `True`。
要判断 `torch.dtype` 是否为复数数据类型,可以使用属性 `is_complex`,如果数据类型是复数类型,则返回 `True`。
当算术运算(加、减、除、乘)的输入数据类型不同时,我们会按照以下规则找到满足条件的最小数据类型进行提升:
* 如果标量操作数的类型属于比张量操作数更高的类别(复数 \> 浮点 \> 整数 \> 布尔值),则提升到足以容纳该类别所有标量操作数的类型。
* 如果零维张量操作数的类别高于有维度的操作数,则提升到足以容纳该类别所有零维张量操作数的类型。
* 如果没有更高类别的零维操作数,则提升到足以容纳所有有维度操作数的类型。
浮点标量操作数的默认数据类型为 `torch.get_default_dtype()`,而整数非布尔标量操作数的默认数据类型为 `torch.int64`。与 NumPy 不同,我们在确定操作数的最小数据类型时不会检查具体值。目前不支持量化和复数类型的提升。
提升示例:
```python
>>> float_tensor = torch.ones(1, dtype=torch.float)
>>> double_tensor = torch.ones(1, dtype=torch.double)
>>> complex_float_tensor = torch.ones(1, dtype=torch.complex64)
>>> complex_double_tensor = torch.ones(1, dtype=torch.complex128)
>>> int_tensor = torch.ones(1, dtype=torch.int)
>>> long_tensor = torch.ones(1, dtype=torch.long)
>>> uint_tensor = torch.ones(1, dtype=torch.uint8)
>>> bool_tensor = torch.ones(1, dtype=torch.bool)
# zero-dim tensors
>>> long_zerodim = torch.tensor(1, dtype=torch.long)
>>> int_zerodim = torch.tensor(1, dtype=torch.int)
>>> torch.add(5, 5).dtype
torch.int64
# 5 is an int64, but does not have higher category than int_tensor so is not considered.
>>> (int_tensor + 5).dtype
torch.int32
>>> (int_tensor + long_zerodim).dtype
torch.int32
>>> (long_tensor + int_tensor).dtype
torch.int64
>>> (bool_tensor + long_tensor).dtype
torch.int64
>>> (bool_tensor + uint_tensor).dtype
torch.uint8
>>> (float_tensor + double_tensor).dtype
torch.float64
>>> (complex_float_tensor + complex_double_tensor).dtype
torch.complex128
>>> (bool_tensor + int_tensor).dtype
torch.int32
# Since long is a different kind than float, result dtype only needs to be large enough
# to hold the float.
>>> torch.add(long_tensor, float_tensor).dtype
torch.float32
```
*** ** * ** ***
当指定算术运算的输出张量时,我们允许将其类型转换为输出张量的数据类型,但存在以下例外情况:
* 整型输出张量不能接受浮点型张量
* 布尔型输出张量不能接受非布尔型张量
* 非复数型输出张量不能接受复数型张量
类型转换示例:
```python
# allowed:
>>> float_tensor *= float_tensor
>>> float_tensor *= int_tensor
>>> float_tensor *= uint_tensor
>>> float_tensor *= bool_tensor
>>> float_tensor *= double_tensor
>>> int_tensor *= long_tensor
>>> int_tensor *= uint_tensor
>>> uint_tensor *= int_tensor
# disallowed (RuntimeError: result type can't be cast to the desired output type):
>>> int_tensor *= float_tensor
>>> bool_tensor *= int_tensor
>>> bool_tensor *= uint_tensor
>>> float_tensor *= complex_float_tensor
```
*** ** * ** ***
### torch.device
*** ** * ** ***
```python
class torch.device
```
*** ** * ** ***
`torch.device` 是一个表示设备类型的对象,`torch.Tensor` 会被分配或已经分配在该设备上。
`torch.device` 包含一个设备类型(最常见的是 "cpu" 或 "cuda",但也可能是 ["mps"](mps.html)、["xpu"](xpu.html)、["xla"](https://github.com/pytorch/xla/) 或 ["meta"](meta.html))以及可选的设备序号。如果未指定设备序号,该对象将始终代表该设备类型的当前设备,即使在调用 [`torch.cuda.set_device()`](https://docs.pytorch.org/docs/stable/generated/torch.cuda.set_device.html#torch.cuda.set_device "torch.cuda.set_device") 之后也是如此;例如,使用设备 `'cuda'` 构造的 `torch.Tensor` 等同于 `'cuda:X'`,其中 X 是 [`torch.cuda.current_device()`](https://docs.pytorch.org/docs/stable/generated/torch.cuda.current_device.html#torch.cuda.current_device "torch.cuda.current_device") 的结果。
可以通过 `Tensor.device` 属性访问 `torch.Tensor` 的设备。
`torch.device` 可以通过字符串或字符串加设备序号来构造:
通过字符串:
```python
>>> torch.device('cuda:0')
device(type='cuda', index=0)
>>> torch.device('cpu')
device(type='cpu')
>>> torch.device('mps')
device(type='mps')
>>> torch.device('cuda') # current cuda device
device(type='cuda')
```
*** ** * ** ***
通过字符串和设备序号:
```python
>>> torch.device('cuda', 0)
device(type='cuda', index=0)
>>> torch.device('mps', 0)
device(type='mps', index=0)
>>> torch.device('cpu', 0)
device(type='cpu', index=0)
```
*** ** * ** ***
设备对象也可用作上下文管理器,用于更改张量分配的默认设备:
```python
>>> with torch.device('cuda:1'):
... r = torch.randn(2, 3)
>>> r.device
device(type='cuda', index=1)
```
*** ** * ** ***
如果向工厂函数传递了显式且非 None 的设备参数,此上下文管理器将不起作用。要全局更改默认设备,请参阅 `torch.set_default_device()`。
警告:此函数会对每次调用 torch API 的 Python 操作(不仅限于工厂函数)产生轻微性能开销。如果这给您带来问题,请在 发表评论。
注意:函数中的 `torch.device` 参数通常可以用字符串替代,这有助于快速原型开发代码。
*** ** * ** ***
```python
>>> # Example of a function that takes in a torch.device
>>> cuda1 = torch.device('cuda:1')
>>> torch.randn((2,3), device=cuda1)
```
*** ** * ** ***
```python
>>> # You can substitute the torch.device with a string
>>> torch.randn((2,3), device='cuda:1')
```
*** ** * ** ***
注意:由于历史遗留原因,可以通过单个设备序号来构造设备,该序号会被视为当前[加速器](torch.html#accelerators)类型。
这与 `Tensor.get_device()` 的行为一致------该方法会返回设备张量的序号,但不支持CPU张量。
*** ** * ** ***
```python
>>> torch.device(1)
device(type='cuda', index=1)
```
*** ** * ** ***
注意:接收设备参数的方法通常支持(格式正确的)字符串或(旧版)整数设备序号,以下写法都是等效的:
```python
>>> torch.randn((2,3), device=torch.device('cuda:1'))
>>> torch.randn((2,3), device='cuda:1')
>>> torch.randn((2,3), device=1) # legacy
```
*** ** * ** ***
注意:张量不会自动在设备间移动,需要用户显式调用。标量张量(`tensor.dim()==0`的情况)是此规则唯一的例外------当需要时它们会自动从CPU转移到GPU,因为该操作可以"零成本"完成。
*** ** * ** ***
示例:
```python
>>> # two scalars
>>> torch.ones(()) + torch.ones(()).cuda() # OK, scalar auto-transferred from CPU to GPU
>>> torch.ones(()).cuda() + torch.ones(()) # OK, scalar auto-transferred from CPU to GPU
```
*** ** * ** ***
```python
>>> # one scalar (CPU), one vector (GPU)
>>> torch.ones(()) + torch.ones(1).cuda() # OK, scalar auto-transferred from CPU to GPU
>>> torch.ones(1).cuda() + torch.ones(()) # OK, scalar auto-transferred from CPU to GPU
```
*** ** * ** ***
```python
>>> # one scalar (GPU), one vector (CPU)
>>> torch.ones(()).cuda() + torch.ones(1) # Fail, scalar not auto-transferred from GPU to CPU and non-scalar not auto-transferred from CPU to GPU
>>> torch.ones(1) + torch.ones(()).cuda() # Fail, scalar not auto-transferred from GPU to CPU and non-scalar not auto-transferred from CPU to GPU
```
*** ** * ** ***
### torch.layout
*** ** * ** ***
```python
class torch.layout
```
*** ** * ** ***
警告:`torch.layout` 类目前处于测试阶段,后续可能会发生变化。
`torch.layout` 是一个表示 `torch.Tensor` 内存布局的对象。目前我们支持 `torch.strided`(密集张量),并对 `torch.sparse_coo`(稀疏 COO 张量)提供测试版支持。
`torch.strided` 表示密集张量,这是最常用的内存布局方式。每个跨步张量都有一个关联的 `torch.Storage` 对象用于存储数据。这些张量提供了存储的多维[跨步](https://en.wikipedia.org/wiki/Stride_of_an_array)视图。跨步是一个整数列表:第 k 个跨步表示在张量的第 k 维中,从一个元素移动到下一个元素所需的内存跳跃量。这个概念使得许多张量操作能够高效执行。
*** ** * ** ***
示例:
```python
>>> x = torch.tensor([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
>>> x.stride()
(5, 1)
>>> x.t().stride()
(1, 5)
```
*** ** * ** ***
有关 `torch.sparse_coo` 张量的更多信息,请参阅 [torch.sparse](sparse.html#sparse-docs)。
*** ** * ** ***
### torch.memory_format
*** ** * ** ***
class torch.memory_format
*** ** * ** ***
`torch.memory_format` 是一个表示内存格式的对象,用于描述 `torch.Tensor` 当前或将要分配的内存布局。
可能的取值包括:
* `torch.contiguous_format`:
张量当前或将要分配在密集且无重叠的内存中。其步长(strides)以递减顺序表示。
* `torch.channels_last`:
张量当前或将要分配在密集且无重叠的内存中。其步长遵循 `strides[0] strides[2] strides[3] strides[1] == 1` 的顺序,即 NHWC 格式。
* `torch.channels_last_3d`:
张量当前或将要分配在密集且无重叠的内存中。其步长遵循 `strides[0] strides[2] strides[3] strides[4] strides[1] == 1` 的顺序,即 NDHWC 格式。
* `torch.preserve_format`:
用于 `clone` 等函数中,以保留输入张量的内存格式。如果输入张量分配在密集且无重叠的内存中,输出张量的步长将从输入张量复制。否则,输出张量的步长将遵循 `torch.contiguous_format`。
*** ** * ** ***
*** ** * ** ***
## 张量视图
PyTorch 允许一个张量作为现有张量的`视图(View)`。视图张量与其基础张量共享相同底层数据。支持`视图`可以避免显式数据拷贝,从而实现快速且内存高效的形状变换、切片和逐元素操作。
例如,要获取现有张量`t`的视图,可以调用`t.view(...)`方法。
*** ** * ** ***
```python
>>> t = torch.rand(4, 4)
>>> b = t.view(2, 8)
>>> t.storage().data_ptr() == b.storage().data_ptr() # `t` and `b` share the same underlying data.
True
# Modifying view tensor changes base tensor as well.
>>> b[0][0] = 3.14
>>> t[0][0]
tensor(3.14)
```
*** ** * ** ***
由于视图与基础张量共享底层数据,当修改视图中的数据时,基础张量也会同步更新。
PyTorch操作通常返回一个新张量作为输出,例如[`add()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.add.html#torch.Tensor.add "torch.Tensor.add")。但对于视图操作,输出会作为输入张量的视图以避免不必要的数据拷贝。
创建视图时不会发生数据移动,视图张量仅改变了对同一数据的解释方式。对连续张量取视图可能会产生非连续张量。
用户需特别注意,因为连续性可能隐式影响性能。[`transpose()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.transpose.html#torch.Tensor.transpose "torch.Tensor.transpose")就是典型示例。
*** ** * ** ***
```python
>>> base = torch.tensor([[0, 1],[2, 3]])
>>> base.is_contiguous()
True
>>> t = base.transpose(0, 1) # `t` is a view of `base`. No data movement happened here.
# View tensors might be non-contiguous.
>>> t.is_contiguous()
False
# To get a contiguous tensor, call `.contiguous()` to enforce
# copying data when `t` is not contiguous.
>>> c = t.contiguous()
```
*** ** * ** ***
以下是PyTorch中视图操作(view ops)的完整参考列表:
* 基础切片和索引操作,例如`tensor[0, 2:, 1:7:2]`会返回基础`tensor`的视图(注意事项见下文)
* [`adjoint()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.adjoint.html#torch.Tensor.adjoint "torch.Tensor.adjoint")
* [`as_strided()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.as_strided.html#torch.Tensor.as_strided "torch.Tensor.as_strided")
* [`detach()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.detach.html#torch.Tensor.detach "torch.Tensor.detach")
* [`diagonal()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.diagonal.html#torch.Tensor.diagonal "torch.Tensor.diagonal")
* [`expand()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.expand.html#torch.Tensor.expand "torch.Tensor.expand")
* [`expand_as()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.expand_as.html#torch.Tensor.expand_as "torch.Tensor.expand_as")
* [`movedim()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.movedim.html#torch.Tensor.movedim "torch.Tensor.movedim")
* [`narrow()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.narrow.html#torch.Tensor.narrow "torch.Tensor.narrow")
* [`permute()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.permute.html#torch.Tensor.permute "torch.Tensor.permute")
* [`select()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.select.html#torch.Tensor.select "torch.Tensor.select")
* [`squeeze()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.squeeze.html#torch.Tensor.squeeze "torch.Tensor.squeeze")
* [`transpose()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.transpose.html#torch.Tensor.transpose "torch.Tensor.transpose")
* [`t()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.t.html#torch.Tensor.t "torch.Tensor.t")
* [`T`](tensors.html#torch.Tensor.T "torch.Tensor.T")
* [`H`](tensors.html#torch.Tensor.H "torch.Tensor.H")
* [`mT`](tensors.html#torch.Tensor.mT "torch.Tensor.mT")
* [`mH`](tensors.html#torch.Tensor.mH "torch.Tensor.mH")
* [`real`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.real.html#torch.Tensor.real "torch.Tensor.real")
* [`imag`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.imag.html#torch.Tensor.imag "torch.Tensor.imag")
* `view_as_real()`
* [`unflatten()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.unflatten.html#torch.Tensor.unflatten "torch.Tensor.unflatten")
* [`unfold()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.unfold.html#torch.Tensor.unfold "torch.Tensor.unfold")
* [`unsqueeze()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.unsqueeze.html#torch.Tensor.unsqueeze "torch.Tensor.unsqueeze")
* [`view()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.view.html#torch.Tensor.view "torch.Tensor.view")
* [`view_as()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.view_as.html#torch.Tensor.view_as "torch.Tensor.view_as")
* [`unbind()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.unbind.html#torch.Tensor.unbind "torch.Tensor.unbind")
* [`split()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.split.html#torch.Tensor.split "torch.Tensor.split")
* [`hsplit()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.hsplit.html#torch.Tensor.hsplit "torch.Tensor.hsplit")
* [`vsplit()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.vsplit.html#torch.Tensor.vsplit "torch.Tensor.vsplit")
* [`tensor_split()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.tensor_split.html#torch.Tensor.tensor_split "torch.Tensor.tensor_split")
* `split_with_sizes()`
* [`swapaxes()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.swapaxes.html#torch.Tensor.swapaxes "torch.Tensor.swapaxes")
* [`swapdims()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.swapdims.html#torch.Tensor.swapdims "torch.Tensor.swapdims")
* [`chunk()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.chunk.html#torch.Tensor.chunk "torch.Tensor.chunk")
* [`indices()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.indices.html#torch.Tensor.indices "torch.Tensor.indices")(仅稀疏张量)
* [`values()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.values.html#torch.Tensor.values "torch.Tensor.values")(仅稀疏张量)
*** ** * ** ***
注意事项:
当通过索引访问张量内容时,PyTorch遵循NumPy的行为规范:基础索引返回视图,而高级索引返回副本。无论是基础索引还是高级索引进行的赋值操作都是就地(in-place)执行的。更多示例可参考[NumPy索引文档](https://numpy.org/doc/stable/user/basics.indexing.html)。
需要特别说明的几个操作:
* [`reshape()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.reshape.html#torch.Tensor.reshape "torch.Tensor.reshape")、[`reshape_as()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.reshape_as.html#torch.Tensor.reshape_as "torch.Tensor.reshape_as")和[`flatten()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.flatten.html#torch.Tensor.flatten "torch.Tensor.flatten")可能返回视图或新张量,用户代码不应依赖其返回类型
* [`contiguous()`](https://docs.pytorch.org/docs/stable/generated/torch.Tensor.contiguous.html#torch.Tensor.contiguous "torch.Tensor.contiguous")在输入张量已连续时返回其自身,否则会通过复制数据返回新的连续张量
如需深入了解PyTorch内部实现机制,请参阅[ezyang的PyTorch内部原理博客文章](http://blog.ezyang.com/2019/05/pytorch-internals/)。
*** ** * ** ***
*** ** * ** ***
## 自动混合精度包 - torch.amp
`torch.amp` 提供了混合精度的便捷方法,其中部分操作使用 `torch.float32` (`float`) 数据类型,而其他操作使用较低精度的浮点数据类型 (`lower_precision_fp`):`torch.float16` (`half`) 或 `torch.bfloat16`。某些运算(如线性层和卷积)在 `lower_precision_fp` 下速度更快,而其他运算(如归约操作)通常需要 `float32` 的动态范围。混合精度会尝试为每个运算匹配最合适的数据类型。
通常,使用 `torch.float16` 数据类型的"自动混合精度训练"会同时使用 `torch.autocast` 和 `torch.amp.GradScaler`,如[自动混合精度示例](notes/amp_examples.html#amp-examples)和[自动混合精度教程](https://pytorch.org/tutorials/recipes/recipes/amp_recipe.html)所示。不过,`torch.autocast` 和 `torch.GradScaler` 是模块化的,也可以根据需要单独使用。如 `torch.autocast` 的CPU示例部分所示,在CPU上使用 `torch.bfloat16` 数据类型的"自动混合精度训练/推理"仅需使用 `torch.autocast`。
*** ** * ** ***
警告:`torch.cuda.amp.autocast(args...)` 和 `torch.cpu.amp.autocast(args...)` 将被弃用,请改用 `torch.autocast("cuda", args...)` 或 `torch.autocast("cpu", args...)`。
`torch.cuda.amp.GradScaler(args...)` 和 `torch.cpu.amp.GradScaler(args...)` 将被弃用,请改用 `torch.GradScaler("cuda", args...)` 或 `torch.GradScaler("cpu", args...)`。
`torch.autocast` 和 [`torch.cpu.amp.autocast`](https://pytorch.org/docs/stable/data.html#torch.cpu.amp.autocast "torch.cpu.amp.autocast") 是1.10版本新增的功能。
*** ** * ** ***
### 自动类型转换
*** ** * ** ***
```python
torch.amp.autocast_mode.is_autocast_available(device_type)
```
*** ** * ** ***
返回一个布尔值,表示`device_type`上是否支持自动类型转换。
参数
* `device_type (str)` -- 要使用的设备类型。可选值包括:'cuda'、'cpu'、'mtia'、'xpu'等。
该类型与[`torch.device`](tensor_attributes.html#torch.device "torch.device")的type属性类型相同。
因此,您可以通过Tensor.device.type获取张量的设备类型。
返回类型:bool
*** ** * ** ***
```python
class torch.autocast(device_type, dtype=None, enabled=True, cache_enabled=None)
```
*** ** * ** ***
`autocast` 实例可作为上下文管理器或装饰器,允许脚本中的部分区域以混合精度运行。
在这些区域中,运算会根据 autocast 自动选择特定数据类型执行,从而在保持精度的同时提升性能。详情请参阅 [Autocast 运算参考](#Autocast 运算参考)。
进入启用 autocast 的区域时,张量可以是任意类型。使用 autocast 时,不应在模型或输入上调用 `half()` 或 `bfloat16()`。
`autocast` 应仅包装网络的前向传播(包括损失计算),不建议在 autocast 下执行反向传播。反向运算会使用与对应前向运算相同的类型执行。
CUDA 设备示例:
```python
# 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 torch.autocast(device_type="cuda"):
output = model(input)
loss = loss_fn(output, target)
# Exits the context manager before backward()
loss.backward()
optimizer.step()
```
*** ** * ** ***
请参阅[自动混合精度示例](notes/amp_examples.html#amp-examples)了解在更复杂场景下的使用方法(包括梯度缩放),例如梯度惩罚、多模型/多损失函数、自定义自动求导函数等情况。
`autocast`也可以作为装饰器使用,例如用于模型的`forward`方法上:
```python
class AutocastModel(nn.Module):
...
@torch.autocast(device_type="cuda")
def forward(self, input):
...
```
*** ** * ** ***
在启用了自动混合精度(autocast)的区域中生成的浮点张量可能是`float16`类型。
当返回到禁用自动混合精度的区域后,如果将这些张量与不同数据类型的浮点张量一起使用,可能会导致类型不匹配错误。如果出现这种情况,请将自动混合精度区域生成的张量转换回`float32`类型(或根据需要选择其他数据类型)。
如果来自自动混合精度区域的张量已经是`float32`类型,则转换操作不会实际执行,也不会产生额外开销。
CUDA示例:
```python
# Creates some tensors in default dtype (here assumed to be 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 is on autocast's 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 types
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 训练示例:
```python
# 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_type="cpu", dtype=torch.bfloat16):
output = model(input)
loss = loss_fn(output, target)
loss.backward()
optimizer.step()
```
*** ** * ** ***
CPU 推理示例:
```python
# Creates model in default precision
model = Net().eval()
with torch.autocast(device_type="cpu", dtype=torch.bfloat16):
for input in data:
# Runs the forward pass with autocasting.
output = model(input)
```
*** ** * ** ***
**使用 Jit Trace 进行 CPU 推理的示例:**
*** ** * ** ***
```python
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_enabled=False):
model = torch.jit.trace(model, torch.randn(1, input_size))
model = torch.jit.freeze(model)
# Models Runfor _ in range(3):
model(torch.randn(1, input_size))
```
*** ** * ** ***
在启用了自动类型转换的区域中出现类型不匹配错误属于程序缺陷;如果您遇到此情况,请提交问题报告。
`autocast(enabled=False)` 子区域可以嵌套在启用自动类型转换的区域内。
局部禁用自动类型转换很有用,例如当您希望强制某个子区域以特定 `dtype` 运行时。禁用自动类型转换能让您精确控制执行类型。在该子区域中,来自外围区域的输入
应在使用前显式转换为目标 `dtype`:
```python
# Creates some tensors in default dtype (here assumed to be 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):
# Calls e_float16.float() to ensure float32 execution
# (necessary because e_float16 was created in an autocasted region)
f_float32 = torch.mm(c_float32, e_float16.float())
# No manual casts are required when re-entering the autocast-enabled region.
# torch.mm again runs in float16 and produces float16 output, regardless of input types.
g_float16 = torch.mm(d_float32, f_float32)
```
*** ** * ** ***
自动转换状态是线程局部的。若要在新线程中启用该功能,必须在该线程内调用上下文管理器或装饰器。当每个进程使用多个GPU时,这会影响`torch.nn.DataParallel`和`torch.nn.parallel.DistributedDataParallel`的行为(参见[多GPU工作指南](notes/amp_examples.html#amp-multigpu))。
*** ** * ** ***
#### 参数说明
* `device_type (str, 必填)` -- 指定使用的设备类型。可选值包括:'cuda'、'cpu'、'mtia'、'xpu'和'hpu'。该类型与[`torch.device`](tensor_attributes.html#torch.device "torch.device")的类型属性一致,因此可通过Tensor.device.type获取张量的设备类型。
* `enabled ([bool], 可选)` -- 控制是否在区域内启用自动转换功能。
默认值:`True`
* `dtype (torch_dtype, 可选)` -- 自动转换区域内运算的数据类型。当`dtype`为`None`时,将使用`get_autocast_dtype()`提供的默认值(CUDA设备默认为`torch.float16`,CPU设备默认为`torch.bfloat16`)。
默认值:`None`
* `cache_enabled ([bool], 可选)` -- 控制是否启用自动转换内部的权重缓存。
默认值:`True`
*** ** * ** ***
```python
torch.amp.custom_fwd(fwd=None, *, device_type, cast_inputs=None)[source]
```
*** ** * ** ***
为自定义自动求导函数的`forward`方法创建一个辅助装饰器。
自动求导函数是`torch.autograd.Function`的子类。
更多细节请参阅[示例页面](notes/amp_examples.html#amp-custom-examples)。
参数
* `device_type (str)` -- 要使用的设备类型。可选值包括'cuda'、'cpu'、'mtia'、'xpu'等。
该类型与[`torch.device`](tensor_attributes.html#torch.device "torch.device")的type属性相同。
因此,您可以通过Tensor.device.type获取张量的设备类型。
* `cast_inputs ( `torch.dtype` 或 None, 可选参数, 默认=None)` -- 如果非`None`,当`forward`在启用自动混合精度的区域运行时,会将输入的浮点张量转换为目标数据类型(非浮点张量不受影响),然后在禁用自动混合精度的状态下执行`forward`。
如果为`None`,则`forward`的内部操作会以当前的自动混合精度状态执行。
注意:如果被装饰的`forward`在未启用自动混合精度的区域被调用,`custom_fwd`将不起作用且`cast_inputs`不会产生任何效果。
*** ** * ** ***
```python
torch.amp.custom_bwd(bwd=None, *, device_type)
```
*** ** * ** ***
为自定义自动求导函数的反向方法创建一个辅助装饰器。
自动求导函数是 `torch.autograd.Function` 的子类。
该装饰器确保 `backward` 方法执行时的自动混合精度状态与 `forward` 方法保持一致。
更多细节请参阅[示例页面](notes/amp_examples.html#amp-custom-examples)。
**参数**
* `device_type (str)` -- 使用的设备类型。可选值包括 'cuda'、'cpu'、'mtia'、'xpu' 等。
该类型与 [`torch.device`](tensor_attributes.html#torch.device "torch.device") 的 type 属性相同。
因此,您可以通过 Tensor.device.type 获取张量的设备类型。
*** ** * ** ***
```python
torch.cuda.amp.autocast(enabled=True, dtype=torch.float16, cache_enabled=True)[source]
```
*** ** * ** ***
请参考 `torch.autocast`。
`torch.cuda.amp.autocast(args...)` 已被弃用,建议改用 `torch.amp.autocast("cuda", args...)`。
*** ** * ** ***
```python
torch.cuda.amp.custom_fwd(fwd=None, *, cast_inputs=None)
```
*** ** * ** ***
`torch.cuda.amp.custom_fwd(args...)` 已被弃用。请改用 `torch.amp.custom_fwd(args..., device_type='cuda')`。
*** ** * ** ***
```python
torch.cuda.amp.custom_bwd(bwd)
```
*** ** * ** ***
`torch.cuda.amp.custom_bwd(args...)` 已被弃用。请改用 `torch.amp.custom_bwd(args..., device_type='cuda')`。
*** ** * ** ***
```python
class torch.cpu.amp.autocast(enabled=True, dtype=torch.bfloat16, cache_enabled=True)
```
*** ** * ** ***
请参考 `torch.autocast`。
`torch.cpu.amp.autocast(args...)` 已被弃用,请改用 `torch.amp.autocast("cpu", args...)`。
*** ** * ** ***
### 梯度缩放
如果某个操作的前向传播输入为`float16`类型,则该操作的反向传播会产生`float16`类型的梯度。幅度较小的梯度值可能无法用`float16`表示,这些值会下溢为零("underflow"),导致对应参数的更新丢失。
为防止下溢,"梯度缩放"技术将网络的损失值乘以一个比例因子,并对缩放后的损失值执行反向传播。通过网络反向流动的梯度会按相同比例因子进行缩放。换句话说,梯度值的幅度因此增大,从而避免下溢为零。
在优化器更新参数之前,每个参数的梯度(`.grad`属性)应该进行反向缩放,这样比例因子就不会影响学习率。
*** ** * ** ***
注意:AMP/fp16可能不适用于所有模型!例如,大多数bf16预训练模型无法在最大值为65504的fp16数值范围内运行,会导致梯度上溢而非下溢。这种情况下,比例因子可能会降至1以下,试图将梯度调整到fp16动态范围内可表示的数字。虽然人们可能期望比例因子总是大于1,但我们的GradScaler并不保证这一点以保持性能。如果在使用AMP/fp16运行时遇到损失或梯度出现NaN值,请确认模型是否兼容。
*** ** * ** ***
```python
class torch.cuda.amp.GradScaler(init_scale=65536.0, growth_factor=2.0, backoff_factor=0.5, growth_interval=2000, enabled=True)
```
*** ** * ** ***
请参考 `torch.amp.GradScaler`。
`torch.cuda.amp.GradScaler(args...)` 已被弃用,请改用 `torch.amp.GradScaler("cuda", args...)`。
*** ** * ** ***
```python
class torch.cpu.amp.GradScaler(init_scale=65536.0, growth_factor=2.0, backoff_factor=0.5, growth_interval=2000, enabled=True)
```
*** ** * ** ***
请参考 `torch.amp.GradScaler`。
`torch.cpu.amp.GradScaler(args...)` 已弃用,请改用 `torch.amp.GradScaler("cpu", args...)`。
*** ** * ** ***
### 自动转换操作符参考
*** ** * ** ***
#### 操作符适用性
在`float64`或非浮点数据类型(dtypes)中运行的操作符不适用自动类型转换,无论是否启用autocast,这些操作符都会保持原有数据类型运行。
只有非原地操作(out-of-place ops)和张量方法(Tensor methods)才适用自动类型转换。
在启用autocast的区域中,虽然允许使用原地操作变体(in-place variants)和显式指定`out=...`张量的调用,但这些操作不会经过自动类型转换处理。
例如,在启用autocast的区域中,`a.addmm(b, c)`可以进行自动类型转换,但`a.addmm_(b, c)`和`a.addmm(b, c, out=d)`则不行。
为了获得最佳性能和稳定性,建议在启用autocast的区域中优先使用非原地操作。
显式指定`dtype=...`参数调用的操作符不适用自动类型转换,其输出将严格遵循指定的`dtype`参数。
*** ** * ** ***
#### CUDA 操作特定行为
以下列表描述了在启用自动混合精度区域中符合条件的操作行为。无论这些操作是通过`torch.nn.Module`调用、作为函数调用,还是作为`torch.Tensor`方法调用,它们都会经过自动混合精度处理。如果函数在多个命名空间中暴露,无论使用哪个命名空间,它们都会经过自动混合精度处理。
未列出的操作不会经过自动混合精度处理。它们会根据输入的类型运行。然而,如果未列出的操作位于经过自动混合精度处理的操作之后,自动混合精度仍可能改变这些操作的运行类型。
如果某个操作未被列出,我们假设它在`float16`下数值稳定。如果您认为某个未列出的操作在`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 运算
`__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 操作
这些操作不需要特定的数据类型(dtype)来保证稳定性,但会接收多个输入并要求输入的数据类型一致。如果所有输入都是 `float16`,操作将以 `float16` 运行。如果任一输入是 `float32`,自动类型转换(autocast)会将所有输入转换为 `float32` 并以 `float32` 运行该操作。
`addcdiv`, `addcmul`, `atan2`, `bilinear`, `cross`, `dot`, `grid_sample`, `index_put`, `scatter_add`, `tensordot`
部分未列出的操作(例如 `add` 等二元操作)本身会在不依赖自动类型转换的情况下提升输入类型。如果输入混合了 `float16` 和 `float32`,这些操作会以 `float32` 运行并生成 `float32` 输出,无论是否启用了自动类型转换。
*** ** * ** ***
##### 优先使用 `binary_cross_entropy_with_logits` 而非 `binary_cross_entropy`
[`torch.nn.functional.binary_cross_entropy()`](https://docs.pytorch.org/docs/stable/generated/torch.nn.functional.binary_cross_entropy.html#torch.nn.functional.binary_cross_entropy "torch.nn.functional.binary_cross_entropy")(以及封装它的[`torch.nn.BCELoss`](https://docs.pytorch.org/docs/stable/generated/torch.nn.BCELoss.html#torch.nn.BCELoss "torch.nn.BCELoss"))的反向传播可能会产生无法用 `float16` 表示的梯度。在启用自动混合精度(autocast)的区域中,前向输入可能是 `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` 可以安全地用于自动混合精度。
*** ** * ** ***
#### XPU 算子特定行为(实验性功能)
以下列表描述了在启用自动混合精度区域中符合条件的算子的行为表现。无论这些算子是通过 `torch.nn.Module` 调用、作为函数调用还是作为 `torch.Tensor` 方法调用,它们都会始终经过自动混合精度处理。如果函数在多个命名空间中暴露,无论通过哪个命名空间调用,都会进行自动混合精度转换。
未列在下方的算子不会经过自动混合精度处理。它们将按照输入定义的类型执行运算。不过,如果未列出的算子位于经过自动混合精度处理的算子下游,自动混合精度仍可能改变这些算子的运算类型。
如果某个算子未被列出,我们默认其在 `float16` 下具有数值稳定性。若您认为某个未列出的算子在 `float16` 下存在数值不稳定性问题,请提交问题报告。
*** ** * ** ***
##### 可自动转换为 `float16` 的 XPU 运算
`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`, `RNNCell`
*** ** * ** ***
##### 可自动转换为`float32`的XPU运算
`__pow__`, `__rdiv__`, `__rpow__`, `__rtruediv__`, `binary_cross_entropy_with_logits`, `cosine_embedding_loss`, `cosine_similarity`, `cumsum`, `dist`, `exp`, `group_norm`, `hinge_embedding_loss`, `kl_div`, `l1_loss`, `layer_norm`, `log`, `log_softmax`, `margin_ranking_loss`, `nll_loss`, `normalize`, `poisson_nll_loss`, `pow`, `reciprocal`, `rsqrt`, `soft_margin_loss`, `softmax`, `softmin`, `sum`, `triplet_margin_loss`
*** ** * ** ***
##### 提升至最宽输入类型的 XPU 运算
这些运算不需要特定的数据类型(dtype)来保证稳定性,但会接收多个输入并要求输入的数据类型一致。如果所有输入都是 `float16`,运算将以 `float16` 运行。如果任一输入是 `float32`,自动类型转换(autocast)会将所有输入转换为 `float32`,并以 `float32` 运行该运算。
支持的运算包括:
`bilinear`、`cross`、`grid_sample`、`index_put`、`scatter_add`、`tensordot`
部分未列出的运算(例如二元运算如 `add`)原生支持输入类型提升,无需自动类型转换干预。如果输入混合了 `float16` 和 `float32`,这些运算会以 `float32` 运行并输出 `float32` 结果,无论是否启用了自动类型转换。
*** ** * ** ***
#### CPU 操作特定行为
以下列表描述了在启用自动混合精度区域中合格操作的行为。无论这些操作是通过 `torch.nn.Module` 调用、作为函数调用,还是作为 `torch.Tensor` 方法调用,它们都会经过自动混合精度处理。如果函数在多个命名空间中暴露,无论调用哪个命名空间,都会应用自动混合精度。
未在下列列表中列出的操作不会经过自动混合精度处理。这些操作将按照其输入定义的类型执行。不过,如果未列出的操作位于经过自动混合精度处理的操作下游,自动混合精度仍可能改变其执行的数据类型。
如果某个操作未被列出,我们默认其在 `bfloat16` 下具有数值稳定性。若您认为某个未列出的操作在 `bfloat16` 中存在数值不稳定性问题,请提交问题报告。`float16` 的数据类型列表与 `bfloat16` 保持一致。
*** ** * ** ***
##### 可自动转换为 `bfloat16` 的 CPU 运算操作
`conv1d`, `conv2d`, `conv3d`, `bmm`, `mm`, `linalg_vecdot`, `baddbmm`, `addmm`, `addbmm`, `linear`, `matmul`, `_convolution`, `conv_tbc`, `mkldnn_rnn_layer`, `conv_transpose1d`, `conv_transpose2d`, `conv_transpose3d`, `prelu`, `scaled_dot_product_attention`, `_native_multi_head_attention`
*** ** * ** ***
##### 可自动转换为 `float32` 的 CPU 运算
`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`, `cosine_embedding_loss`, `nll_loss`, `nll_loss2d`, `hinge_embedding_loss`, `poisson_nll_loss`, `cross_entropy_loss`, `l1_loss`, `huber_loss`, `margin_ranking_loss`, `soft_margin_loss`, `triplet_margin_loss`, `multi_margin_loss`, `ctc_loss`, `kl_div`, `multilabel_margin_loss`, `binary_cross_entropy_with_logits`, `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_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`, `geqrf`, `_lu_with_info`, `qr`, `svd`, `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运算
这些运算不需要特定的数据类型(dtype)来保证稳定性,但会接收多个输入并要求输入的数据类型必须匹配。如果所有输入都是`bfloat16`类型,运算将以`bfloat16`精度执行。如果任一输入是`float32`类型,自动类型转换(autocast)会将所有输入转为`float32`并以该精度运行运算。
典型运算包括:
`cat`, `stack`, `index_copy`
注意:部分未列出的运算(如二元操作`add`)本身具备自动类型提升机制,无需autocast干预。当输入混合`bfloat16`和`float32`类型时,这些运算会始终以`float32`精度运行并输出`float32`结果,与autocast是否启用无关。
*** ** * ** ***
2025-08-20 (三)
亲爱的梅梅 生日快乐🎂