模型的多GPU并行训练,DDP (附代码)

Pytorch中的DDP 举个例子:我有两台机子,每台8张显卡,那就是2x8=16个进程,并行数是16。但是,我们也是可以给每个进程分配多张卡的。 阅读详情
AI摘要

本文总结了用DDP进行多GPU并行训练的方法。介绍了DDP变量用于区分进程,可用torchrun命令启动train.py。探讨了batch size超GPU内存时的处理办法,还说明了划分数据区域、处理model、同步梯度计算及输出log等方面的要点,最后提及数据存储不同位置时的训练注意事项。

DDP全称是DistributedDataParallel, 在torch.nn.parallel里面。
今天总结一下用DDP进行多GPU并行训练的方法,
内容来自build gpt2加上自己的补充。
本文有些长,需要耐心阅读,希望整理的这些对大家有所帮助。

如果你有多块GPU,就可以充分利用它们。
DDP会创建多个process(进程,不是线程哦), 每个process分配一个GPU,这些process同时运行,于是就达到了多个GPU同时训练的目的。
之前写的训练代码你就可以想象它们同时在被多个process同时运行,
但每个process处理的是不同部分的数据(数据当然要不同了,不然不成了重复训练了嘛)。
这时候你还需要注意一个问题就是梯度的计算,比如现在有8个GPU,它们同时计算了不同部分数据的梯度,
而你的训练目标是不是所有数据汇总的梯度,你就需要把8个GPU计算的梯度加起来求平均。

DDP变量

那么你该如何区分哪个机器上的哪个进程呢,有下面几个变量帮你区分:
WORLD_SIZE: 总进程数
LOCAL_RANK: 当前进程在本机器上的局部排名,从0开始计数
RANK: 当前进程在所有进程中的全局排名,从0到 WORLD_SIZE-1
举个例子:
在2台机器上运行4个进程时:
机器1:

  • 进程0: RANK=0, LOCAL_RANK=0
  • 进程1: RANK=1, LOCAL_RANK=1

机器2:

  • 进程2: RANK=2, LOCAL_RANK=0
  • 进程3: RANK=3, LOCAL_RANK=1

所有进程的 WORLD_SIZE=4
如果只有一个机器,那local_rank和rank的值是相同的。

启动train.py

可以手动设置分布式环境

import torch.distributed as dist

# 手动设置环境变量
os.environ['RANK'] = '0'
os.environ['WORLD_SIZE'] = '4'
os.environ['LOCAL_RANK'] = '0'
os.environ['MASTER_ADDR'] = 'localhost'
os.environ['MASTER_PORT'] = '29500'

# 初始化进程组
dist.init_process_group(backend='nccl')

更方便的是用torchrun命令,它可以自动做如下事情:

  1. 自动设置环境变量(RANK, LOCAL_RANK, WORLD_SIZE等)
  2. 为每个GPU创建一个进程
  3. 设置进程组通信,初始化分布式环境
  4. 在每个进程中运行train.py
# 单机4卡
torchrun --standalone --nproc_per_node=4 train.py
torchrun --nproc_per_node=4 train.py #单机训练,--standalone参数会被自动设置为默认值

# 多机训练
torchrun --nproc_per_node=4 --nnodes=2 --node_rank=0 --master_addr="192.168.1.1" --master_port=29500 train.py

torchrun会根据GPU序号设置RANK。例如在单机4卡时:

GPU 0: RANK=0
GPU 1: RANK=1
GPU 2: RANK=2
GPU 3: RANK=3

在多机时,RANK会跨机器累加。例如2机4卡:

机器1: RANK=0,1,2,3
机器2: RANK=4,5,6,7

那你说,我的train.py有时会用单个GPU,有时会用多个,我想让它具有通用性,不需要每次都修改代码。
可以下面这样做,后面都说的是单个机器的情况。

GPU之间的通信一般用’nccl’,
NCCL (NVIDIA Collective Communications Library) 是NVIDIA开发的GPU通信库,专门优化了GPU之间的通信效率。在PyTorch分布式训练中,它是GPU训练的默认后端选项。
初始化阶段

