【深度学习实战(27)】「分布式训练」DDP单机多卡并行指南

news2024/10/7 10:18:02

一、DDP实现流程

(1)初始化进程
(2)model并行
(3)BN并行
(4)data并行
(5)进程同步

二、DDP代码实现

(1)初始化进程
#-------------- 初始化进程,设置用到的显卡 -----------------#
ngpus_per_node = torch.cuda.device_count()
if distributed:
    dist.init_process_group(backend="nccl")
    local_rank = int(os.environ["LOCAL_RANK"])
    rank = int(os.environ["RANK"])
    device = torch.device("cuda", local_rank)
    if local_rank == 0:
        print(f"[{os.getpid()}] (rank = {rank}, local_rank = {local_rank}) training...")
        print("Gpu Device Count : ", ngpus_per_node)
    else:
        device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
        local_rank = 0
        rank = 0

概念说明:
RANK: 使用os.environ[“RANK”]获取进程的序号,一般1GPU对应一个进程。它是一个全局的序号,从0开始,最大值为GPU数量-1。一般单机多卡的情况要比多机多卡的情况常见的多,单机多卡时,rank就等于local_rank
LOCAL_RANK:使用os.environ[“LOCAL_RANK”]获取每个进程在所在主机中的序号。从0开始,最大值为当前进程所在主机的GPU的数量-1
WORLD_SIZE:使用os.environ[“world_size”]获取当前启动的所有的进程的数量(所有机器进程的和),一般world_size = gpus_per_node * nnodes
每个node包含16GPU,且nproc_per_node=8nnodes=3,机器的node_rank=5,请问world_size是多少? 答案:world_size = 3*8 = 24
看下图比较方便理解:
在这里插入图片描述

在分布式训练中,RANKLOCAL_RANKWORLD_SIZE这三个环境变量通常需要在所有进程中保持一致,并且需要在初始化分布式训练环境时设置。例如,在 PyTorch 中,可以使用 torch.distributed.init_process_group() 函数来初始化分布式训练环境,并自动设置RANKLOCAL_RANKWORLD_SIZE这三个环境变量。

(2)模型并行
# -------------- 模型并行 --------------#
if Cuda:
    if distributed:
        model_train = model_train.cuda(local_rank)
        model_train = torch.nn.parallel.DistributedDataParallel(model_train, device_ids=[local_rank],find_unused_parameters=find_unused_parameters)
    else:
        model_train = torch.nn.DataParallel(model)
        cudnn.benchmark = True
        model_train = model_train.cuda()

nn.parallel.DistributedDataParallel函数接口中,find_unused_parameters: 如果模型的输出有不需要进行反向传播的,此参数需要设置为True;如果你的模型结构有有冗余的没有参加反向传播的参数,而find_unused_parameters设置为False,在训练过程中就会报错。

(3)BN并行
# -------------- 多卡同步Bn --------------#
if sync_bn and ngpus_per_node > 1 and distributed:
    model_train = torch.nn.SyncBatchNorm.convert_sync_batchnorm(model)
elif sync_bn:
    print("Sync_bn is not support in one gpu or not distributed.")

前向传播期间,损失函数的计算在每个 GPU 上独立执行,因此无需收集网络输出。
反向传播期间,各进程通过一种 ALL-ReduceAllGather 的方法与其他进程通讯,交换各自的梯度,均值和方差,从而获得所有GPU上的平均梯度,全局的均值和方差,同时更新 running_meanrunning_var
各进程使用平均梯度在所有 GPU 上执行梯度下降,更新自己的参数。因为各个进程的初始参数、更新梯度一致,所以更新后的参数完全相同。

在这里插入图片描述

在这里插入图片描述

(4)数据并行
# -------------- 数据并行 --------------#
if distributed:
    train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset, shuffle=True, )
    val_sampler = torch.utils.data.distributed.DistributedSampler(val_dataset, shuffle=False, )
    batch_size = batch_size // ngpus_per_node
    shuffle = False
else:
    train_sampler = None
    val_sampler = None
    shuffle = True


# -------------- 训练每进行一轮,都需要调用 train.sampler.set_epoch --------------#
if args.distributed:
    train_sampler.set_epoch(epoch)

