深度学习-分布式训练机制

1、分布式训练时,包括train.py的全部的代码都会在每个gpu上运行吗?

  • 在分布式训练(如使用 PyTorch 的 DistributedDataParallel,DDP)时,每个 GPU 上运行的进程会执行 train.py 的全部代码,但通过分布式机制(如 rank、world_size、torch.distributed 等)控制不同进程的行为,确保它们协作完成训练任务。
  • 每个 GPU 对应一个独立的进程,每个进程都会从头到尾完整执行 train.py 的代码(包括数据加载、模型初始化、前向/反向传播等)。但通过条件判断和分布式通信,不同进程会执行不同的逻辑分支(例如:仅 rank=0 的进程保存模型、打印日志等)。
    2、解释下面分布式训练的启动代码
python 复制代码
CONFIG=$1
GPUS=$2
PORT=${PORT:-28651}

PYTHONPATH="$(dirname $0)/..":$PYTHONPATH \
python3 -m torch.distributed.launch --nproc_per_node=$GPUS --master_port=$PORT \
    $(dirname "$0")/train.py $CONFIG --launcher pytorch ${@:3}

这段代码是一个用于启动分布式训练的 Bash 脚本,通常用于 PyTorch 的 DistributedDataParallel (DDP) 训练。它通过 torch.distributed.launch 启动多个进程(每个 GPU 一个进程),并传递必要的参数。
3、torch.distributed.launch后面接的train.py的位置可以任意吗?

Python 解释器在执行脚本时,会根据提供的路径(绝对路径、相对路径或模块名)动态定位文件,只要路径有效即可。torch.distributed.launch 只是将 train.py 的路径传递给 Python 解释器,由解释器负责加载文件,因此路径格式只需符合 Python 的规则即可。

torch.distributed.launch 后面接的训练脚本名称 可以是任意有效的 Python 脚本文件名,只需满足以下条件:

后缀必须是 .py:因为 torch.distributed.launch 最终会调用 Python 解释器执行该文件。

文件名允许任意命名:如 train.pymain.py、custom_script.py 均可,只需文件内容符合训练逻辑。
4、解释下面分布式训练的初始化代码

python 复制代码
dist_params = dict(backend="nccl")
init_dist(
            args.launcher, timeout=timedelta(seconds=3600), **cfg.dist_params
        )
  • 指定启动器为pytorch,指定gpu间的通信为"nccl",设置通信超时为1小时,定义一个字典 dist_params,指定分布式训练的后端通信库为 NCCL(NVIDIA Collective Communications Library)。"nccl" 指定分布式训练使用的通信后端,nccl 是 NVIDIA GPU 间高效通信的库,适用于多 GPU 训练。
  • 底层实现(PyTorch 分布式核心)
    init_dist 函数内部通常会调用 PyTorch 的 torch.distributed.init_process_group,关键逻辑如下:
python 复制代码
import torch.distributed as dist
def init_dist(launcher, **kwargs):
    if launcher == "pytorch":
        dist.init_process_group(**kwargs)  # 实际初始化分布式环境
    elif launcher == "slurm":
        # SLURM 集群的特殊处理
        ...

init_process_group 的关键参数

backend:通信后端(如 "nccl")。

init_method:进程组初始化方式(如 "env://" 表示通过环境变量自动发现)。

world_size:全局进程数(通常由启动器自动设置)。

rank:当前进程的全局编号(由启动器自动设置)。

进程组操作的超时时间(timeout) 是指分布式进程组(Process Group)在执行集体通信操作(如梯度同步、数据广播等)时的最大等待时间。如果操作在指定时间内未完成,会触发超时错误(torch.distributed.DistBackendError)。
5、梯度同步

梯度同步的基本流程

(1) 前向传播

每个 GPU 独立处理自己分配到的数据(一个 mini-batch 的子集),计算 本地损失(local loss)。

注意:每个 GPU 的损失是基于其本地数据计算的,不是全局所有数据的平均损失。

(2) 反向传播

每个 GPU 根据本地损失计算 本地梯度(即对模型参数的偏导数)。

此时各 GPU 的梯度可能不同(因数据不同)。

(3) 梯度同步(关键步骤)

通过 All-Reduce 操作(通常是求和或平均)将所有 GPU 的梯度同步,得到全局一致的梯度。

同步后的梯度 = 所有 GPU 本地梯度的均值(若使用 平均)或总和(若使用 求和)。

(4) 参数更新

所有 GPU 使用同步后的全局梯度更新模型参数(保证所有 GPU 的模型始终保持一致)。

6、既然每个gpu独立计算本地损失,那每次训练迭代后,可视化的损失是如何计算的

在分布式训练中,可视化的损失值通常是通过对多个 GPU 的本地损失进行聚合计算得到的。具体计算方式和实现逻辑如下:

损失计算的基本流程

在分布式训练(如 PyTorch 的 DistributedDataParallel)中,每个 GPU 独立处理一部分数据(batch_size / num_gpus),并按以下步骤计算损失:

前向传播:

每个 GPU 用当前模型参数计算其本地数据的预测结果。

计算 本地损失(如交叉熵、MSE),假设为 loss_local。

反向传播:

根据本地损失计算梯度(loss_local.backward())。

通过 All-Reduce 同步梯度(梯度取平均或求和,取决于配置)。

损失聚合:

为了可视化或日志记录,需要将所有 GPU 的本地损失聚合为 全局损失。

  1. 损失聚合的常见方法

(1) 直接求平均(默认推荐)

公式:

global_loss=1N∑i=1Nloss_locali

global_loss=N1​i=1∑N​loss_locali​

NN 是 GPU 数量(world_size)。

物理意义:所有 GPU 本地损失的均值,等价于单卡使用全局 batch 计算的损失。

PyTorch 实现:

python 复制代码
import torch.distributed as dist
# 计算本地损失(每个 GPU 的 batch 是总 batch 的一部分)
loss_local = criterion(output, target)
# 聚合所有 GPU 的损失(求平均)
dist.all_reduce(loss_local, op=dist.ReduceOp.SUM)  # 先求和
global_loss = loss_local / dist.get_world_size()    # 再除以 GPU 数量
相关推荐
2201_7549184142 分钟前
OpenCV 背景建模详解:从原理到实战
人工智能·opencv·计算机视觉
CopyLower1 小时前
苹果计划将AI搜索集成至Safari:谷歌搜索下降引发的市场变革
前端·人工智能·safari
wd2099881 小时前
2025年Ai写PPT工具推荐,这5款Ai工具可以一键生成专业PPT
人工智能
张飞飞飞飞飞1 小时前
语音识别——声纹识别
人工智能·语音识别
archko2 小时前
语音识别-3,添加ai问答
android·人工智能
Bowen_CV4 小时前
AI 赋能防艾宣传:从创意到实践,我的 IP 形象设计之旅
人工智能·3d建模·豆包·造好物·腾讯混元 3d
你是一个铁憨憨4 小时前
使用深度学习预训练模型检测物体
人工智能·深度学习·arcgis·影像
AI算法工程师Moxi5 小时前
什么时候可以开始学习深度学习?
人工智能·深度学习·学习
好评笔记5 小时前
Meta的AIGC视频生成模型——Emu Video
人工智能·深度学习·机器学习·aigc·transformer·校招·面试八股
思通数据7 小时前
AI全域智能监控系统重构商业清洁管理范式——从被动响应到主动预防的监控效能革命
大数据·人工智能·目标检测·机器学习·计算机视觉·数据挖掘·ocr