Chapter 07

全参数微调:DeepSpeed & FSDP

当 LoRA 的效果触及上限时,全参数微调是唯一选择。掌握多机多卡分布式训练的核心概念。

何时需要全参数微调

大多数场景 LoRA/QLoRA 已经足够,但以下情况考虑全参数微调:

DeepSpeed ZeRO:分割显存压力

ZeRO Stage 1 — 分割优化器状态
Adam 优化器状态(momentum、variance)分散到各 GPU,每张 GPU 显存减少约 4×(8 GPU)。梯度和参数仍然每卡一份。
ZeRO Stage 2 — 分割梯度 + 优化器状态
在 Stage 1 基础上,梯度也分散存储。总节省约 8×(8 GPU)。训练速度基本不受影响,是多数场景的推荐选择。
ZeRO Stage 3 — 分割参数 + 梯度 + 优化器
模型参数本身也分散存储。总节省约 64×(8 GPU)。但 forward 需要 all-gather 参数,通信开销较大。适合极大模型(70B+)。

DeepSpeed 配置

{
  "zero_optimization": {
    "stage": 2,
    "overlap_comm": true,
    "contiguous_gradients": true,
    "sub_group_size": 1e9,
    "reduce_bucket_size": "auto",
    "stage3_prefetch_bucket_size": "auto",
    "stage3_param_persistence_threshold": "auto",
    "gather_16bit_weights_on_model_save": true
  },
  "bf16": {"enabled": true},
  "gradient_clipping": 1.0,
  "train_micro_batch_size_per_gpu": 4,
  "gradient_accumulation_steps": 4
}

启动多 GPU 训练

# 单机 8 GPU 训练
deepspeed --num_gpus=8 train.py \
  --deepspeed ds_config.json \
  --model_name_or_path meta-llama/Meta-Llama-3-8B \
  --dataset_path data/train.jsonl \
  --output_dir ./output \
  --num_train_epochs 3

# 或使用 torchrun(FSDP)
torchrun --nproc_per_node=8 \
  --master_addr="localhost" \
  --master_port=29500 \
  train_fsdp.py

FSDP vs DeepSpeed 选择

特性FSDPDeepSpeed ZeRO
来源PyTorch 原生微软独立库
集成难度较简单需要配置 JSON
HuggingFace 集成Trainer 原生支持需要 deepspeed 库
多机支持
CPU Offload有限强大(可卸载到 CPU/NVMe)
推荐场景单机多卡,7B-30B多机多卡,30B+

全参数微调训练技巧

使用更低的学习率
全参数微调的学习率通常比 LoRA 低 10 倍:1e-5 到 5e-5。过高学习率会"灾难性遗忘"预训练知识。
Flash Attention 2
安装 flash-attn 可将 Attention 计算速度提升 2-4 倍,显存降低 50%。这是全参数微调的必选项。
混合精度 BF16
使用 BF16 而不是 FP16。BF16 数值范围更大,不容易出现 loss scaling 相关的训练不稳定问题。
本章小结 全参数微调适合大数据集和极高精度要求。ZeRO Stage 2 是多数场景的最佳起点,Flash Attention + BF16 是标配优化。下一章进入 DPO 偏好对齐训练。