pytorch模型加DDP进行单机多卡分布式训练

1.接收local_rank的参数

不要自己替换--local_rank的数值

如果有import导入dataloader,init的代码必须要在dataloader之前。

import argparse
# 运行时,torch.distributed.lunch 会自动传入参数0,1,2来表示是第几个进程
parser = argparse.ArgumentParser()
parser.add_argument('--local_rank', type=int, default=-1, help="DDP parameter, do not modify")
args = parser.parse_args()

## 上面代码也可替换成
local_rank = int(os.environ['LOCAL_RANK'])
world_size = int(os.environ['WORLD_SIZE'])
rank = int(os.environ['RANK'])



## Initialization
torch.distributed.init_process_group(backend="nccl" )
torch.cuda.set_device(args.local_rank)

1.1 设置随机数种子,使模型初始化时都是一样的参数

torch.manual_seed(0)
torch.cuda.manual_seed_all(0)

2.模型上:

## 套DDP的时候,model要加.cuda()
model = torch.nn.parallel.DistributedDataParallel(model.cuda(), device_ids=[args.local_rank], output_device=args.local_rank,find_unused_parameters=True)
## 加broadcast_buffers会让loss同步,速度会稍微变慢

3.DataLoader导入数据上:

​
## 对DataLoader中的database进行一个sampler,再在最后加一个sampler=train_sampler即可
train_sampler = torch.utils.data.distributed.DistributedSampler(traindatabase)
trainLoader = torch.utils.data.DataLoader(traindatabase, batch_size=args.batch_size, shuffle = (train_sampler is None), sampler=train_sampler, pin_memory=False)

​
## pin_memory 为 True时,允许在训练的时候提前加载数据,理论上可以提升GPU利用率

3.1 每个epoch中:

for epoch in range(30):
    train_sampler.set_epoch(epoch)
    train(model,xxxxxx)
    xxxxxxx

4. loss上:

默认loss.backward()会等待其他进程的同步。 实验中当设定local_rank == 1的时候sleep,就能看到其他进程不打印了

下面代码能强制保证不同GPU之间的loss是同步的(!!)

在loss.backward()后面:


loss.backward()
## 等待所有进程到这个位置
dist.barrier()   # import torch.distributed as dist
  


## 或者使用:  (还可以计算平均loss)
loss.backward()
world_size = dist.get_world_size()
with torch.no_grad():
    d = dist.all_reduce(loss, async_op=True)
    d.wait()
	loss /= world_size

5:运行代码

## 改成nproc_per_node的值改成GPU数量
python -m torch.distributed.launch --nproc_per_node=2 main.py

6.要使用特定的GPU,在运行的最前面加

CUDA_VISIBLE_DEVICES=3,4 python -m xxxxxxxx

或者在python内开头加

os.environ['CUDA_VISIBLE_DEVICES'] = '3,4'

测试结果:

(1)运行速度: 提升进两倍

(2)精度基本上无变化

注意事项:

        1.在model之外,在任何地方都是默认等待其他进程同步的,

           而在model内的函数操作是不会等待的。(可以利用barrier()或者.wait())

2. 输入model的data和labels,在dataloader之后在CPU上,一输入model居然自己变成了对应的GPU上

参考:

Pytorch并行分布式训练四 (DDP)_Dteam_f的博客-CSDN博客

pytorch分布式系列3——分布式训练时,torch.utils.data.distributed.DistributedSampler做了什么?_searobbers_duck的博客-CSDN博客

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值