第 1 章 课程导入:DeepSpeed 概述、ZeRO 核心思想与学习路径

当你第一次尝试训练一个 7B 甚至 13B 参数的大语言模型时,最先撞上的往往不是算法问题,而是显存墙:一张 80GB 的 A100,光是模型参数、梯度、优化器状态三项加起来就可能超过 100GB。DeepSpeed 正是为解决这类"规模带来的工程瓶颈"而生的深度学习优化库。它由微软研究院推出,核心目标可以概括为一句话:让更大的模型、更长的序列、更多的设备,在有限的硬件上跑得起来、跑得更快。

本课程围绕 DeepSpeed 与 ZeRO 展开,从概念到配置、从单机到多机、从训练到推理,逐步搭建一套可落地的知识框架。本章作为导入,先回答三个问题:DeepSpeed 是什么、ZeRO 为什么有效、接下来该怎么学。

一、DeepSpeed 是什么:一个训练与推理的系统级工具箱

DeepSpeed 不是一个新模型,也不是一个新框架,而是构建在 PyTorch 之上的分布式训练与推理加速库。它的价值不在于替换 PyTorch,而在于把分布式训练中大量繁琐、易错的工程细节封装成可配置的组件。理解 DeepSpeed,关键是理解它提供的几类能力:

  • ZeRO 显存优化:对优化器状态、梯度、参数进行分片,消除数据并行中的显存冗余。
  • 混合精度与通信优化:FP16/BF16 训练、梯度压缩、通信重叠,降低带宽压力。
  • 并行策略组合:数据并行、张量并行、流水线并行可组合使用,支撑超大模型。
  • Offload 卸载:把状态或计算卸载到 CPU/NVMe,用时间换显存。
  • 推理加速:DeepSpeed-Inference 提供 kernel 融合、量化与张量并行推理。

换句话说,DeepSpeed 把"如何把模型塞进显存并高效训练"这件事,从手写通信代码变成了改几行配置。

二、ZeRO 核心思想:消除数据并行中的三份冗余

要理解 ZeRO,先看标准数据并行(DP)的问题。在 DP 中,每张卡都保存一份完整的模型副本,包括参数、梯度和优化器状态。以 Adam 为例,每个参数需要:2 字节 FP16 参数、2 字节 FP16 梯度、4 字节 FP32 主参数、4 字节动量、4 字节方差,合计约 16 字节。一个 7B 模型仅这三项就约 112GB,远超单卡容量。

ZeRO 的洞察是:这些数据在每张卡上完全重复,属于纯粹的冗余。于是它把这三类状态按 GPU 数量切分,每张卡只保留 1/N,需要时再通过通信临时聚合。ZeRO 分为三个阶段,逐级加深分片:

阶段分片对象显存收益通信代价
ZeRO-1优化器状态约 4 倍与 DP 相当
ZeRO-2优化器状态 + 梯度约 8 倍略增
ZeRO-3优化器状态 + 梯度 + 参数与 GPU 数线性明显增加

可以用一个直观的类比:DP 像每个学生都抄了一整本教材;ZeRO-1 是大家只各自保管习题答案;ZeRO-2 连草稿纸也分开;ZeRO-3 则连教材正文都拆开,谁要用哪页就去借。分得越细,人均占用越小,但借还(通信)越频繁。

数据并行显存冗余与 ZeRO 三阶段分片示意 标准 DP(每卡全量副本) GPU0 参数 P 梯度 G 优化器 O GPU1 参数 P 梯度 G 优化器 O 冗余 ×N,显存随副本线性增长 ZeRO 逐级分片 ZeRO-1 P 全量 G 全量 O 分片 1/N 仅优化器状态分片,通信开销最小 ZeRO-2 P 全量 G 分片 O 分片 梯度也分片,显存进一步下降 ZeRO-3 P 分片 G 分片 O 分片 参数也分片,显存随 GPU 数线性下降 显存占用趋势(同一模型,N 张卡) 高 低 DP ZeRO-1 ZeRO-2 ZeRO-3 → 显存下降,通信上升

