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

本文介绍了Pytorch中的数据并行训练,包括DataParallel(DP)和DistributedDataParallel(DDP)的原理及应用。DP适用于单机多卡,代码简洁,但负载不均;DDP支持多机多卡,训练速度更快,负载均衡,是优先选择。文章详细阐述了两者的工作流程,并给出了DDP的应用实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

1. 前言

并行训练可以分为数据并行和模型并行。

  • 模型并行

    模型并行主要应用于模型相比显存来说更大,一块 device 无法加载的场景,通过把模型切割为几个部分,分别加载到不同的 device 上。比如早期的 AlexNet,当时限于显卡,模型就是分别加载在两块显卡上的。

  • 数据并行

    这个是日常会应用的比较多的情况。每一个 device 上会加载一份模型,然后把数据分发到每个 device 并行进行计算,加快训练速度。

如果要再细分,又可以分为单机多卡,多机多卡。这里主要讨论数据并行的单机多卡的情况

在这里插入图片描述

2. Pytorch 并行训练

常用的 API 有两个:

  • torch.nn.DataParallel(DP)
  • torch.nn.DistributedDataParallel(DDP)

DP 相比 DDP 使用起来更友好(代码少),但是 DDP 支持多机多卡,训练速度更快,而且负载相对要均衡一些。所以优先选用 DDP 吧。

2.1 训练模型的过程

在开始怎么调用并行的接口之前,了解并行的过程是有必要的。首先来看下模型训练的过程。

在这里插入图片描述

2.2 DP

2.2.1 DP 的计算过程

DP 并行的具体过程可以参考下图两幅图。

在这里插入图片描述

在这里插入图片描述

上图清晰的表达了 torch.nn.DataParallel 的计算过程。

  • 将 inputs 从主 GPU 分发到所有 GPU 上
  • 将 model 从主 GPU 分发到所有 GPU 上
  • 每个 GPU 分别独立进行前向传播,得到 outputs
  • 将每个 GPU 的 outputs 发回主 GPU
  • 在主 GPU 上,通过 loss function 计算出 loss,对 loss function 求导,求出损失梯度
  • 计算得到的梯度分发到所有 GPU 上
  • 反向传播计算参数梯度
### PyTorch DataParallel DistributedDataParallel 的区别及用法 #### 数据并行机制概述 数据并行是一种通过将输入数据划分为多个子集,在不同设备上同时处理这些子集来加速训练的方法。PyTorch 提供了两种主要的数据并行方式:`torch.nn.DataParallel` `torch.nn.parallel.DistributedDataParallel`。 #### DataParallel (DP) - **适用场景**:适用于单机多卡环境下的简单并行化需求。 - **工作原理**:每次前向传播时会复制整个模型到每个GPU上,完成计算后再收集结果返回主进程[^3]。 - **局限性** - 参数同步效率低,因为需要频繁地在CPU-GPU之间传输参数; - 不支持复杂的通信模式,难以扩展至大规模集群环境中; ```python import torch from torchvision import models model = models.resnet50() dp_model = torch.nn.DataParallel(model).cuda() output = dp_model(input_tensor) ``` #### DistributedDataParallel (DDP) - **适用范围更广**:不仅限于单节点内的多GPU设置,还能够跨越多个节点构建大型分布式系统[^1]。 - **性能优势明显**: - 使用高效的梯度累积策略减少不必要的内存占用; - 支持多种后端协议(如NCCL),优化跨节点间的通讯速度; ```python import os import torch.distributed as dist from torch.nn.parallel import DistributedDataParallel as DDP def setup(rank, world_size): os.environ['MASTER_ADDR'] = 'localhost' os.environ['MASTER_PORT'] = '12355' # 初始化进程组 dist.init_process_group("nccl", rank=rank, world_size=world_size) setup(0, 2) # 假设只有两个GPU参与运算 model = models.resnet50().to('cuda') ddp_model = DDP(model, device_ids=[local_rank]) output = ddp_model(input_tensor.to(local_rank)) ``` #### 性能对比总结 相比于传统的`DataParallel`,`DistributedDataParallel`提供了更好的可伸缩性更高的吞吐量,尤其是在涉及大量GPU资源的情况下表现尤为突出。因此对于现代深度学习项目而言,推荐优先考虑采用`DistributedDataParallel`来进行高效的大规模训练任务。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值