from torch.distributed import init_process_group
    #如果用torchrun启动,RANK的值在0~WORLD_SIZE-1,WORLD_SIZE为进程数,即GPU总数
    ddp = int(os.environ.get('RANK', -1)) != -1
    if ddp:
        assert torch.cuda.is_available() #DDP中CUDA是必须的
        init_process_group(backend='nccl')
        ddp_rank = int(os.environ['RANK'])
        ddp_local_rank = int(os.environ['LOCAL_RANK'])
        ddp_world_size = int(os.environ['WORLD_SIZE'])
        device = f'cuda:{ddp_local_rank}'
        torch.cuda.set_device(device)
        master_process = ddp_rank==0 #防止log重复输出,指定master process输出
    else:
        ddp_rank = 0
        ddp_local_rank = 0
        ddp_world_size = 1
        master_process = True
        device = 'cpu'
        if torch.cuda.is_available():
            device = 'cuda'
        elif hasattr(torch.backends, "mps") and torch.backends.mps.is_available():
            device = 'mps'  #较新的MAC用
        print(f'using device: {device}')

在代码里面加上这么一句话,就可以看到代码正在被哪个GPU执行:

print("I am GPU: ", ddp_rank)

打印出来的是随机顺序,并不能保证先后,且它们是并行发生的。

batch size超过GPU内存的情况

比如gpt2, paper中的batch size为0.5M个token, 一般取2的N次方会利于GPU加速计算,
所以令total_batch_size=219=524288, 这么大的batch size一般GPU很难容纳,如何在有限的GPU内存上实现如此大的batch size?

可以每次处理小批量的batch, 分多次处理。
比如gpt的sequence length设为T=128,batch size B=32, 这是一次处理的batch量(设为你的GPU能承受的batch size),
总共要处理grad_accum_steps=total_batch_size // (B * T)次。
这是在分解任务,总共batch, 可是我的GPU容纳不下,于是分批处理,最后再合起来。

total_batch_size = 524288
B = 32 #小的batch size(GPU能承受的)
T = 128
assert total_batch_size % (B*T) == 0
grad_accum_steps = total_batch_size // (B*T)  #一共需要累加多少轮
print(f"total desired batch size: {total_batch_size}")
print(f"=> calculated grad accumulation steps: {grad_accum_steps}")

于是到了训练的时候,我们要在step里面再分解为micro_step,
我们的目的是最后把每个iteration里面的所有micro_steps的梯度累加起来,才算一个大batch的梯度,累加完了之后再更新optimizer, 梯度归0。
用到了这个特性:
如果你不用optimizer.zero_grad(),梯度梯度是累加的,所以每个iteration开始时用一次, micro_step里面(小batch结束时)不用。optimizer.step()是用梯度来更新变量,所以也是每个iteration结束时用一次,micro_step里面不用。

不过loss不会自动累加,你需要设一个变量用来累加loss.
在累加loss的时候,你要注意一个问题,
举例来说明,假如现在batch size=B, 每个micro_step中的batch size=b. 一共累加B//b=N次。
一般loss里面会对这个batch里面的loss求平均,会有mean的运算。
那么每一个micro_step里面的loss就是1/b * 小batch的loss和,
最后我们把所有micro_step的loss累加起来之后loss就是1/b * 大batch的loss.
发现问题了吗,本来大batch的loss应该是1/B * 大batch的loss, 现在变成了1/b, 这个求平均的基数不对。
所以在所有micro_steps的loss累加时,要另外再除grad_accum_steps.

    for step in range(max_steps):
        t0 = time.time()
        optimizer.zero_grad()
        loss_accum = 0.0 #用于print loss
        #在这些步里面累加梯度(用loss.backward的累加梯度效果),模拟一个0.5M的batch size的效果
        for micro_step in range(grad_accum_steps):
            x, y = train_loader.next_batch()
            x = x.to(device)
            y = y.to(device)

            #一般的loss里面会用mean来求这个batch里面loss的平均,所以每个batch会除以batch_size
            #那么大batch的loss加起来,也只相当于除以了小batch的batch_size,并不是大batch_size
            #所以在累加的loss基础上还要除以(大batch_size / 小batch_size), 也就是grad_accum_steps
            loss /= grad_accum_steps
            loss_accum += loss.detach() #detach():变成叶子节点,梯度累加,loss可没有累加,累加loss要自己算
            loss.backward()  # 更新梯度,会累积,所以每次optimizer要设置zero_grad,它不会自动清零
        #把梯度的norm限制在1,什么是norm,就是一个向量的L2 norm
        norm = torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0) #根据gpt3 paper
        optimizer.step() #更新参数

