深度学习笔记(8)——单机多卡分布式训练

深度学习笔记(8)——单机多卡分布式训练

由于chat GPT3.0的出现,开始研究大模型。而大模型需要使用大算力,故而在单卡的条件下训练模型很难快速高效完成训练,所以需要使用单机多卡并行的方式运行训练脚本,本文演示如何通过单机多卡DDP并行的方式微调完成下游任务。

1. 两种分布式训练方式

Pytorch 分布式目前只支持 Linux。实现程序并行主要有 DataParallel 和 DistributedDataParallel 两种方式:

DataParallel (DP):实现简单,代码量较少,启动速度快一点。但速度较慢,且存在负载不均衡的问题。单进程,多线程。主卡显存占用比其他卡会多很多。不支持 Apex 的混合精度训练。是Pytorch官方很久之前给的一种方案。受 Python GIL 的限制,DP的操作原理是将一个batchsize的输入数据均分到多个GPU上分别计算(此处注意,batchsize要大于GPU个数才能划分)。

DistributedDataParallel (DDP):All-Reduce模式,本意是用来分布式训练(多机多卡),但是也可用于单机多卡。配置稍复杂。多进程。数据分配较均衡。是新一代的多卡训练方法。使用 torch.distributed 库实现并行。torch.distributed 库提供分布式支持,包括 GPU 和 CPU 的分布式训练支持,该库提供了一种类似 MPI 的接口,用于跨多机器网络交换张量数据。它支持几种不同的后端和初始化方法。DDP通过Ring-Reduce的数据交换方法提高了通讯效率,并通过启动多个进程的方式减轻Python GIL的限制,从而提高训练速度。

2.多卡训练的原理

1.将模型在各个GPU上复制一份;
2.将总的 batch 数据等分到不同的GPU上进行计算(shuffle 顺序打乱),每个进程都从磁盘加载其自己的数据;
3. 在模型训练时,损失函数的前向传播和计算在每个 GPU 上独立执行,因此,不需要收集网络输出。在反向传播期间,各个进程通过一种叫 Ring-Reduce 的方法与其他进程通讯,交换各自的梯度,从而获得所有进程的平均梯度;然后用这个值在所有 GPU
上执行梯度下降,从而每个 GPU 在反向传播结束时最终得到平均梯度的相同副本;
4.各个进程用平均后的梯度更新自己的参数,因为各个进程的初始参数、更新梯度是一致的,所以更新后的参数也是完全相同的。

3.数据并行&模型并行

1 .数据并行是指,多张 GPUs 使用相同的模型副本,但采用同一batch中的不同数据进行训练。
2.模型并行是指,多张 GPUs 使用同一 batch 的数据,分别训练模型的不同部分。 简单来记就是:并行就是对并行对象进行拆分,以提高运算效率。

4. DDP代码操作步骤

1.引入必要的包

import torch.distributed as dist
import torch.multiprocessing as mp
from torch.cuda.amp import GradScaler
from torch.utils.data.distributed import DistributedSampler
from torch.nn.parallel import DistributedDataParallel as DDP

其中dist负责多线程通信,DDP负责模型传递工作。

2.初始化通信进程

在训练代码前面,使用nccl进行通信

dist.init_process_group(backend='nccl')

3.获取可用的gpu设备

local_rank 为自动获取到的可用gpu设备

local_rank = torch.distributed.get_rank()

4.设置gpu设备

torch.cuda.set_device(local_rank)
device = torch.device(f"cuda:{local_rank}"

5.使用DistributedSampler

train_loader = DataLoader(dataset=dataset,
                              batch_size=BATCH_SIZE, num_workers=num_workers, sampler=DistributedSampler(dataset))

6.模型放到多卡gpu设备上

model.to(device)
if torch.cuda.device_count() > 1:
    print("let's use", torch.cuda.device_count(), "gpus!")

7.封装模型

model = torch.nn.parallel.DistributedDataParallel(model,
                                                  device_ids=[local_rank],
                                                  find_unused_parameters=True,
                                                  output_device=local_rank)

8. 训练时,将数据放到device上

for steps, samples in enumerate(train_loader):
    optimizer.zero_grad()
    latent, codition = samples
    latent, codition = latent.to(device), codition.to(device)

5.启动方式

CUDA_VISIBLE_DEVICES=0,1,2,3 python -m torch.distributed.launch --nproc_per_node=4 main.py

在终端使用以上命令启动多卡训练,CUDA_VISIBLE_DEVICES是所用到的gpu设备0,1,2,3代表有四个卡,python -m torch.distributed.launch是torch.distributed 提供的启动工具,用于在每个单节点上启动多个分布式进程。其同时支持 Python2 和 Python 3。– nproc_per_node 参数用于指定为当前主机创建的进程数,由于我们现在说的是单机多卡,所以设为4, main.py是用于训练的脚本。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值