大模型分散式訓練實戰:DeepSpeed ZeRO、FSDP與多GPU最佳化

AI与大数据

摘要

  • 大模型訓練的顯存瓶頸:7B模型FP16需28GB參數+14GB梯度+14GB最佳化器=56GB,單卡A100 80GB無法訓練
  • DeepSpeed ZeRO-3透過參數分片將顯存佔用降低8倍,64卡可訓練70B模型
  • PyTorch FSDP是Meta官方方案,與PyTorch生態無縫整合,2026年已成為主流選擇
  • 3D並行(資料+張量+流水線)是訓練超大模型的標配,Megatron-LM是事實標準
  • 本文提供從單機多卡到千卡叢集的完整訓練方案,含Slurm排程與故障恢復

目錄


大模型訓練的顯存瓶頸

訓練顯存分解

┌──────────────────────────────────────────────────────────────┐
│              大模型訓練顯存分解                                 │
│                                                                │
│  模型參數(Weights):     2 × params × dtype_size               │
│  梯度(Gradients):       2 × params × dtype_size               │
│  最佳化器狀態(Adam):    12 × params × dtype_size (FP32)       │
│  活化值(Activations):   batch × seq_len × hidden × layers     │
│                                                                │
│  7B模型FP16訓練顯存:                                          │
│  ┌──────────────────────────────────────────────────────┐    │
│  │ 參數:     14GB                                       │    │
│  │ 梯度:     14GB                                       │    │
│  │ 最佳化器: 56GB (FP32的m和v)                          │    │
│  │ 活化值:   8-16GB (取決於batch和seq_len)              │    │
│  │ ─────────────────────────                            │    │
│  │ 合計:     92-100GB ❌ 超出單卡A100 80GB              │    │
│  └──────────────────────────────────────────────────────┘    │
└──────────────────────────────────────────────────────────────┘

不同規模模型的訓練需求

模型 參數量 訓練顯存(FP16+Adam) 最低GPU配置 推薦配置
1.8B 1.8B 26GB 1×A100 40GB 1×A100 80GB
7B 7B 100GB 2×A100 80GB 4×A100 80GB
13B 13B 186GB 4×A100 80GB 8×A100 80GB
70B 70B 1TB 16×A100 80GB 32×H100 80GB
671B 671B 9.6TB 128×H100 80GB 256×H100 80GB

DeepSpeed ZeRO:3階段顯存最佳化

ZeRO三階段原理

┌──────────────────────────────────────────────────────────────┐
│              ZeRO三階段顯存最佳化                               │
│                                                                │
│  ZeRO-1: 最佳化器狀態分片                                      │
│  ┌──────────────────────────────────────────────────────┐    │
│  │ 每卡只存1/N的最佳化器狀態(m和v)                        │    │
│  │ 顯存節省: 4× (最佳化器佔最大頭)                        │    │
│  │ 通訊量: 與DDP相同                                     │    │
│  └──────────────────────────────────────────────────────┘    │
│                                                                │
│  ZeRO-2: 最佳化器+梯度分片                                    │
│  ┌──────────────────────────────────────────────────────┐    │
│  │ 每卡只存1/N的最佳化器狀態+梯度                         │    │
│  │ 顯存節省: 8×                                          │    │
│  │ 通訊量: 與DDP相同(梯度reduce-scatter)                 │    │
│  └──────────────────────────────────────────────────────┘    │
│                                                                │
│  ZeRO-3: 最佳化器+梯度+參數分片                               │
│  ┌──────────────────────────────────────────────────────┐    │
│  │ 每卡只存1/N的所有狀態                                  │    │
│  │ 顯存節省: N× (N=GPU數)                                │    │
│  │ 通訊量: 增加1.5× (需要all-gather參數)                 │    │
│  └──────────────────────────────────────────────────────┘    │
└──────────────────────────────────────────────────────────────┘

DeepSpeed ZeRO-3訓練配置

{
  "train_batch_size": 128,
  "train_micro_batch_size_per_gpu": 2,
  "gradient_accumulation_steps": 8,
  "zero_optimization": {
    "stage": 3,
    "offload_optimizer": {
      "device": "cpu",
      "pin_memory": true
    },
    "offload_param": {
      "device": "cpu",
      "pin_memory": true
    },
    "overlap_comm": true,
    "contiguous_gradients": true,
    "sub_group_size": 1e9,
    "reduce_bucket_size": "auto",
    "stage3_prefetch_bucket_size": "auto",
    "stage3_param_persistence_threshold": "auto",
    "stage3_max_live_parameters": 1e9,
    "stage3_max_reuse_distance": 1e9,
    "stage3_gather_16bit_weights_on_model_save": true
  },
  "bf16": {
    "enabled": true
  },
  "gradient_clipping": 1.0,
  "prescale_gradients": false,
  "wall_clock_breakdown": false
}

