Transformers documentation

DDP

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

DDP

DistributedDataParallel (DDP) 在每张 GPU 上维护一份完整的模型副本。每张 GPU 处理数据的一个不重叠分片,并执行前向和反向传播。在优化器步骤之前,通过 all-reduce 在所有 GPU 之间对梯度求平均,以确保每个模型副本保持一致。当模型可以放入单张 GPU 时,请使用 DDP。

                         ┌─────────────────┐
                         │  training data  │
                         └────────┬────────┘
               ┌──────────────────┼──────────────────┐
               │ shard 0          │ shard 1          │ shard 2
               ▼                  ▼                  ▼
        ┌─────────────┐    ┌─────────────┐    ┌─────────────┐
        │   model     │    │   model     │    │   model     │
        │  (copy 0)   │    │  (copy 1)   │    │  (copy 2)   │
        │   GPU 0     │    │   GPU 1     │    │   GPU 2     │
        └──────┬──────┘    └──────┬──────┘    └──────┬──────┘
               │ grads            │ grads            │ grads
               └──────────────────┼──────────────────┘
                               all-reduce
                          (average gradients)
               ┌──────────────────┼──────────────────┐
               ▼                  ▼                  ▼
        ┌─────────────┐    ┌─────────────┐    ┌─────────────┐
        │  optimizer  │    │  optimizer  │    │  optimizer  │
        │    step     │    │    step     │    │    step     │
        └─────────────┘    └─────────────┘    └─────────────┘
          (identical)        (identical)        (identical)

使用 Accelerate 等多进程启动器启动时,DDP 会自动激活。

# 4 GPUs on one machine
accelerate launch --num_processes 4 train.py

配置 DDP

将这些 TrainingArguments 传入以控制 DDP 行为。

  • gradient_accumulation_steps() 决定了何时执行 all-reduce。Trainer 会在中间的累积步骤中跳过 all-reduce,仅在最后一个 micro-batch 上执行。例如,当 gradient_accumulation_steps=4 时,all-reduce 每 4 次反向传播执行一次。
  • ~TrainingArguments.ddp_find_unused_parameters 会在前向传播结束时遍历 autograd 图,找出不会接收梯度的参数并将其标记为就绪,以免阻塞 all-reduce。请勿与 ~TrainingArguments.gradient_checkpointing 一起使用,因为梯度检查点会丢弃中间激活值并在需要时重新计算。
  • ~TrainingArguments.ddp_bucket_cap_mb 是反向传播过程中将梯度批量合并为单次 all-reduce 的桶大小。桶越大,all-reduce 调用次数越少,启动开销也越小。
  • ~TrainingArguments.ddp_broadcast_buffers 会在每次前向传播开始时,将模型缓冲区(例如 BatchNorm 的运行统计量)从 rank 0 同步到所有其他 rank。如果您的模型仅使用 LayerNorm,请禁用此选项。请勿与 ~TrainingArguments.gradient_checkpointing 一起使用。
  • ~TrainingArguments.ddp_backend 用于设置通信后端。对于 NVIDIA GPU,请使用 "nccl"(默认且速度最快);对于 CPU 训练或调试,请使用 "gloo";对于其他硬件,请使用 "xccl"、"hccl" 或 "cncl"。
  • ddp_timeout() 为所有进程和操作(all-reduce、broadcast)设置完成时限。如果某个进程挂起(例如加载大型模型时速度较慢),超时机制会抛出错误,而不是无限期阻塞。
from transformers import TrainingArguments

args = TrainingArguments(
    ...,
    gradient_accumulation_steps=4,
    ddp_backend="nccl",
    ddp_find_unused_parameters=False,
    ddp_bucket_cap_mb=25,
    ddp_broadcast_buffers=True,
    ddp_timeout=1800,
)

后续步骤

  • 有关训练无法在单个 GPU 上容纳的过大模型,请参阅 FSDP。
  • 有关 ZeRO 优化和卸载,请参阅 DeepSpeed。
  • 阅读《The Ultra-Scale Playbook》中的数据并行章节,以了解 DDP 的工作原理。
Update on GitHub