PyTorch张量的最后一点是关于在GPU上计算。每一个Torch张量都可以转移到GPU上去执行快速、大规模并且可以并行的计算。在张量上执行的所有操作均由PyTorch自带的GPU特定例程执行。
请注意: 截止至2019年初,主要的PyTorch版本仅仅在支持CUDA的GPU上具有加速功能。PyTorch的概念验证版本(Proof-of-concept version)已经可以运行在AMD的ROCm平台上,但是从1.0版开始,尚未将全部支持合并到PyTorch中。对Google TPU的支持正在进行开发中,目前的概念验证版已在Google Colab中向公众公开。在我们写这章的时候,并未计划在其他GPU技术(例如OpenCL)上实现相应的数据结构和内核。
除了dtype
之外,PyTorch张量还具有设备(device
)的概念,这是在设置计算机上放张量(tensor)数据的位置。 通过为构造函数指定相应的参数,可以在GPU上创建张量:
points_gpu = torch.tensor([[1.0, 4.0], [2.0, 1.0], [3.0, 4.0]], device='cuda')
你可以使用to
方法将在CPU上创建的张量(tensor)复制到GPU:
points_gpu = points.to(device='cuda')
这段代码返回一个具有相同数值数据的新张量,但存储在GPU的RAM中,而不是常规的系统RAM中。
现在数据已经存放在本地的GPU中,当在张量上运行数字运算时,你可以看见很好的加速效果。并且,这个新GPU支持的张量的类也更改为torch.cuda.FloatTensor
(一开始输入的类型为torch.FloatTensor
;torch.cuda.DoubleTensor
等等也存在对应关系)。在大部分样例中,基于CPU和GPU的张量都公开面向用户相同的API,这使得与繁琐数字运算过程中无关的代码的编写更加容易。
如果你的机器拥有多个GPU,你可以通过传递从零开始的整数来确定张量分配给哪个GPU,该整数标志着机器上的GPU下标:
points_gpu = points.to(device='cuda:0')
此时,在GPU上执行对张量的任何操作,例如将所有元素乘以一个常数。
points = 2 * points # 在CPU上做乘法
points_gpu = 2 * points.to(device='cuda') # 在GPU上做乘法
请注意,当计算结果产生后,points_gpu
的张量并不会返回到CPU。这里发生的是以下三个过程:
- 将
points
张量复制到GPU - 在GPU上分配了一个新的张量,并用于存储乘法的结果
- 返回该GPU张量的句柄
因此,如果你还想向结果加上一个常量:
points_gpu = points_gpu + 4
加法仍然在GPU上执行,并且没有信息流到CPU(除非您打印或访问得到的张量)。 如果要将张量移回CPU,你需要为to
方法提供一个cpu参数:
points_cpu = points_gpu.to(device='cpu')
你可以使用速记方法cpu
和cuda
代替to
方法来实现相同的目标
points_gpu = points.cuda() # 默认为GPU0
points_gpu = points.cuda(0)
points_cpu = points_gpu.cpu()
值得一提的是,使用to
方法时,可以通过提供device
和dtype
参数来同时更改位置和数据类型。