现在用了DDP,就有多个GPU一起来处理这个batch, 每个GPU处理的grad_accum_steps变为:

grad_accum_steps=total_batch_size // (B * T * ddp_world_size)

划分不同数据区域

这部分讨论如何让每个process访问不同的数据部分,也就是说每个GPU处理不同的数据。
所以我们需要把数据划分,让不同的GPU访问不同的部分。
如何识别不同的GPU,这就用到了前面的RANK.
你就需要把ddp_rank和ddp_world_size传给dataloader.

class DataLoaderLite:
    def __init__(self, B, T, process_rank, num_processes):
        self.B = B
        self.T = T
        self.process_rank = process_rank  #ddp_rank
        self.num_processes = num_processes  #ddp_world_size

        with open('./data/input.txt','r') as f:
            text = f.read()
        enc = tiktoken.get_encoding('gpt2')
        tokens = enc.encode(text)
        self.tokens = torch.tensor(tokens)
        print(f"loaded {len(self.tokens)} tokens")
        print(f"1 epoch = {len(self.tokens) // (B*T)} batches")

		#每个GPU读不同的数据
        self.current_position = self.B * self.T * self.process_rank

    def next_batch(self):
        B, T = self.B, self.T
        buf = self.tokens[self.current_position:self.current_position+B*T+1]
        x = buf[:-1].view(B,T)
        y = buf[1:].view(B,T)
        self.current_position += B*T * self.num_processes  #每个GPU处理的数据,有点类似CNN中的batch
		
		#数据应该不会小到一个循环之内self.B * self.T * self.process_rank的时候就超出边界了
        if self.current_position + (B*T*self.num_processes+1) >= len(self.tokens):
            self.current_position = B * T * self.process_rank
        return x, y

train_loader = DataLoaderLite(B=B, T=T, process_rank=ddp_rank, num_processes=ddp_world_size)

如何处理model

由于一个代码被N个GPU同时执行,这里假设有8个GPU并行。
那么model就会被创建8次,要保证这8个model是一致的,就需要固定seed.

还需要把model装进DDP container.
这个可以参考DistributedDataParallel官方文档,device_ids这个参数指的是ddp_local_rank, 而不是ddp_rank.

DDP 这样包装 model 的主要原因是为了实现高效的分布式训练,
device_ids=[ddp_local_rank] 的作用:

将模型绑定到指定的 GPU 上
ddp_local_rank 通常是 0,1,2,3… 这样的局部 GPU 编号
确保每个进程只使用分配给它的那个 GPU

DDP 包装后会实现:
自动梯度同步:不同 GPU 上的梯度会自动进行平均
参数广播:确保所有 GPU 上的模型参数保持一致
通信优化:使用高效的 ring-allreduce 算法进行梯度同步

包装了之后model就变成了DDP model.
而需要调用model里面的method时,需要的是raw model.

#这里model会被创建GPU个数次,比如8个GPU,就会创建8个model, torch.compile也会发生8次
#固定seed, 让每个model计算一致
torch.manual_seed(1337)
if torch.cuda.is_avaliable():
    torch.cuda.manual_seed(1337)
model = GPT(GPTConfig(vocab_size=50534))
model.to(device)
model = torch.compile(model)
if ddp:
	model = DDP(model, device_ids=[ddp_local_rank])
raw_model = model.module if ddp else model

#当需要调用model里面的method时,要用raw_model
optimizer = raw_model.configure_optimizers(weight_decay=0.1, ...)

同步梯度计算

forward过程每个GPU都是一样的,
backward涉及到每个GPU都在计算梯度,所以在backward结束的时候,会计算所有GPU计算的梯度的平均,
同步这个平均梯度到每个GPU上。其实是调用了all_reduce
实际上并不是结束的时候才这样做,而是在backward正在进行的时候就在同步做这些事情。
在loss.backward()时,就会发生通信,并同步梯度信息到各GPU。

前面提到了batch size过大时,会分解成每次处理小的batch.

