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()

在加载数据前,如果数据集不存在,我们要下载数据集

  1. 我们只需要在唯一一个进程中开启一次下载
  2. 我们需要让其他进程等待其下载完成,再去加载数据

怎么解决这个问题呢?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作为随机数种子,不做修改,就会造成以下后果:

  1. DDP的N个进程都使用同一个随机数种子
  2. 在生成数据时,如果我们使用了一些随机过程的数据扩充方法,那么,各个进程生成的数据会带有一定的同态性。
    1. 比如说,YOLOv5会使用mosaic数据增强(从数据集中随机采样3张图像与当前的拼在一起,组成一张里面有4张小图的大图)。这样,因为各卡使用了相同的随机数种子,你会发现,各卡生成的图像中,除了原本的那张小图,其他三张小图都是一模一样的!
  3. 同态性的数据,降低了训练数据的质量,也就降低了训练效率!最终得到的模型性能,很有可能是比原来更低的。

所以,我们需要给不同的进程分配不同的、固定的随机数种子:

def main():rank = torch.distributed.get_rank()# 问题完美解决!init_seeds(1 + rank)

torch.distributed多卡/多GPU/分布式DPP(二)—torch.distributed.all_reduce(reduce_mean)barrier控制进程执行顺序seed随机种子相关推荐

  1. PyTorch多卡/多GPU/分布式DPP的基本概念(noderanklocal_ranknnodesnode_ranknproc_per_nodeworld_size)

    node 物理节点,就是一台机器,节点内部可以有多个GPU(一台机器有多卡). rank & local_rank 用于表示进程的序号,用于进程间通信.每一个进程对应了一个rank. rank ...

  2. Pytorch分布式训练/多卡训练(二) —— Data Parallel并行(DDP)(2.2)(代码示例)(BN同步主卡保存梯度累加多卡测试inference随机种子seed)

    DDP的使用非常简单,因为它不需要修改你网络的配置.其精髓只有一句话 model = DistributedDataPrallel(model, device_ids=[local_rank], ou ...

  3. pytorch GPU分布式训练 单机单卡、单机多卡

    可以用"watch -n 0.1 nvidia-smi"来查看gpu状态,我用的是3块12G的GPU进行实验 本实验将使用一个简单的瞎写的网络进行,网络训练一个分类任务,当然这个不 ...

  4. gpu处理信号_在PyTorch中使用DistributedDataParallel进行多GPU分布式模型训练

    先进的深度学习模型参数正以指数级速度增长:去年的GPT-2有大约7.5亿个参数,今年的GPT-3有1750亿个参数.虽然GPT是一个比较极端的例子但是各种SOTA模型正在推动越来越大的模型进入生产应用 ...

  5. PyTorch 多机多卡训练:分布式实战与技巧

    向AI转型的程序员都关注了这个号???????????? 机器学习AI算法工程   公众号:datayx DistributedDataParallel(DDP)是一个支持多机多卡.分布式训练的深度学 ...

  6. Pytorch 分布式DPP 基本概念

    Reference PyTorch分布式DPP涉及的基本概念与问题(强烈推荐) GO 防喷指南,小小学生,啥也不会,欢迎指出错误. 1. 分布式参数解释 rank:用于表示在整个分布式任务中进程的序号 ...

  7. Pytorch:多块GPU分布式|并行训练

    分布式与并行训练的区别 分布式: 多台服务器上的多个GPU,分布式涉及了服务器之间的通信,因此比较复杂,PyTorch封装了相应的接口,可以用几句简单的代码实现分布式训练. 并行: 一台服务器上的多个 ...

  8. torch.nn.DataParallel()--多个GPU加速训练

    公司配备多卡的GPU服务器,当我们在上面跑程序的时候,当迭代次数或者epoch足够大的时候,我们通常会使用nn.DataParallel函数来用多个GPU来加速训练.一般我们会在代码中加入以下这句: ...

  9. 在线GPU分布式实验环境+企业级项目,轻松斩获offer

    前 言 开课吧AI学院在前四期具有求职意向的同学中,已经有80%的同学拿到了国内外名企的AI算法岗位offer,或者国外名校的AI 硕士.全奖博士录取 offer. 在大家的认可下,我们对课程做了全面 ...

  10. spark学习笔记:弹性分布式数据集RDD(Resilient Distributed Dataset)

    弹性分布式数据集RDD 1. RDD概述 1.1 什么是RDD RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象,它代表一个不可 ...

最新文章

  1. 【php】(转载)分享一个好用的php违禁词 处理类
  2. Java多线程编程模式实战指南(三):Two-phase Termination模式--转载
  3. mysql 5.7.20主从配置_mysql5.7.20免安装版配置方法图文教程
  4. cmds在线重定义增加列
  5. jeewx-api-1.0.1(捷微微信接口API)版本正式发布
  6. 备份恢复,DBA最后一道防线,你完全掌握了吗?
  7. numpy.core.defchararray.join
  8. Puppet Master安裝手冊(CentOS 7)
  9. 清除vlan.dat文件
  10. SQL中char、varchar、nvarchar的区别
  11. 想学PHP来兄弟连是正确的选择 初识兄弟连三周
  12. java svg to png_如何用Image Magick将SVG转换为PNG?
  13. 【网络编程】同步、异步、阻塞和非阻塞
  14. oracle 自定义分词器,自定义分词器和自定义词典
  15. Android 84、gc、高德、百度、墨卡托地理坐标转换
  16. Linux下显示IP地理位置信息的工具-nali
  17. 帝国CMS二次开发 – 使用程序本身的SQL类
  18. 隐私计算头条周刊(7.31-8.6)
  19. 语音信号的基音参数提取
  20. jira7.2安装、中文及破解

热门文章

  1. sip信令跟踪工具sngrep
  2. 哈工大在CoNLL上斩获全球第四,车万翔博士详解背后的技术细节
  3. 函数的基本用法c语言,C语言(函数基本用法).ppt
  4. 奋斗5年,从月薪3500到700万(不止谈赚钱,故事也很感人)
  5. FCM算法研究(一)
  6. 【毕业设计】 基于STM32的人体红外测温枪温度采集系统
  7. 本地传奇架设详细教程
  8. 计算机网络与信息安全公务员,计算机网络技术专业考公务员有些职位?
  9. VLAN 划分——基于交换机端口划分VLAN
  10. 计算机网路vlan划分练习