看下面这张图可以很好理解utils.data.distributed.DistributedSampler
在这里插入图片描述

(5)进程同步
#----------- 训练 -----------#
num_update = 0
for epoch in range(Init_epoch, Total_epoch):
    for iter in range(epoch_step):
        pass

#----------- 验证 -----------#
for epoch in range(Init_epoch, Total_epoch):
    for iter in range(epoch_step):
        pass

#----------- 进程同步 -----------#
if distributed:
    dist.barrier()

dist.barrier()是一个同步操作,用于在分布式训练中进行进程间的同步。
当调用dist.barrier()时,当前进程会被阻塞,直到所有参与分布式训练的进程都调用了dist.barrier(),才会继续执行后续的代码。
这个同步操作的目的是确保所有进程都达到了同一个同步点,以便进行下一步的操作。在分布式训练中,可能会有一些需要所有进程都完成的操作,例如数据的收集、模型的更新等。通过使用dist.barrier()进行同步,可以保证所有进程在同一时间点上进行下一步操作,避免数据不一致或竞争条件的发生。
在给定的代码中,dist.barrier()被用于确保所有进程都已经写入了各自的部分结果,以便后续的合并操作可以顺利进行。在调用dist.barrier()之前和之后,分别进行了部分结果的保存和读取操作,通过同步操作可以保证这些操作在所有进程都完成之后再进行。

三、DDP完整训练框架

import torch
import torch.nn as nn
from torchvision import models
import matplotlib.pyplot as plt
import torch.distributed as dist
import os
import torch.backends.cudnn as cudnn

# -------------- DDP相关参数 --------------#
distributed=True
sync_bn = True
Cuda = True
find_unused_parameters=False

num_train_data = 100
batch_size = 10
epoch_step = num_train_data // batch_size

Init_epoch = 50
Total_epoch = 300

#---------- 搭建DDP训练框架 ------------#

#---------- model ------------#
model = models.AlexNet()
model = model.train()

#-------------- 初始化进程,设置用到的显卡 -----------------#
ngpus_per_node = torch.cuda.device_count()
if distributed:
    dist.init_process_group(backend="nccl")
    local_rank = int(os.environ["LOCAL_RANK"])
    rank = int(os.environ["RANK"])
    device = torch.device("cuda", local_rank)
    if local_rank == 0:
        print(f"[{os.getpid()}] (rank = {rank}, local_rank = {local_rank}) training...")
        print("Gpu Device Count : ", ngpus_per_node)
    else:
        device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
        local_rank = 0
        rank = 0

# -------------- 多卡同步Bn --------------#
if sync_bn and ngpus_per_node > 1 and distributed:
    model_train = torch.nn.SyncBatchNorm.convert_sync_batchnorm(model)
elif sync_bn:
    print("Sync_bn is not support in one gpu or not distributed.")

# -------------- 数据并行 --------------#
if Cuda:
    if distributed:
        model_train = model_train.cuda(local_rank)
        model_train = torch.nn.parallel.DistributedDataParallel(model_train, device_ids=[local_rank],find_unused_parameters=find_unused_parameters)
    else:
        model_train = torch.nn.DataParallel(model)
        cudnn.benchmark = True
        model_train = model_train.cuda()

# -------------- 数据分配 --------------#
if distributed:
    train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset, shuffle=True, )
    val_sampler = torch.utils.data.distributed.DistributedSampler(val_dataset, shuffle=False, )
    batch_size = batch_size // ngpus_per_node
    shuffle = False
else:
    train_sampler = None
    train_sampler_no_aug = None
    val_sampler = None
    shuffle = True


    


num_update = 0
for epoch in range(Init_epoch, Total_epoch):
    #----------- 一轮训练和验证 -----------#
    # -------------- train.sampler.set_epoch --------------#
    if args.distributed:
        train_sampler.set_epoch(epoch)
    for iter in range(train_epoch_step):
        pass
    for iter in range(val_epoch_step):
        pass


#----------- 进程同步 -----------#
if distributed:
    dist.barrier()

四、DDP启动指令

CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 torchrun --nproc_per_node=2 --master_port='29501' train.py 

-CUDA_VISIBLE_DEVICES:指定使用哪几块GPU
-nproc_per_node :每台机器中运行几个进程
-master_port0号机器的可用端口

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1646729.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vivado Virtex 和 Kintex UltraScale+ 比特流设置

下表所示 Virtex 和 Kintex UltraScale 器件的器件配置设置可搭配 set_property <Setting> <Value> [current_design] Vivado 工具 Tcl 命令一起使用。

Vue 基础语法

【1】模板语法 &#xff08;1&#xff09;差值表达式 {{}}是 Vue.js 中的文本插值表达式。 它用于在模板中输出数据或表达式的值。当数据或表达式的值发生变化时&#xff0c;插值表达式会自动更新。 补充&#xff1a;三目运算符 它的基本语法是 Condition ? A : B&#xff0…

python绘图(pandas)

matplotlib绘图 import pandas as pd abs_path rF:\Python\learn\python附件\pythonCsv\data.csv df pd.read_csv(abs_path, encodinggbk) # apply根据多列生成新的一个列的操作&#xff0c;用apply df[new_score] df.apply(lambda x : x.数学 x.语文, axis1)# 最后几行 …

3W 3KVDC 隔离单输出 DC/DC 电源模块——TPG-3W 系列

TPG-3W系列是一款额定功率为3W的隔离产品&#xff0c;国际标准引脚&#xff0c;宽范围工作、温度–40℃ 到 105℃&#xff0c;在此温度范围内都可以稳定输出3W&#xff0c;并且效率非常高&#xff0c;高达88%&#xff0c;同时负载调整率非常低&#xff0c;对于有输出电压精度有…

61-ARM与FPGA间SPI通信电路设计

视频链接 ARM与FPGA间SPI通信电路设计01_哔哩哔哩_bilibili ARM与FPGA间SPI通信电路设计 第22课&#xff1a;SPI Flash 电路设计 第65课&#xff1a;实战S1-FPGA板级实战导学 1、SPI简介 1.1、SPI概述 SPI是(Serial Peripheral Interface) 串行外设接口&#xff0c;由Mot…

产业空间集聚DO指数计算

1.前言 创始人 :Duranton and Overman&#xff08;2005&#xff09; 目前应用较多的产业集聚度量指数主要基于两类&#xff0c;一是根据不同空间地理单元中产业经济规模的均衡性进行构造&#xff0c;如空间基尼系数与EG指数&#xff1b;二是基于微观企业地理位置信息形成的产业…

求解亲和数

【问题描述】 古希腊数学家毕达哥拉斯在自然数研究中发现&#xff0c;220的所有真约数&#xff08;即不是自身 的约数&#xff09;之和为&#xff1a; 1245101120224455110284。而284的所有真约数为1、2、4、71、142&#xff0c;加起来恰好为220。人 们对这样的数感到很惊奇&am…

H3C ripng实验(ipv6)

H3C ripng实验&#xff08;ipv6&#xff09; 实验需求 按照图示为路由器配置IPv6地址 所有路由器运行ripng&#xff0c;进行ipv6网段的互通 查询路由表后&#xff0c;​进行全网段的ping测试&#xff0c;实验目的RTD可以ping通RTA 实验解法 按照图示为路由器配置IPv6地址 …

力扣295. 数据流的中位数

Problem: 295. 数据流的中位数 文章目录 题目描述思路复杂度Code 题目描述 思路 1.定义一个大顶堆和小顶堆&#xff1b; 2.当添加的数据小于大顶堆的堆顶元素或者大顶堆为空时&#xff0c;将元素添加到大顶堆&#xff1b;当元素大于大顶堆堆顶元素时添加到小顶堆&#xff1b;同…

easy_signin_ctfshow_2023愚人杯

https://ctf.show/challenges#easy_signin-3967 2023愚人杯信息检索&#xff0c;在请求荷载中发现一个base64 face.pngencode ZmFjZS5wbmc解密结果 flag.pngencode ZmxhZy5wbmc尝试一下 返回内容 Warning: file_get_contents(flag.png): failed to open stream: No such file…