可以看到每个小batch计算时都有loss.backward(), 导致多次通信,同步梯度,影响效率,
我们现在不想这么做,想让一轮batch计算结束时再同步。

    for step in range(max_steps):
        t0 = time.time()
        optimizer.zero_grad()
        loss_accum = 0.0
       
        for micro_step in range(grad_accum_steps):
            x, y = train_loader.next_batch()
            x = x.to(device)
            y = y.to(device)

            loss /= grad_accum_steps
            loss_accum += loss.detach() 
            loss.backward() 
            
        norm = torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0) 
        optimizer.step() #更新参数

一般是用no_sync(), 看上去比较复杂

在这里插入图片描述

而当你看了no_sync()的源码,你会发现起作用的是一个flag

在这里插入图片描述

所以直接用这个flag, 会比较简洁,风险就是将来版本升级了这个flag可能就不存在了-_-
需要在loss.backward()前面设置是否需要通信同步梯度。

另外,梯度已经求了所有GPU的平均并同步,但是loss并没有求各GPU的平均,
每个GPU只能看见它自己的loss.
这时需要调用all_reduce, 前面提到了同步梯度时也是all_reduce.
在完成了一整个大batch的计算后(从for loop出来),调用all_reduce.
all_reduce做的事情是对每个GPU上的loss_accum, 计算所有GPU(rank)上的平均值,然后同步到每个GPU。

当你print(loss_accum)时,所有GPU上的数值应该是一致的。

import torch.distributed as dist

    for step in range(max_steps):
        t0 = time.time()
        optimizer.zero_grad()
        loss_accum = 0.0 
        
        for micro_step in range(grad_accum_steps):
            x, y = train_loader.next_batch()
            x = x.to(device)
            y = y.to(device)

            loss /= grad_accum_steps
            loss_accum += loss.detach() 
            if ddp:
            	#到最后一轮时才需要同步梯度
            	model.require_backward_grad_sync = (micro_step == grad_accum_steps-1)
            loss.backward() 
        #从for loop中出来后所有GPU里面的梯度都同步了  
        if ddp:
        	dist.all_reduce(loss_accum, op=dist.ReduceOp.AVG) #average
        norm = torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
        optimizer.step() 

输出log

应该意识到现在每个GPU都在运行这个代码,所以你会输出重复的log,
设置一个master, 只输出一个log,
master可以在前面初始化的时候设置

结束时要调用destroy_process_group

#master_process = ddp_rank==0 #前面初始化的部分已经设置

for step in range(max_steps):
   ...
token_processed = train_loader.B * train_loader.T * grad_accum_steps * ddp_world_size
token_per_sec = token_processed / dt
if master_process:
	print(f"step {step:4d} | loss: {loss.item():.6f} | norm: {norm:.4f} | dt: {dt*1000:.2f}ms, token_per_sec: {token_per_sec:.2f}ms")
	
if ddp:
	destroy_process_group()

你会发现多GPU并行时的loss可能会和单GPU不同,这是因为data_loader中读取数据的方式不一样,
以前是一个一个的batch, 超出边界了就从0开始,现在把N个GPU一次读的数据看成一个page, page超过边界时重置,这个地方会导致batch数据可能会出现不同。
如果想让loss相同,需要调节total batch size, 让单个GPU重置的边界和多个GPU相同。

拓展一下,如果数据很大,存储在不同的地方,也可通过DDP实现训练,设置不同rank的GPU读取不同地方的数据。
不过要注意以下几点:
确保数据分片大小相近,避免负载不均衡
根据实际存储位置和网络带宽调整数据分配策略
可能需要处理数据分片边界的问题

分布式训练 - 多机多卡 (DDP) 起初为调用大规模的模型训练,单卡GPU是不够使用的,需要借用服务器的多GPU使用。就会涉及到单机多卡,多机多卡的使用。在这里记录一下使用的方式和踩过的一些坑。文中若有不足,请多多指正。 由于分布式的内容较多,笔者准备分几篇来讲一次下深度学习的分布式训练,深度学习的框架使用的是Pytorch框架。 ----1.分布式训练的理论基础 ----2.GPU训练 ----3.单机多卡的使用 ----4.多机多卡的使用 在前边的文章中已经提到了怎样进行单机单卡和单机多卡进行分布式训练,那可能有小伙伴会有疑问能不能进行多 阅读详情

