文章目录
GPU的使用
1、CPU与GPU
CPU(Central Processing Unit, 中央处理器):主要包括控制器和运算器
GPU(Graphics Processing Unit, 图形处理器):处理统一的,无依赖的大规模数据运算
从上面的图可以看出,GPU的ALU(算术运算单元)比CPU多,而CPU中的缓存区多,用于加速程序的运行,两者适用于不同的任务,计算密集型的程序和易于并行的程序通常在GPU上完成
2、数据迁移至GPU
Pytorch
中提供了.to()
方法,用于数据在CPU和GPU之间的来回切换,这里的数据通常之两类:Tensor和Module
(1).to()
函数:转换数据类型或设备
x = torch.ones((3, 3))
x = x.to(torch.float64)
x = torch.ones((3, 3))
x = x.to("cuda")
linear = nn.Linear(2, 2)
linear.to(torch.double)
gpu1 = torch.device("cuda")
linear.to(gpu1)
- 两种方式:
tensor.to(*args, **kwargs)
module.to(*args, **kwargs)
区别在于张量不执行inplace而模型执行inplace
x_cpu = torch.ones((3, 3))
print("x_cpu:\ndevice: {} is_cuda: {} id: {}".format(x_cpu.device, x_cpu.is_cuda, id(x_cpu)))
x_gpu = x_cpu.to(device)
print("x_gpu:\ndevice: {} is_cuda: {} id: {}".format(x_gpu.device, x_gpu.is_cuda, id(x_gpu)))
# x_cpu:
# device: cpu is_cuda: False id: 140006701225376
# x_gpu:
# device: cuda:0 is_cuda: True id: 140005221392624
# ==================================================== #
net = nn.Sequential(nn.Linear(3, 3))
print("\nid:{} is_cuda: {}".format(id(net), next(net.parameters()).is_cuda))
net.to(device)
print("\nid:{} is_cuda: {}".format(id(net), next(net.parameters()).is_cuda))
# id:140378336669136 is_cuda: False
#
# id:140378336669136 is_cuda: True
#
# Process finished with exit code 0
(2)torch.cuda
模块
- 常用方法:
torch.cuda.device_count()
:计算当前可见可用GPU数torch.cuda.get_device_name()
:获取GPU名称torch.cuda.manual_seed()
:为当前GPU设置随机种子torch.cuda.manual_seed_all()
:为所有可见可用GPU设置随机种子torch.cuda.set_device()
:设置主GPU为哪一个物理GPU(不推荐),推荐os.environ.setdefault("CUDA_VISIBLE_DEVICES", "2, 3")
这种方式
current_device = torch.cuda.current_device()
print("current_device: ", current_device)
torch.cuda.set_device(0)
current_device = torch.cuda.current_device()
print("current_device: ", current_device)
#
cap = torch.cuda.get_device_capability(device=None)
print(cap)
#
name = torch.cuda.get_device_name()
print(name)
is_available = torch.cuda.is_available()
print(is_available)
# ===================== seed
seed = 2
torch.cuda.manual_seed(seed)
torch.cuda.manual_seed_all(seed)
current_seed = torch.cuda.initial_seed()
print(current_seed)
# current_device: 0
# current_device: 0
# (6, 1)
# Quadro
# P2000
# True
# 2
3、多GPU并行运算
(1)多GPU运算的分发并行机制
通常而言,多GPU的并行运算有三个步骤:
- 分发:由主GPU分发数据到各GPU
- 并行运算:各GPU分别进行运算
- 结果回收:各GPU将运算得到的结果发回主GPU
(2)PyTorch
实现
Pytorch
中的多GPU运算的分发并行机制由torch.nn.DataParallel
实现
class DataParallel(Module):
def __init__(self, module, device_ids=None, output_device=None, dim=0):
super(DataParallel, self).__init__()
- 功能:包装模型,实现分发并行机制
- 参数:
module
:需要包装分发的模型device_ids
:可分发的GPU,默认分发到所有可见可用GPUoutput_device
:结果输出设备