张量属性

每个 torch.Tensor 都具有一个 torch.dtypetorch.devicetorch.layout

torch.dtype

torch.dtype

torch.dtype 是一个表示 torch.Tensor 数据类型的对象。PyTorch 支持十二种不同的数据类型。

数据类型

数据类型(dtype)

传统构造函数

32位浮点数

torch.float32torch.float

torch.FloatTensor

64位浮点数

torch.float64torch.double

torch.DoubleTensor

64位复杂数

torch.complex64torch.cfloat

128位复数

torch.complex128torch.cdouble

16位浮点数 1

torch.float16torch.half

torch.HalfTensor

16位浮点数 2

torch.bfloat16

torch.BFloat16Tensor

8位无符号整数

torch.uint8

torch.ByteTensor

8位有符号整数

torch.int8

torch.CharTensor

16位带符号的整数

torch.int16torch.short

torch.ShortTensor

32位 signed 整数

torch.int32torch.int

torch.IntTensor

64位带符号的整数

torch.int64torch.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

当算术操作(addsubdivmul)的输入数据类型不同时,我们通过找到满足以下规则的最小数据类型来进行数据类型的提升:

  • 如果标量操作数的类型高于张量操作数的类别(复数 > 浮点 > 整型 > 布尔),则将其提升为能够容纳此类别中所有标量操作数的足够大的类型。

  • 如果零维度张量操作数的类别高于其他有维度的操作数,我们会将其提升为一种足够大的类型,以容纳同一类的所有零维度张量操作数。

  • 如果没有更高类别的零维度操作数,则会将其提升为一种足够大的类型,以容纳所有的带维度操作数。

浮点标量运算符的数据类型为 torch.get_default_dtype(),而整数非布尔型标量运算符的数据类型为 torch.int64。与 numpy 不同,在确定运算符的最小数据类型时,我们不会检查值。目前还不支持量化和复数类型。

促销例子:

>>> 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)
>>> double_tensor = torch.ones(1, dtype=torch.double)
>>> 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
当指定了算术运算的输出张量时,我们会将其转换为相应的 dtype,除非另有说明:
  • 一个积分输出张量无法接收浮点数张量。

  • 布尔输出张量不能接收非布尔张量。

  • 一个实数输出张量无法接收复数张量

类型转换示例:

# 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

torch.device

一个 torch.device 对象用于表示 torch.Tensor 所在的或者将要分配的设备。

The torch.device 包含一个设备类型(最常见的是“cpu”或“cuda”,但也可能是“mps”“xpu”“xla”“meta”),以及可选的设备序号。如果没有指定设备序号,则此对象始终代表当前设备类型中的默认设备;即使调用了torch.cuda.set_device(),也是如此。例如,使用'cuda' 构造的 torch.Tensor 等同于'cuda:X' ,其中 X 是torch.cuda.current_device() 的结果。

可以使用 Tensor.device 属性来访问 torch.Tensor 的设备。

可以使用字符串或结合字符串和设备序号来构造torch.device

使用字符串:

>>> 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')

通过字符串和设备顺序编号:

>>> 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)

device 对象还可以用作上下文管理器,以更改张量分配的默认设备。

>>> with torch.device('cuda:1'):
...     r = torch.randn(2, 3)
>>> r.device
device(type='cuda', index=1)

如果工厂函数传递了显式的非 None 设备参数,此上下文管理器将不会产生任何效果。要全局更改默认设备,请参见torch.set_default_device()

警告

此函数每次调用 Python 中的 torch API(不仅仅是工厂函数)时都会带来一定的性能开销。如果你遇到问题,请在 https://github.com/pytorch/pytorch/issues/92701 上留言。

注意

函数中的torch.device 参数通常可以替换为字符串。这样可以方便地进行代码的快速原型开发。

>>> # Example of a function that takes in a torch.device
>>> cuda1 = torch.device('cuda:1')
>>> torch.randn((2,3), device=cuda1)
>>> # You can substitute the torch.device with a string
>>> torch.randn((2,3), device='cuda:1')

注意

由于历史原因,可以通过单个设备序号来构造一个设备,这被视为当前的加速器类型。这与Tensor.get_device()方法相匹配,该方法返回设备张量的序号,并且不支持CPU张量。

>>> torch.device(1)
device(type='cuda', index=1)

注意

接受设备的方法通常可以接收一个格式正确的字符串或(legacy)整数设备序号,它们是等价的:

>>> 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,因为这种操作可以“免费”完成。示例:

>>> # 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
>>> # 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
>>> # 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

torch.layout

警告

torch.layout 类目前处于测试阶段,可能还会有所变动。

一个torch.layout 对象表示torch.Tensor 的内存布局。目前,我们支持torch.strided(稠密张量),并且对torch.sparse_coo(稀疏COO张量)提供Beta版支持。

torch.strided 表示密集张量,并且是最常用的内存布局。每个 strided 张量都有一个关联的 torch.Storage 用于存储其数据。这些张量提供多维、strided 的存储视图。步长是一个整数列表:第 k 个步长表示在 Tensor 第 k 维中从一个元素跳到下一个元素所需的内存跳跃大小。这一概念使得许多张量操作能够高效地进行。

示例:

>>> 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

torch.memory_format

类 torch.memory_format

一个 torch.memory_format 对象表示 torch.Tensor 将要分配其上的内存格式。

可能的值包括:

  • torch.contiguous_format: 张量分配在连续且不重叠的内存中,步长按降序排列。

  • 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

本页目录