相关推荐

Pytorch DDP原理及配置[最大限度提高GPU利用率]

pytorch在单机多卡,多机多卡之间已经做了进一步的优化,最早之前可以使用net = torch.nn.DataParallel(net.cuda(), device_ids=range(torch.cuda.device_count()))来使用多显卡加速运行,但是会受到python GIL锁的限制,导致对CPU的使用率不高,进而导致多显卡之间的协调不足,出现利用率较低的情况。为了解决这个微博替,需要将原来的代码进行说为的修改,使用DDP的方式提高多卡的利用率。

爱在深秋 2573

AI分布式训练:DDP (数据并行)技术详解与实战

如今传统的单机单卡模式已经无法满足超大模型进行训练的要求,如何更好地、更轻松地利用多个 GPU 资源进行模型训练成为了人工智能领域的热门话题。 我们今天为大家带来的这篇文章详细介绍了一种名为 DDP(Distributed Data Parallel)的并行训练技术,作者认为这项技术既高效又易于实现。

Baihai_IDP的博客 2267

科研第五步:如何使用DDP分布式多GPU并行跑pytorch深度学习训练

DDP分布式多GPU并行跑pytorch深度学习模型 多卡并行代码模板 文章目录DDP分布式多GPU并行跑pytorch深度学习模型前言一、DDP怎么用二、使用步骤1.引入库2.读入数据总结 前言 PyTorch的数据并行相对于TensorFlow而言,要简单的多,主要分成两个API: DataParallel(DP):Parameter Server模式,一张卡为reducer,实现也超级简单,一行代码。 DistributedDataParallel(DDP):All-Reduce模式,本意是用来分布式

fs1341825137的博客 6664

PyTorch 多机多卡训练:DDP 实战与技巧

点击上方“小白学视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达作者丨996黄金一代@知乎(已授权)来源丨https://zhuanlan.zhihu.com/p/250471767零. 概览想要让你的PyTorch神经网络在多卡环境上跑得又快又好?那你definitely需要这一篇!No one knows DDP better than I do!– – mag...

小白学视觉 7280

GPU并行模式之数据并行DDP实践案例

本文介绍了GPU数据并行(DDP)的基本原理及PyTorch实现。DDP通过将数据分割到多个设备、复制模型副本、并行计算和梯度聚合来实现高效训练。文章详细讲解了DDP的工作流程,包括Reduce-Scatter和All-Gather的梯度聚合方法,并提供了PyTorch中DDP工具包的使用方法。最后通过一个图数据处理的案例,展示了如何实现多进程数据并行训练,包括进程初始化、数据采样、模型包装、训练循环等关键步骤。该案例使用MLP模型进行训练,并提供了模型保存和单卡预测的实现方法。

qq_38142901的博客 1162

Pytorch(十一) —— 分布式(多GPU/多卡)训练 并行 (DP & DDP)

从PyTorch 0.2版本开始,PyTorch新增分布式GPU支持。 注意分布式和并行的区别:分布式是指有多个GPU在多台服务器上,而并行一般指的是一台服务器上的多个GPU。分布式涉及了服务器之间的通信,因此比较复杂,PyTorch封装了相应的接口,可以用几句简单的代码实现分布式训练。 分布式对普通用户来说比较遥远,因为搭建一个分布式集群的代价很大,使用也比较复杂。相比之下,一机多卡更现实。 如果服务器具有多个GPU,tensor.cuda......

hxxjxw的博客 6884

Pytorch实现多GPU并行训练(DDP)

Pytorch实现并行训练通常有两个接口:DP(DataParallel)和DDP(DistributedDataParallel)。目前DP(DataParallel)已经被Pytorch官方deprecate掉了,原因有二:1,DP(DataParallel)只支持单机多卡,无法支持多机多卡;2,DP(DataParallel)即便在单机多卡模式下效率也不及DDP(DistributedDataParallel)。

木盏 6899

Unity 代码混淆<混淆插件(Obfuscator Pro 3.9.4)>