ZeRO各階段顯存對比(7B模型,8×A100 80GB)

階段 參數 梯度 最佳化器 活化值 總計 每卡
DDP 14GB 14GB 56GB 12GB 96GB 96GB
ZeRO-1 14GB 14GB 7GB 12GB 47GB 47GB
ZeRO-2 14GB 1.75GB 7GB 12GB 35GB 35GB
ZeRO-3 1.75GB 0.22GB 0.88GB 12GB 15GB 15GB

DeepSpeed啟動腳本

deepspeed --num_gpus=8 \
    --num_nodes=2 \
    --master_addr=$MASTER_ADDR \
    --master_port=29500 \
    train.py \
    --model_name_or_path Qwen/Qwen2.5-7B \
    --data_path ./data/train.jsonl \
    --bf16 \
    --deepspeed ds_config_z3.json \
    --per_device_train_batch_size 2 \
    --gradient_accumulation_steps 8 \
    --learning_rate 2e-5 \
    --num_train_epochs 3 \
    --warmup_ratio 0.03 \
    --lr_scheduler_type cosine \
    --weight_decay 0.01 \
    --save_strategy epoch \
    --output_dir ./output \
    --gradient_checkpointing true \
    --logging_steps 10 \
    --report_to tensorboard

PyTorch FSDP:Meta官方方案

FSDP vs DeepSpeed ZeRO

維度 DeepSpeed ZeRO-3 PyTorch FSDP
開發方 Microsoft Meta
整合度 獨立函式庫 PyTorch原生
參數分片
梯度分片
最佳化器分片
CPU卸載
混合精度
流水線並行 ✅ (DeepSpeed PP) ⚠️ (需手動)
除錯友善度 高(PyTorch原生)
社群活躍度 ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐

FSDP訓練程式碼

import torch
from torch.distributed.fsdp import FullyShardedDataParallel as FSDP
from torch.distributed.fsdp import ShardingStrategy, MixedPrecision
from torch.distributed.fsdp.wrap import transformer_auto_wrap_policy
from transformers import AutoModelForCausalLM, AutoTokenizer

torch.distributed.init_process_group(backend="nccl")
local_rank = int(os.environ["LOCAL_RANK"])
torch.cuda.set_device(local_rank)

model = AutoModelForCausalLM.from_pretrained(
    "Qwen/Qwen2.5-7B",
    torch_dtype=torch.bfloat16,
    device_map={"": local_rank},
)

mp_policy = MixedPrecision(
    param_dtype=torch.bfloat16,
    reduce_dtype=torch.bfloat16,
    buffer_dtype=torch.bfloat16,
)

auto_wrap_policy = transformer_auto_wrap_policy(
    transformer_layer_names=["Qwen2DecoderLayer"],
)

model = FSDP(
    model,
    sharding_strategy=ShardingStrategy.FULL_SHARD,
    mixed_precision=mp_policy,
    auto_wrap_policy=auto_wrap_policy,
    device_id=local_rank,
    use_orig_params=True,
)

optimizer = torch.optim.AdamW(model.parameters(), lr=2e-5, weight_decay=0.01)
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=1000)

for epoch in range(num_epochs):
    for batch in dataloader:
        batch = {k: v.to(local_rank) for k, v in batch.items()}
        outputs = model(**batch)
        loss = outputs.loss
        loss.backward()
        optimizer.step()
        scheduler.step()
        optimizer.zero_grad()

3D並行:資料+張量+流水線

3D並行架構

┌──────────────────────────────────────────────────────────────┐
│              3D並行架構                                        │
│                                                                │
│  資料並行(DP): 4組 × 每組4卡                                   │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  DP組0          DP組1          DP組2          DP組3   │    │
│  │  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────┐│    │
│  │  │ TP=2     │  │ TP=2     │  │ TP=2     │  │TP=2  ││    │
│  │  │ PP=2     │  │ PP=2     │  │ PP=2     │  │PP=2  ││    │
│  │  │ ┌──┬──┐ │  │ ┌──┬──┐ │  │ ┌──┬──┐ │  │┌──┬─┐││    │
│  │  │ │G0│G1│ │  │ │G4│G5│ │  │ │G8│G9│ │  ││12│13│││    │
│  │  │ ├──┼──┤ │  │ ├──┼──┤ │  │ ├──┼──┤ │  │├──┼──┤││    │
│  │  │ │G2│G3│ │  │ │G6│G7│ │  │ │10│11│ │  ││14│15│││    │
│  │  │ └──┴──┘ │  │ └──┴──┘ │  │ └──┴──┘ │  │└──┴──┘││    │
│  │  └──────────┘  └──────────┘  └──────────┘  └──────┘│    │
│  └──────────────────────────────────────────────────────┘    │
│                                                                │
│  TP=張量並行(層內切分)  PP=流水線並行(層間切分)                │
│  DP=資料並行(資料切分)  總計16卡                               │
└──────────────────────────────────────────────────────────────┘