T0策略是什么?有哪些优点和缺点,如何操作T0策略?

T0策略又称日内交易策略&#xff0c;它的持仓时间较短&#xff0c;基于对未来短期股价走势的判断&#xff0c;通过低位买入、高位卖出的方式来获得价差收益&#xff0c;并且买入卖出交易在日内完成。 T0策略分类 按照策略逻辑分类&#xff0c;T0策略可分为融券T0和底仓T0。融…

Android11 InputManagerService启动流程分析

InputManagerService在systemserver进程中被启动 //frameworks\base\services\java\com\android\server\SystemServer.java t.traceBegin("StartInputManagerService"); inputManager new InputManagerService(context);//1 t.traceEnd(); //省略 //注册服务 Servi…

我独自升级崛起在哪下载 我独自升级电脑PC端下载教程分享

将于5月8日在全球舞台闪亮登场的动作角色扮演游戏《我独自升级崛起》&#xff0c;灵感源自同名热门动画与网络漫画&#xff0c;承诺为充满激情的游戏玩家群体带来一场集深度探索与广阔体验于一身的奇幻旅程。该游戏以独特的网络武侠世界观为基底&#xff0c;展现了一位普通人踏…

React + 项目(从基础到实战) -- 第11期

目标 问卷编辑器的开发 设计UI - 拆分布局 水平垂直居中 画布 y方向滚动 自定义问卷组件 后端 返回组件数据 //获取单个问卷信息{url: /api/question/:id,method: get,response: () > {return {errno: 0,data: {id: Random.id(),title: Random.ctitle(),componentList:[//…

纯血鸿蒙APP实战开发——页面间共享组件实例的案例

介绍 本示例提供组件实例在页面间共享的解决方案&#xff1a;通过Stack容器&#xff0c;下层放地图组件&#xff0c;上层放Navigation组件来管理页面&#xff0c;页面可以共享下层的地图组件&#xff0c;页面中需要显示地图的区域设置为透明&#xff0c;并参考触摸交互控制&am…

Linux网络-部署YUM仓库及NFS共享服务

目录 一.YUM仓库服务 1.YUM概述 1.1.YUM&#xff08;Yellow dog Updater Modified&#xff09; 2.准备安装源 2.1.软件仓库的提供方式 2.2.RPM软件包的来源 2.3.构建CentOS 7 软件仓库 2.4.在软件仓库中加入非官方RPM包组 3.一键安装软件包的工具&#xff1a; 好处&a…

ubuntu中的docker记录(3)——如何安装nvidia-docker以更好地支持GPU加速计算应用程序的运行

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、nvidia-docker2的安装1. 安装docker2. 安装nvidia-docker2(1) 添加密钥(2) 更新软件列表(3) 安装nvidia-docker2(4) 测试nvidia-docker2 二、可能的报错及解…

大模型争霸的下一站:不仅是超越GPT-4,更是寻求模型之间的平衡应用

文 | 智能相对论 作者 | 沈浪 知名科学杂志《Nature》发表了一篇关于大模型规模参数大小争议的文章《In Al, is bigger always better?》——AI大模型&#xff0c;越大越好吗&#xff1f;随着大模型应用走向实践&#xff0c;这一问题不可避免地成为了当前AI行业发展的焦点与…

【网络原理】IP协议详解

一.与IP协议相关的基本概念 IP协议&#xff0c;即网际互连协议&#xff08;Internet Protocol&#xff09;&#xff0c;是TCP/IP体系中的核心网络层协议。 网络层IP协议解决的问题 数据传输的过程中,不是直接进行的传输,而是经过层层的封装和分用的过程才能到达对端. IP协议主…

怎么通过网页查看iPhone手机的备忘录内容?

在这个数字化的时代&#xff0c;iPhone已成为我们日常生活中不可或缺的一部分。我特别喜欢用iPhone的备忘录功能&#xff0c;随时随地记录生活的点点滴滴&#xff0c;工作中的待办事项。然而&#xff0c;有时候&#xff0c;当我需要在电脑上查看或编辑这些备忘录时&#xff0c;…