Unity 代码混淆<混淆插件(Obfuscator Pro 3.9.4)> 插件导入项目 导入后打开OPS/Obfuscator/Obfuscator Pro Settings 打开后可以看到界面如下 可以在上面界面中选择你需要混淆的类,方法,字段,属性,事件,参数。需要混淆的程序集的选择。如果有些程序集混淆后会有问题也可以添加到白名单里不被混淆 根据自己需求取选择 这个界面是是否添加添加随机代码的 如果使用了上面的插件可以使用 插件下载网址:https://download.cs

Xing_Cheng_Yun的博客 5097

Pytorch 并行训练(DP, DDP)的原理和应用

Pytorch 并行训练(DP, DDP)的原理和应用 1. 前言 并行训练可以分为数据并行和模型并行。 模型并行 模型并行主要应用于模型相比显存来说更大,一块 device 无法加载的场景,通过把模型切割为几个部分,分别加载到不同的 device 上。比如早期的 AlexNet,当时限于显卡,模型就是分别加载在两块显卡上的。 数据并行 这个是日常会应用的比较多的情况。每一个 device 上会加载一份模型,然后把数据分发到每个 device 并行进行计算,加快训练速度。 如果要再细分,又可以分

生命在于折腾! 2万+

处理SAP资产折旧AFAB 过账报错:“科目 8019010100 要求一个成本会计分配”

本文介绍如何处理资产折旧报错 ““科目XXXXXXX 要求一个成本会计分配””

IT小职员 2774

代谢组学数据分析实战:用R语言从PCA、PLS-DA到OPLS-DA一步步搞定(附代码)

本文详细介绍了使用R语言进行代谢组学数据分析的全流程,从数据预处理到PCA、PLS-DA和OPLS-DA模型构建与验证。通过实际案例和代码示例,帮助研究者掌握关键分析技术,提升数据解读能力,特别适合生命科学领域的研究人员。

weixin_28689507的博客 132

Pytorch 多卡并行训练教程 (DDP)

Pytorch 多卡并行训练教程 (DDP),关于使用DDP进行多开并行训练 网上有许多教程,而且很多对原理解析的也比较透彻,但是有时候看起来还是比较懵逼,再啃了许多相关的博客后,博主记录了一些自己对于使用torch.nn.DistributedDataParallel(DDP)进行单机多卡并行训练的一些体会,希望能对入门的小白有一定的帮助,不足之处也希望指出,大家一起交流学习。

fovever_的博客 6877

Vite与Webpack路径配置大不同:从Vue2迁移到Vue3必须知道的public目录使用技巧

本文详细解析了Vite与Webpack在public目录路径配置上的核心差异,为Vue2迁移到Vue3的开发者提供实用指南。重点对比了两种构建工具的资源处理逻辑,给出典型编译警告的解决方案,并分享路径适配表与高级优化技巧,帮助开发者高效完成技术栈升级。

weixin_30836759的博客 485

「分布式训练」使用 DDP 实现程序单机多卡并行指南

「大模型微调」使用 DDP 实现程序单机多卡并行指南

Meiling_up 4651

深入解析高通Adreno DPU的DRM/KMS驱动架构与硬件协同设计

本文深入解析了高通Adreno DPU的DRM/KMS驱动架构与硬件协同设计,详细介绍了Adreno DPU的核心模块组成、显示接口设计以及DRM驱动架构。通过实际案例和调试技巧,帮助开发者理解硬件与软件的协同工作原理,优化显示性能并解决常见问题。

weixin_29266679的博客 436

假新闻检测论文分享(17)CAFE(Cross-modal Ambiguity Learning for Multimodal Fake NewsDetection)

本文首先从信息论的角度对跨模态歧义性学习问题进行形式化描述,利用不同单模态特征之间的分布散度量化其歧义性;然后,提出了一种模糊度感知的多模态假新闻检测方法CAFE。CAFE通过自适应地聚合单模态特征和跨模态关联,即在跨模态歧义性较弱时依赖单模态特征,在跨模态歧义性较强时参考跨模态关联,从而提高假新闻检测精度。提出了跨模态歧义学习问题,这是多模态假新闻检测的一个关键挑战,并提出了一种基于KL散度的方法,通过估计其特征分布的散度来量化文本和图像之间的歧义。

weixin_41964296的博客 1724

