深度学习框架 Pytorch 深入学习(6):GPU 加速:CUDA 的使用
Pytorch 搭建神经网络(6)GPU 加速:CUDA 的使用
笔记和代码存储在我的 GitHub 库中 github.com/isKage/pytorch-notes
使用 GPU 加速技术,可以大幅减少训练时间。Pytorch 中的 Tensor
张量和 nn.Module
类就分为 CPU 和 GPU 两种版本。一般使用 .cuda()
和 .to(device)
方法实现从 CPU 迁移到 GPU ,从设备迁移到设备。
但
Tensor
和nn.Module
使用.cuda()
方法时返回的对象不同。
Tensor.cuda()
返回一个新对象,即拷贝了一份张量到 GPU ,之前的张量仍然储存在 CPUnn.Module
实例化后的module
使用module.cuda()
直接将所有数据推送到 GPU 不备份自己,即module.cuda()
与module = module.cuda()
等价
.to(device)
可以更灵活地在不同设备上迁移
1 .cuda() 方法
1.1 张量 .cuda() 返回新的对象
1 | import torch |
1 | [Out]: False |
.cuda()
等价于.cuda(0)
or.cuda(device=0)
迁移到第 0 块 GPU 上
1.2 module.cuda() 返回自己
1 | from torch import nn |
1 | [Out]: True |
迁移到 GPU 本质都是对张量 Tensor 做变换,所以对于模型 module ,也是其权重等参数进行迁移
2 .to(device) 方法
.to(device)
方法可以指定设备
1 | # 使用.to方法,将 Tensor 转移至第 0 块GPU上 |
1 | [Out]: True |
3 损失函数迁移到 GPU
大部分的损失函数都属于 nn.Module
,在使用 GPU 时,建议使用 .cuda
或 .to
迁移到 GPU 。
1 | if torch.cuda.is_available(): |
1 | [Out]: OrderedDict([('weight', tensor([1., 3.], device='cuda:0'))]) |
4 torch.cuda.device() 指定默认设备
使用 torch.cuda.device()
指定默认设备,则不需要每次调用 .cuda
或 .to
方法。
1 | # 指定默认使用GPU "cuda:0" |
1 | <built-in method get_device of Tensor object at 0x0000019C70C59CC0> |
或者使用 torch.set_default_tensor_type()
方法,指定张量类型
1 | torch.set_default_tensor_type('torch.cuda.FloatTensor') # 指定默认 Tensor 的类型为GPU上的FloatTensor |
5 多 GPU 操作
多个 GPU 方便快捷地指定迁移设备。
5.1 方法一:调用 torch.cuda.set_device()
例如:指定先调用 torch.cuda.set_device(1)
指定默认使用 GPU “cuda:1” ,后续的 .cuda()
都无需更改,切换 GPU 只需修改这一行代码
5.2 方法二:设置环境变量 CUDA_VISIBLE_DEVICES
例如当 CUDA_VISIBLE_DEVICE=1
时,代表优先使用 GPU “cuda:1” 而不是 GPU “cuda:0” 。此时调用tensor.cuda()
会将Tensor转移至 GPU “cuda:1”
CUDA_VISIBLE_DEVICES
还可以指定多个 GPU 。例如 CUDA_VISIBLE_DEVICES=0,2,3
代表按照 GPU “cuda:0”, “cuda:2”, “cuda:3” 的顺序使用 GPU 。此时 cuda(0)
迁移到 GPU “cuda:0” ,而 .cuda(1)
迁移到 GPU “cuda:2” ,.cuda(2)
迁移到 GPU “cuda:3” 。
5.3 设置 CUDA_VISIBLE_DEVICES
的方法:
- 法一:命令行中执行
CUDA_VISIBLE_DEVICES=0,1 python main.py
来运行主程序 - 法二:程序中编写
1
2import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0,1' - 法三:IPython 或者 Jupyter notebook 中(即
.ipynb
文件),则可以使用魔法方法1
%env CUDA_VISIBLE_DEVICES=0,1
6 CPU 与 GPU 并存
考虑到不同电脑可能会有差异,例如当遇到无 GPU 的主机时,容易出现不兼容。(例如:无法迁移到 GPU),所以建议判断是否存在 GPU ,再迁移数据。
1 | # 【推荐】如果用户具有 GPU 设备,那么使用GPU,否则使用CPU |
确定了设备之后,再迁移
1 | x = torch.randn(2, 3) |
7 张量指定设备
7.1 创建张量时指定设备
1 | device = torch.device("cuda" if torch.cuda.is_available() else "cpu") |
7.2 new_* 保留原属性
1 | # new_*() : 保留原 Tensor 的设备属性 |
7.3 *_like 保留原属性
1 | # 使用ones_like或zeros_like可以创建与原Tensor大小类别均相同的新Tensor |