3D並行選擇決策

模型規模 GPU數 推薦並行策略 說明
7B 8 DP=8 純資料並行即可
13B 16 DP=8, TP=2 加入張量並行
70B 64 DP=8, TP=4, PP=2 3D並行
671B 256 DP=16, TP=8, PP=2 3D並行+ZeRO

多節點訓練與故障恢復

Slurm啟動腳本

#!/bin/bash
#SBATCH --job-name=llm-train
#SBATCH --nodes=4
#SBATCH --ntasks-per-node=8
#SBATCH --gres=gpu:8
#SBATCH --cpus-per-task=8
#SBATCH --mem=512G
#SBATCH --time=72:00:00
#SBATCH --partition=gpu-a100

export MASTER_ADDR=$(scontrol show hostname $SLURM_JOB_NODELIST | head -n1)
export MASTER_PORT=29500
export NCCL_DEBUG=INFO
export NCCL_IB_DISABLE=0
export NCCL_IB_HCA=mlx5

srun torchrun \
    --nnodes=$SLURM_JOB_NUM_NODES \
    --nproc_per_node=8 \
    --rdzv_id=$SLURM_JOB_ID \
    --rdzv_backend=c10d \
    --rdzv_endpoint=$MASTER_ADDR:$MASTER_PORT \
    train.py \
    --model_name_or_path Qwen/Qwen2.5-7B \
    --deepspeed ds_config_z3.json \
    --per_device_train_batch_size 2 \
    --gradient_accumulation_steps 8 \
    --learning_rate 2e-5 \
    --num_train_epochs 3 \
    --output_dir ./output \
    --save_strategy steps \
    --save_steps 500 \
    --save_total_limit 5

訓練故障恢復

from transformers import Trainer

class FaultTolerantTrainer(Trainer):
    def _save_checkpoint(self, model, trial, metrics=None):
        super()._save_checkpoint(model, trial, metrics)
        self._save_training_state()

    def _save_training_state(self):
        state = {
            "global_step": self.state.global_step,
            "epoch": self.state.epoch,
            "rng_state": torch.cuda.get_rng_state().cpu().numpy().tolist(),
        }
        with open(f"{self.args.output_dir}/training_state.json", "w") as f:
            json.dump(state, f)

    def _load_training_state(self):
        state_path = f"{self.args.output_dir}/training_state.json"
        if os.path.exists(state_path):
            with open(state_path) as f:
                state = json.load(f)
            return state
        return None

訓練效能最佳化Checklist

最佳化項目 效果 配置
Flash Attention 2 訓練速度+30% attn_implementation="flash_attention_2"
梯度檢查點 顯存-40% gradient_checkpointing=True
BF16混合精度 顯存-50% bf16=True
NCCL IB通訊 通訊延遲-60% NCCL_IB_DISABLE=0
預取分片參數 通訊計算重疊 stage3_prefetch_bucket_size
梯度累積 等效大batch gradient_accumulation_steps=8

總結與延伸閱讀

大模型分散式訓練的核心是顯存最佳化和通訊最佳化。DeepSpeed ZeRO-3透過參數分片將顯存降低N倍,FSDP是PyTorch原生方案更易除錯,3D並行是超大模型的標配。

訓練要點回顧

  1. ZeRO-3是顯存最佳化的終極方案,但通訊量增加1.5倍
  2. FSDP是PyTorch原生方案,2026年已成為主流選擇
  3. 3D並行:7B用DP,13B加TP,70B+用DP+TP+PP
  4. Flash Attention 2 + 梯度檢查點是訓練標配
  5. 故障恢復和Checkpoint是長時間訓練的剛需

延伸閱讀

權威參考

本站提供瀏覽器本地工具,免註冊即可試用 →

#大模型分布式训练#DeepSpeed ZeRO#FSDP训练#Megatron-LM#多GPU训练优化#2026