Pytorch 多卡并行(1)—— 原理简介和 DDP 并行实践

本文介绍多卡并行原理,并用一个简单的例子演示 Pytorch 中的 DDP 多卡并行代码写法

佚失的诗篇 4767

GameFramework教程✨六、怎样加载一个3D UI

怎样加载一个3D UI

星河造梦坊 1581

YOLOv5多GPU训练:分布式数据并行(DDP)最佳实践指南

你是否还在忍受单GPU训练YOLOv5时的漫长等待?当数据集规模达到数万张图片、模型参数量突破千万级,单卡训练不仅耗时数天甚至数周,还会因batch size受限导致收敛效果不佳。本文将系统讲解如何利用PyTorch的分布式数据并行(Distributed Data Parallel, DDP)技术,在多GPU环境下实现训练效率的线性提升,同时规避常见的性能陷阱与配置误区。 读完本文后,你将掌握...

gitblog_00742的博客 1204

OpenClaw零基础教程:30分钟搭建你的第一个AI自动化助手

别再看那些满是代码、专业术语的教程了,那些都是给程序员看的。这篇教程,我把所有步骤拆到了极致,你跟着点鼠标就行,点错了都没关系,大不了重装一遍,5分钟的事。

2601_94871597的博客 96

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Pytorch DDP一机多卡并行训练

Pytorch并行主要有两种方式,DataParallel(DP)和DistributedDataParallel(DDP)。DP方式较为简单,但是多线程训练,并且主卡显存占用比其他卡会多很多。因此这里采用DDP方式来多卡计算。 DDP是多进程,将模型复制到多块卡上计算,数据分配较均衡。 使用DDP的一机多卡配置 1.加入local_rank参数,这一步会在代码运行时通过torch.distributed.launch输入,该参数意义是当前进程所用的是哪块卡 parser.add_argument

qq_37935516的博客 2447

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

【计算系统】分布式训练:DDP单机多卡并行实战

分布式训练是一种模型训练范式,涉及在多个工作节点上分散训练工作量,从而显著提高训练速度和模型准确性。虽然分布式训练可以用于任何类型的ML模型训练,但将其用于大型模型和计算要求高的任务(如深度学习)是最有益的。

小哲的博客 4289

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Pytorch分布式训练/多卡训练(二) —— Data Parallel并行(DDP)(2.1)(基本概念&代码框架)

Pytorch官网已经建议使用DistributedDataParallel来代替DataParallel, 因为DistributedDataParallel比DataParallel运行的更快, 然后显存分配的更加均衡. 而且DistributedDataParallel功能更加强悍 DDP与DP的区别 ①DataLoader部分需要使用Sampler,保证不同GPU卡处理独立的子集. ②模型部分使用DistributedDataParallel. DDP的主要代码部分 .......

hxxjxw的博客 5234

【问题解决】DDP | 如何使用 DDP 模式来训练模型

本文主要介绍如何使用 DDP 模式训练模型

呆呆的猫的博客 3160

多GPU使用与并行训练

环境变量控制 GPU 可见性:在命令行设置可以灵活选择使用哪几块 GPU。单 GPU 训练:通过将模型和数据移动到指定 GPU 上进行训练。多 GPU 训练:简单易用,但存在主 GPU 负载过高等问题,适合小规模场景。:更高效、扩展性更好(支持多机多卡),需要额外设置分布式环境(例如使用 torchrun 启动)。混合精度训练:使用可以减少显存使用并提高训练速度。数据采样:在 DDP 中使用确保各进程数据不重叠并且均衡。

frostmelody 全网同名,大家多多关注呀~ 持续分享优质内容! 1540

多GPU训练大语言模型,DDP, ZeRO 和 FSDP

在某些时候,我们可能需要将模型训练扩展到单个 GPU 之外。当模型变得太大无法适应单个 GPU 时,需要使用多 GPU 计算策略。但即使模型适合单个 GPU,使用多个 GPU 来加速训练也是有好处的。即使您正在处理一个小模型,了解如何在多个 GPU 上分配计算也是有用的。

祖国翔的博客 1253
上一篇: 混合精度训练说明
下一篇: 一个例子练习知识蒸馏
蓝羽飞鸟
博客等级 码龄8年 1万+粉丝 727原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值