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

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 数量
相关推荐
FairyGirlhub14 小时前
神经网络的初始化:权重与偏置的数学策略
人工智能·深度学习·神经网络
zzhongcy15 小时前
分布式存储:RustFS与MinIO全面对比
分布式
一叶飘零_sweeeet18 小时前
从手写 Redis 分布式锁到精通 Redisson:分布式系统的并发控制终极指南
redis·分布式·redisson
大写-凌祁19 小时前
零基础入门深度学习:从理论到实战,GitHub+开源资源全指南(2025最新版)
人工智能·深度学习·开源·github
焦耳加热19 小时前
阿德莱德大学Nat. Commun.:盐模板策略实现废弃塑料到单原子催化剂的高值转化,推动环境与能源催化应用
人工智能·算法·机器学习·能源·材料工程
深空数字孪生19 小时前
储能调峰新实践:智慧能源平台如何保障风电消纳与电网稳定?
大数据·人工智能·物联网
wan5555cn19 小时前
多张图片生成视频模型技术深度解析
人工智能·笔记·深度学习·算法·音视频
格林威20 小时前
机器视觉检测的光源基础知识及光源选型
人工智能·深度学习·数码相机·yolo·计算机视觉·视觉检测
今天也要学习吖21 小时前
谷歌nano banana官方Prompt模板发布,解锁六大图像生成风格
人工智能·学习·ai·prompt·nano banana·谷歌ai
Hello123网站21 小时前
glean-企业级AI搜索和知识发现平台
人工智能·产品运营·ai工具