torch.distributed多卡/多GPU/分布式DPP(二)—torch.distributed.all_reduce(reduce_mean)barrier控制进程执行顺序seed随机种子
torch.distributed.all_reduce
实现的就是Ring-Reduce版本
跨卡汇总
torch.distributed.all_reduce(tensor, op=<ReduceOp.SUM: 0>, group=None, async_op=False)
举例
import torch import argparse import torch.distributed as dist from torch.distributed import ReduceOp # 新增1:从外面得到local_rank参数,在调用DDP的时候,其会自动给出这个参数 parser = argparse.ArgumentParser() parser.add_argument("--local_rank", default=-1, type=int) args = parser.parse_args()# 新增2:DDP backend初始化 # a.根据local_rank来设定当前使用哪块GPU torch.cuda.set_device(args.local_rank) # b.初始化DDP, nccl是GPU设备上最快、最推荐的后端.如果是CPU模型运行,需要选择其他后端。 dist.init_process_group(backend='nccl') world_size = torch.distributed.get_world_size() print('全局进程数: ', world_size)# 新增3:定义并把模型放置到单独的GPU上 device = torch.device("cuda", args.local_rank)tensor = (torch.arange(world_size, dtype=torch.int64) + 1 + world_size * args.local_rank).to(device) print(tensor)dist.all_reduce(tensor, op=ReduceOp.SUM) print(tensor)
python -m torch.distributed.launch \--nproc_per_node 2 \main.py
4 = 3+1
6 = 4+2
如果是求均值的话(reduce_mean)
dist.all_reduce(value) if average:value /= world_size
torch.distributed.
barrier DDP各个进程同步
torch.distributed
提供了一个barrier()
的接口,利用它我们可以同步各个DDP中的各个进程!当使用barrier函数时,DDP进程会在函数的位置进行等待,知道所有的进程都跑到了 barrier函数的位置,它们才会再次向下执行。torch.distributed.barrier(group=None, async_op=False, device_ids=None)
用
torch.distributed.
barrier控制DDP不同进程的执行顺序
一般情况下,各个进程是各自执行的,速度有快有慢,只有在gradient all-reduce的时候,快的进程才会等一下慢的进程,也就是进行同步
在某个进程中执行A操作,其他进程等待其执行完成后再执行B操作
if rank == 0:do_A()torch.distributed.barrier() else:torch.distributed.barrier()do_B()
在加载数据前,如果数据集不存在,我们要下载数据集
- 我们只需要在唯一一个进程中开启一次下载
- 我们需要让其他进程等待其下载完成,再去加载数据
怎么解决这个问题呢?
torch.distributed
提供了一个barrier()
的接口,利用它我们可以同步各个DDP中的各个进程!当使用barrier函数时,DDP进程会在函数的位置进行等待,知道所有的进程都跑到了 barrier函数的位置,它们才会再次向下执行。在某个进程中优先执行A操作,其他进程等待其执行完成后再执行A操作
这个值得深入讲一下,因为这个是非常普遍的需求。利用
contextlib.contextmanager
,我们可以把这个逻辑给优雅地包装起来!from contextlib import contextmanager@contextmanager def torch_distributed_zero_first(rank: int):"""Decorator to make all processes in distributed training wait for each local_master to do something."""if rank not in [-1, 0]:torch.distributed.barrier()# 这里的用法其实就是协程的一种哦。yieldif rank == 0:torch.distributed.barrier()
然后我们就可以这样骚操作:
with torch_distributed_zero_first(rank):if not check_if_dataset_exist():download_dataset()load_dataset()
给不同的进程分配不同的、固定的随机数种子seed
为保证实验的可复现性,一般我们会在代码在开头声明一个固定的随机数种子,从而使得同一个配置下的实验,无论启动多少次,都会拿到同样的结果。
import random import numpy as np import torchdef init_seeds(seed=0, cuda_deterministic=True):random.seed(seed)np.random.seed(seed)torch.manual_seed(seed)# Speed-reproducibility tradeoff https://pytorch.org/docs/stable/notes/randomness.htmlif cuda_deterministic: # slower, more reproduciblecudnn.deterministic = Truecudnn.benchmark = Falseelse: # faster, less reproduciblecudnn.deterministic = Falsecudnn.benchmark = Truedef main():# 一般都直接用0作为固定的随机数种子。init_seeds(0)
但是在DDP训练中,如果还是像以前一样,使用0作为随机数种子,不做修改,就会造成以下后果:
- DDP的N个进程都使用同一个随机数种子
- 在生成数据时,如果我们使用了一些随机过程的数据扩充方法,那么,各个进程生成的数据会带有一定的同态性。
- 比如说,YOLOv5会使用mosaic数据增强(从数据集中随机采样3张图像与当前的拼在一起,组成一张里面有4张小图的大图)。这样,因为各卡使用了相同的随机数种子,你会发现,各卡生成的图像中,除了原本的那张小图,其他三张小图都是一模一样的!
- 同态性的数据,降低了训练数据的质量,也就降低了训练效率!最终得到的模型性能,很有可能是比原来更低的。
所以,我们需要给不同的进程分配不同的、固定的随机数种子:
def main():rank = torch.distributed.get_rank()# 问题完美解决!init_seeds(1 + rank)
torch.distributed多卡/多GPU/分布式DPP(二)—torch.distributed.all_reduce(reduce_mean)barrier控制进程执行顺序seed随机种子相关推荐
- PyTorch多卡/多GPU/分布式DPP的基本概念(noderanklocal_ranknnodesnode_ranknproc_per_nodeworld_size)
node 物理节点,就是一台机器,节点内部可以有多个GPU(一台机器有多卡). rank & local_rank 用于表示进程的序号,用于进程间通信.每一个进程对应了一个rank. rank ...
- Pytorch分布式训练/多卡训练(二) —— Data Parallel并行(DDP)(2.2)(代码示例)(BN同步主卡保存梯度累加多卡测试inference随机种子seed)
DDP的使用非常简单,因为它不需要修改你网络的配置.其精髓只有一句话 model = DistributedDataPrallel(model, device_ids=[local_rank], ou ...
- pytorch GPU分布式训练 单机单卡、单机多卡
可以用"watch -n 0.1 nvidia-smi"来查看gpu状态,我用的是3块12G的GPU进行实验 本实验将使用一个简单的瞎写的网络进行,网络训练一个分类任务,当然这个不 ...
- gpu处理信号_在PyTorch中使用DistributedDataParallel进行多GPU分布式模型训练
先进的深度学习模型参数正以指数级速度增长:去年的GPT-2有大约7.5亿个参数,今年的GPT-3有1750亿个参数.虽然GPT是一个比较极端的例子但是各种SOTA模型正在推动越来越大的模型进入生产应用 ...
- PyTorch 多机多卡训练:分布式实战与技巧
向AI转型的程序员都关注了这个号???????????? 机器学习AI算法工程 公众号:datayx DistributedDataParallel(DDP)是一个支持多机多卡.分布式训练的深度学 ...
- Pytorch 分布式DPP 基本概念
Reference PyTorch分布式DPP涉及的基本概念与问题(强烈推荐) GO 防喷指南,小小学生,啥也不会,欢迎指出错误. 1. 分布式参数解释 rank:用于表示在整个分布式任务中进程的序号 ...
- Pytorch:多块GPU分布式|并行训练
分布式与并行训练的区别 分布式: 多台服务器上的多个GPU,分布式涉及了服务器之间的通信,因此比较复杂,PyTorch封装了相应的接口,可以用几句简单的代码实现分布式训练. 并行: 一台服务器上的多个 ...
- torch.nn.DataParallel()--多个GPU加速训练
公司配备多卡的GPU服务器,当我们在上面跑程序的时候,当迭代次数或者epoch足够大的时候,我们通常会使用nn.DataParallel函数来用多个GPU来加速训练.一般我们会在代码中加入以下这句: ...
- 在线GPU分布式实验环境+企业级项目,轻松斩获offer
前 言 开课吧AI学院在前四期具有求职意向的同学中,已经有80%的同学拿到了国内外名企的AI算法岗位offer,或者国外名校的AI 硕士.全奖博士录取 offer. 在大家的认可下,我们对课程做了全面 ...
- spark学习笔记:弹性分布式数据集RDD(Resilient Distributed Dataset)
弹性分布式数据集RDD 1. RDD概述 1.1 什么是RDD RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象,它代表一个不可 ...
最新文章
- 【php】(转载)分享一个好用的php违禁词 处理类
- Java多线程编程模式实战指南(三):Two-phase Termination模式--转载
- mysql 5.7.20主从配置_mysql5.7.20免安装版配置方法图文教程
- cmds在线重定义增加列
- jeewx-api-1.0.1(捷微微信接口API)版本正式发布
- 备份恢复,DBA最后一道防线,你完全掌握了吗?
- numpy.core.defchararray.join
- Puppet Master安裝手冊(CentOS 7)
- 清除vlan.dat文件
- SQL中char、varchar、nvarchar的区别
- 想学PHP来兄弟连是正确的选择 初识兄弟连三周
- java svg to png_如何用Image Magick将SVG转换为PNG?
- 【网络编程】同步、异步、阻塞和非阻塞
- oracle 自定义分词器,自定义分词器和自定义词典
- Android 84、gc、高德、百度、墨卡托地理坐标转换
- Linux下显示IP地理位置信息的工具-nali
- 帝国CMS二次开发 – 使用程序本身的SQL类
- 隐私计算头条周刊(7.31-8.6)
- 语音信号的基音参数提取
- jira7.2安装、中文及破解