pytorch分布式系列2——DistributedDataParallel是如何做同步的?

试验2: DistributedDataParallel是如何做同步的?

  1. 在开始试验之前我们先说明DataParallel,当我们使用DataParallel去做分布式训练时,假设我们使用四块显卡去做训练,数据的batch_size设置为8,则程序启动时只启动一个进程,每块卡会分配batch_size=2的资源进行forward操作,当4快卡的forward操作做完之后,主进程会收集所有显卡的结果进行loss运算和梯度回传以及参数更新,这些都在主进程中完成,也就是说主进程看到看到的forward运算的结果是batch_size=8的。
  2. 当我们用DistributedDataParallel去做分布式训练时,假设我们使用4块显卡训练,总的batch_size设置为8,程序启动时会同时启动四个进程,每个进程会负责一块显卡,每块显卡对batch_size=2的数据进行forward操作,在每个进程中,程序都会进行的loss的运算、梯度回传以及参数更新,DataParallel的区别是,每个进程都会进行loss的计算、梯度回传以及参数更新。这里抛出我们的问题,既然每个进程都会进行loss计算与梯度回传是怎么保证模型训练的同步的呢?
    OK, 下面开始我们的试验,不看代码就靠猜。。。
试验用到的代码
  1. 数据类datasets.py: 这个数据类随机生成224x224大小的图像和其对应的随机标签0-8
class RandomClsDS(Dataset):
    def __init__(self):
        pass

    def __len__(self):
        return 10000

    def __getitem__(self, item):
        image = torch.randn(3,224, 224)
        label = np.random.randint(0,9)

        return image, label

  1. 训练类train.py
import os
import
### PyTorch 分布式训练常见错误及其解决方案 #### 1. GPU资源分配不当 在多GPU环境中启动分布式训练时,如果未正确设置`CUDA_VISIBLE_DEVICES`环境变量,则可能导致程序无法识别预期数量的GPU设备。应确保此环境变量仅包含计划使用的显卡ID,并且这些ID按照期望顺序排列[^1]。 ```bash export CUDA_VISIBLE_DEVICES=0,1 ``` #### 2. 数据加载器配置不合理 当观察到CPU核心利用率异常低的情况时,这通常意味着数据预处理阶段成为了瓶颈所在。调整`DataLoader`中的`num_workers`参数可有效缓解这一状况;然而需要注意的是,在某些情况下,导入库文件的位置也会影响性能表现——特别是像OpenCV这样的图像处理库应当放置于其他依赖项之后再引入,从而避免潜在冲突影响线程调度机制[^2]。 ```python # 正确法:先引入PyTorch/Numpy后再引入cv2 import torch import numpy as np import cv2 ``` #### 3. DDP初始化失败或通信障碍 利用`DistributedDataParallel`(DDP)模块能够显著提升并行计算效率的同时保持良好的扩展性。但在实践中可能会遭遇诸如进程间同步失误等问题。为了预防此类情况的发生,建议严格按照官方文档指导完成必要的准备工作,比如指定恰当的启动方式(`torchrun`, `torch.distributed.launch`)以及合理设定相关超参(world_size, rank等)[^3]。 ```python if __name__ == '__main__': # 使用torchrun或其他推荐的方式启动脚本... dist.init_process_group( backend='nccl', # NCCL适用于NVIDIA GPUs间的高效通讯 init_method='env://', world_size=args.world_size, rank=args.rank ) ``` #### 4. Rendezvous协议执行出错 对于支持动态调整规模的应用场景而言,“碰面点”(rendezvous point)扮演着至关重要的角色。它允许集群内的各个成员相互认识彼此的身份信息进而协同工作。一旦该环节出现问题将会阻碍整个系统的正常运作流程。因此务必确认所选方案兼容当前硬件设施并且遵循最佳实践指南来部署相应组件[^4]。 ```python from torch.distributed.elastic.rendezvous import ( get_rendezvous_handler, ) handler = get_rendezvous_handler('c10d') rdzv_config = handler.get_rdzv_backend().get_config() print(f"Rendezvous configuration:\n{rdzv_config}") ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值