三、方法流程:一次 DeepSpeed 训练的基本链路

从工程视角看,使用 DeepSpeed 训练一个模型,通常遵循如下流程:

  1. 准备 PyTorch 模型、数据集与训练循环;
  2. 编写 DeepSpeed JSON 配置,声明 batch size、精度、ZeRO 阶段、Offload 等;
  3. 用 deepspeed.initialize() 包装模型与优化器,得到 engine;
  4. 用 deepspeed 命令启动,由 launcher 负责多机多卡进程分发;
  5. 在训练循环中调用 engine.backward() 与 engine.step();
  6. 按需保存/加载 checkpoint,并监控显存与吞吐。
# 典型启动命令
deepspeed --num_gpus=8 train.py \
  --deepspeed ds_config.json \
  --model_name_or_path ./model

# ds_config.json 关键片段
{
  "train_batch_size": 64,
  "fp16": { "enabled": true },
  "zero_optimization": {
    "stage": 2,
    "offload_optimizer": { "device": "cpu" }
  }
}

可以看到,DeepSpeed 的接入成本主要集中在配置文件和启动方式上,模型代码改动很小,这也是它被广泛采用的原因之一。

四、案例与场景:不同规模下的选择

假设你手上有 8 张 40GB 的 A100,要训练不同规模的模型,选择策略大致如下:

  • 1B 以下:普通 DDP 或 ZeRO-1 即可,通信开销小,吞吐优先。
  • 1B~7B:ZeRO-2 是性价比最高的选择,梯度分片显著降显存,通信增加可接受。
  • 7B~70B:ZeRO-3 配合 CPU Offload,必要时叠加张量并行。
  • 70B 以上:ZeRO-3 + 张量并行 + 流水线并行,或使用 MoE 结构。
经验法则:先尝试 ZeRO-2,如果仍然 OOM,再升级到 ZeRO-3;不要一上来就用最重的配置,因为通信开销会直接吃掉吞吐。

五、常见误区与复盘

初学者最容易踩的坑,往往不是配置写错,而是对机制理解偏差:

  • 误区一:ZeRO 阶段越高越好。实际上 ZeRO-3 通信量最大,小模型上反而更慢,应按显存缺口选择。
  • 误区二:Offload 一定划算。CPU Offload 会引入 PCIe 传输,若 CPU 内存带宽不足,训练速度可能下降数倍。
  • 误区三:batch size 配置随意。DeepSpeed 的 train_batch_size 是全局值,需与 micro_batch_size 和梯度累积配合,否则会报错或语义不符。
  • 误区四:忽略通信与计算重叠。合理设置 bucket size 和 overlap 参数,才能让分片带来的收益真正体现。
排障提示:遇到 OOM 时,先确认是参数、梯度还是激活值占用过高。ZeRO 只解决前三者中的状态冗余,激活值需要靠梯度检查点(activation checkpointing)来压缩。

六、学习路径与整体框架

本课程后续内容将按"基础 → 配置 → 并行 → 实战 → 调优"的主线展开,建议按以下路径推进:

  1. 基础篇:分布式训练基本概念、数据并行与通信原语。
  2. ZeRO 篇:三阶段原理、显存计算、通信量分析。
  3. 配置篇:ds_config 各字段含义、精度设置、checkpoint 管理。
  4. 并行篇:张量并行、流水线并行与组合策略。
  5. 实战篇:单机多卡、多机多卡训练与推理部署。
  6. 调优篇:吞吐分析、显存排障、性能复盘。

掌握这条主线后,你将能够根据硬件条件与模型规模,独立设计一套可运行的 DeepSpeed 训练方案,并在遇到瓶颈时快速定位是显存、通信还是配置问题。这正是本课程希望交付的核心能力。