课程导入:ZeRO-Offload 概述、异构计算背景与学习框架

当大模型参数从十亿级迈向千亿级,单张 GPU 的显存很快成为训练瓶颈。以 13B 参数模型为例,若采用 Adam 混合精度训练,仅模型状态(参数、梯度、优化器动量与方差)就需要约 13 × (2 + 2 + 4 + 4) = 156 GB 显存,远超单卡 80 GB 的容量。传统做法是增加 GPU 数量做数据并行,但每张卡仍需保存完整模型状态,显存冗余极高。ZeRO-Offload 正是在这一矛盾下提出的关键技术:它把优化器状态与梯度计算卸载到 CPU 内存,让单张 GPU 也能训练远超其显存容量的模型。

一、异构计算背景:GPU 与 CPU 的分工

现代训练服务器本质是一个异构计算系统:GPU 拥有极高带宽的 HBM 与海量并行算力,适合矩阵乘法、卷积等计算密集型算子;CPU 拥有大容量 DDR 内存与较强的标量/分支控制能力,适合优化器更新、数据预处理等访存密集型任务。二者通过 PCIe 或 NVLink 连接,带宽通常为 16~64 GB/s,远低于 GPU 内部 HBM 的 1~3 TB/s。

ZeRO-Offload 的核心洞察是:优化器更新(如 Adam)计算量小但显存占用大,属于“低计算强度、高内存占用”操作,把它放到 CPU 上执行,用 CPU 内存承载优化器状态,GPU 只保留前向与反向所需参数,就能用有限的 PCIe 带宽换取数倍的显存节省。下图展示了这一异构分工与数据流关系:

ZeRO-Offload 异构计算数据流 GPU(HBM 显存) FP16 参数分片 前向 / 反向计算 FP16 梯度分片 反向传播产生 激活值 / 中间结果 按需重算或保留 CPU(DDR 内存) FP32 优化器状态 动量 m / 方差 v FP32 参数副本 用于更新计算 Adam 更新算子 CPU 端执行 梯度卸载 参数回传 状态同步 PCIe / NVLink 互联带宽:16~64 GB/s,是卸载策略的关键约束

二、ZeRO-Offload 的核心原理

ZeRO-Offload 建立在 ZeRO(Zero Redundancy Optimizer)的分片思想之上。ZeRO 将模型状态切分到多张 GPU,消除数据并行中的显存冗余;而 ZeRO-Offload 进一步把切分后的优化器状态与梯度“下沉”到 CPU 内存,形成三级存储层次:

  • GPU HBM:存放当前计算所需的 FP16 参数分片与激活值,容量最小、带宽最高。
  • CPU DDR:存放 FP32 优化器状态(动量、方差)与 FP32 参数副本,容量大、带宽中等。
  • NVMe SSD(可选):在 CPU 内存仍不足时,可进一步将优化器状态换出到磁盘,形成 ZeRO-Infinity 的扩展。

其单步训练流程可概括为:GPU 完成前向与反向,得到 FP16 梯度分片;将梯度从 GPU 拷贝到 CPU;CPU 用 FP32 优化器状态执行 Adam 更新,得到新的 FP32 参数;再将更新后的参数转回 FP16 并拷贝回 GPU,供下一轮前向使用。整个过程通过计算与通信的重叠(overlap)隐藏 PCIe 传输延迟。

关键公式:Adam 更新在 CPU 端执行,每个参数需要读取 m、v、param 三个 FP32 张量,写回 param 与 m、v,共约 6 次访存。由于计算强度低,CPU 的标量算力足以胜任,而 GPU 得以专注于高密度的矩阵运算。

三、方法流程与配置示例

在 DeepSpeed 中启用 ZeRO-Offload 只需在配置文件中声明 offload 设备。以下是一个典型配置片段:

{
  "train_batch_size": 64,
  "fp16": { "enabled": true },
  "zero_optimization": {
    "stage": 2,
    "offload_optimizer": {
      "device": "cpu",
      "pin_memory": true
    },
    "offload_param": {
      "device": "cpu",
      "pin_memory": true
    },
    "overlap_comm": true,
    "contiguous_gradients": true
  }
}

其中 stage 决定分片粒度:stage 1 仅切分优化器状态,stage 2 增加梯度切分,stage 3 进一步切分参数。ZeRO-Offload 常与 stage 2 搭配,在显存节省与通信开销之间取得平衡。pin_memory 启用锁页内存,可提升 CPU-GPU 拷贝效率;overlap_comm 让通信与计算重叠,是保持吞吐的关键开关。

四、典型场景与误区复盘

ZeRO-Offload 最适合“GPU 显存受限、CPU 内存充足、互联带宽较高”的场景,例如单机 8 卡 A100 训练 10B~70B 模型。但它并非万能:若 PCIe 带宽不足或 CPU 核心数过少,优化器更新会成为瓶颈,训练速度可能下降 30%~50%。

常见误区 现象 正确做法
认为 Offload 一定更快 训练吞吐反而下降 先评估 PCIe 带宽与 CPU 核数,必要时仅卸载优化器状态
忽略 pin_memory 拷贝延迟高、GPU 空转 开启锁页内存并配合 overlap_comm
stage 3 与 Offload 盲目叠加 通信量激增,扩展性变差 优先 stage 2 + offload_optimizer,按需再切参数
CPU 内存未预留足够空间 OOM 或频繁换页 按 16~20 字节/参数估算 CPU 内存需求

学习建议:本课程后续将依次拆解 ZeRO 三级分片机制、CPU Adam 算子实现、梯度卸载流水线、通信重叠策略与性能调优方法。建议先建立“GPU 算、CPU 存、PCIe 传”的整体心智模型,再深入每个模块的源码与参数细节。

五、本课程整体框架

围绕“异构计算底层解密”这一主线,课程将分为五个模块:基础篇讲解 ZeRO 与 Offload 的动机和存储层次;原理篇剖析分片、卸载与重计算机制;实现篇深入 DeepSpeed 源码中的 CPU Adam、梯度桶与流水线;调优篇覆盖带宽、重叠、批大小与并行策略的联合优化;实战篇通过单机多卡与多机场景完成端到端训练复现。掌握这些内容后,你将能够独立判断何时启用 Offload、如何配置参数,并定位训练中的显存与吞吐瓶颈。