每卡算出局部贡献,求和后人人得到完整结果
典型用于 DP 梯度同步。通信量与模型梯度大小相关,可用 bucket/overlap 与 backward 重叠。
g = Σ_i g_i
ENGINEERING EXTENSION / TRAINING SYSTEMS
参数、梯度、优化器、激活、层、专家和序列都可以被切分,但每一种切法换来不同的 collective、内存和调度。 精度又决定每份状态占多少 bytes。下面按切分对象和通信方式逐项分析。
切换一种并行方式,看权重、梯度、优化器、activation 与 batch 分布怎样变化。
DATA PARALLEL
每卡有完整权重、梯度和优化器状态,适合单卡放得下训练状态的情况。梯度用 all-reduce 同步;DDP 可在梯度桶就绪后发起通信,与反向计算重叠。
batch
all-reduce gradients
每卡完整训练状态放不下
bits 减少会同时改变显存、带宽、吞吐与数值稳定性;不同变量可以使用不同精度。
| 格式 | bits / 结构 | 常见用途 | 优势 | 主要风险 |
|---|---|---|---|---|
| FP32 | 1 sign + 8 exp + 23 fraction · 32b | master weights、较高精度优化器状态、诊断 | 范围与精度高 | 仍有舍入误差;存储成本高于低位格式 |
| TF32 | Ampere 为例:8 exp + 10 fraction | 部分 FP32 矩阵乘/卷积加速 | 该模式以 FP32 存储和累加 | 乘法输入精度低于 FP32;依赖硬件与 kernel |
| BF16 | 1 sign + 8 exp + 7 fraction · 16b | 训练 activation/参数、KV Cache | 范围接近 FP32,通常无需传统 loss scaling | 尾数少,累加和细腻差异仍需注意 |
| FP16 | 1 sign + 5 exp + 10 fraction · 16b | 部分推理、训练 mixed precision | 正规数的小数位多于 BF16、硬件成熟 | 指数范围小,可能出现 overflow/underflow |
| FP8 | E4M3 / E5M2 · 8b | 受支持的训练与推理 kernel | 显存/带宽明显下降 | 需要 scaling、分组配置,并检查数值误差 |
| INT8 / INT4 | 整数 + scale / group | 权重量化、部分激活/KV | 服务吞吐和内存友好 | 误差累积、outlier 与 kernel/模型结构依赖强 |
权重、梯度、master copy、Adam m/v、activation、KV Cache 可以各有不同精度,应分别记录各自的字节数。
Softmax、norm、loss 与 accumulation 常需要更高精度;低精度 kernel 是否安全必须用真实数据验证。
量化收益取决于 kernel 支持;格式转换和额外访存可能抵消部分节省。
下面的估算显示单层关键中间张量。实际反传会保留一部分 activation,框架与重算策略差异很大。
可以避免显式保存完整 T×T 矩阵,显存更接近随 B·T·d 线性增长;但反向仍需保存/重算部分中间量,通信与 kernel 支持也会影响结果。
计数假设 MHA 的 Q/K/V 都有 H 个头,模型宽度为 H×head dim;元素数分别为 BH T²、3BT H·head dim、2BTF 和 BT H·head dim,再乘每元素字节数。gate/up 只数两路投影,不含 SiLU、逐元素乘积或 down projection 的额外中间量。面板不是反传保存清单或总峰值;GQA、融合算子、重算、临时 workspace 与通信缓冲需另算。FP8 选项仅按 1 byte 计数,不表示这些张量都能使用 FP8 kernel,也未计缩放元数据。
集合通信会占用带宽并造成等待,需要放进完整执行时间线分析。
典型用于 DP 梯度同步。通信量与模型梯度大小相关,可用 bucket/overlap 与 backward 重叠。
g = Σ_i g_i
ZeRO/FSDP 常用来规约梯度并保留本卡分片,再更新本卡拥有的优化器状态;Adam 的 m/v 按各自参数分片维护。计算所需的参数分片之后还可能需要 all-gather。
reduce → shard
ZeRO-3/FSDP 计算层前重聚参数,TP 也常用。频繁 gather 会把参数分片省下的显存换成带宽压力。
shards → full
MoE expert parallel 的核心通信。路由不均衡时,某些设备成为热点;需要容量、负载均衡与调度。
tokens ↔ experts
Pipeline Parallel 将层分给不同阶段,再把 batch 拆成 microbatch。后阶段等待前阶段的激活,前阶段的反向等待后阶段的梯度。调度改变空闲位置和激活保留时间;本例所有 microbatch 完成反向后才更新权重。
依赖操作必须在前一 tick 完成;每个阶段每 tick 至多执行一项。GPipe 采用全前向屏障,1F1B 采用 warmup、交替和 cooldown。
| 阶段 | 前向次数 | 反向次数 | 保留激活峰值 |
|---|
F/B 后数字为 microbatch 编号。激活以每阶段、每 microbatch 一份计数,反向结束后释放;不含张量尺寸、重算和传输缓冲。逻辑 tick 不预测真实时延。
1F1B 可让已完成前向的激活更早被反向消费,通常能降低某些阶段的保留峰值;在本例同速、零通信假设下,完成时间未必比 GPipe 更短。实际模型阶段耗时不等,通信、重算、虚拟阶段和调度交错都会改变结果。
Microbatch 增多可以更充分填充流水线,但同时改变每次更新的样本组织。比较必须保持全局目标、梯度缩放与权重版本语义一致。异步更新或不同版本权重属于另一类协议,不能直接套用本例的同权重对照。
DeepSeek-V3 的 DualPipe 将前向/反向 chunk 细分为 Attention、专家分派、MLP 与合并;反向再分输入梯度与权重梯度,并用双向流水线和计算—通信重叠改善执行。原报告还给出参数副本与激活的代价;这些条件不能从一个“并行”标签里省略。
下面是受该分解思路启发的有限调度教具,不是完整 DualPipe:一个新 microbatch 的前向 F,搭配一个旧 microbatch 的反向 B;一条独占计算通道、一条独占通信通道。计算操作均为 2 tick,四次通信先设为 3 tick,操作不抢占;只允许不同通道重叠。
F 的依赖为 FA→FD→FM→FC。旧反向先经 BC 回传合并端梯度,再产生 MLP 输入梯度 BMI 与权重梯度 BMW;BD 只依赖 BMI,之后 Attention 输入梯度 BAI 与权重梯度 BAW 都可执行。BMW 不必阻塞 BD。相同通道上的操作必须额外串行。
| 每次通信 tick | 显式串行完成 | 双资源最短完成 | 激活峰值限 1 的最短完成 | 双资源工作量下界 |
|---|---|---|---|---|
| 1 | 16 | 12 | 15 | 12 |
| 3 | 24 | 13 | 22 | 12 |
| 6 | 36 | 24 | 34 | 24 |
每组穷举 6!×4!=17,280 对通道顺序,296 对与依赖相容;为每对计算最早开始时间,再选最短完成。三组通信时长在计算前固定,未按最好结果选择。最短仅指这个有限资源模型,没有 GPU、网络或训练吞吐实测。
| 操作 | 资源 | 开始 | 结束 | 前驱 |
|---|---|---|---|---|
| BC | 通信 | 0 | 3 | — |
| FA | 计算 | 0 | 2 | — |
| BMI | 计算 | 3 | 5 | BC |
| FD | 通信 | 3 | 6 | FA |
| BMW | 计算 | 5 | 7 | BC |
| BD | 通信 | 6 | 9 | BMI |
| FM | 计算 | 7 | 9 | FD |
| BAI | 计算 | 9 | 11 | BD |
| FC | 通信 | 9 | 12 | FM |
| BAW | 计算 | 11 | 13 | BD |
每个不抢占、同通道互斥的可行调度,都给出一份计算顺序和一份通信顺序。把顺序边加入原依赖后,必须无环;对固定顺序,各节点按前驱最晚完成时刻启动,不会比同顺序的其他方案更晚。因此枚举所有通道顺序并取最小值,覆盖了本模型的所有可行完成时间。
激活峰值限 1 另要求所有旧反向计算完成后才能开始 FA。因为它们和 FA 都使用计算通道,该条件等价于相应操作全部排在 FA 之前;枚举中保留这些顺序即可。证明只用于本例的两份激活包规则,没有推广到细粒度张量释放或真实 GPU 调度。
只计两份逻辑激活包:旧反向包在 t=0 已存在,全部旧反向计算完成后才释放;新前向包在 FA 开始时取得,并留到本对 chunk 之后。相同时刻先释放再取得。该粒度故意简化,不含张量大小、逐层释放、重算、参数副本或通信缓冲。
| 固定通信 3 tick | 完成 | 激活包峰值 | 新包取得时刻 | 旧包释放时刻 |
|---|---|---|---|---|
| 显式串行 | 24 | 2 | 0 | 24 |
| 双资源最短 | 13 | 2 | 0 | 13 |
| 激活峰值限 1 | 22 | 1 | 12 | 12 |
峰值限 1 时,所有旧反向计算必须排在 FA 之前;枚举中一并检查这些通道顺序,得到 22 tick。这个结果只说明指定存活规则下的交换关系,不能作为真实显存或报告中参数副本代价的替代。
一手依据:DeepSeek-V3 v1(2024-12-27)第 3.2.1 节、图 4–5 与表 2。完整 DualPipe 还有双向 microbatch、PP 通信、硬件 SM 分配与参数布局条件;本站不实现这些部分,也不把本例的 24→13 当作作者的加速比。
本例固定同一权重版本,不在这对 chunk 内更新参数。完整训练步仍需等齐对应 microbatch 的权重梯度,并保持目标归约、更新时刻与版本语义一致;异步更新属于另一份协议。
每卡长期保存一部分参数,计算一层时临时聚齐该层。前向后释放完整参数能降低存活量,反向则需要重新获取。把状态分片和计算时的临时缓冲区放在同一条时间线上,才能解释峰值。
本例用两个 DP rank、两层 2×2 矩阵和 tanh 中间激活;每卡持有不同样本。每层按扁平数组分成两个连续片段。目标是两份 ½‖Y−target‖² 的平均;反向先产生本地完整梯度,再求和、除以 2 并保留本卡片段。
初始每卡有 4 个参数元素与 4 个动量元素。图只计参数、动量、完整本地梯度及归约梯度片;临时完整参数另分配缓冲区。字节账本假设每元素 4 B,数值计算使用 JavaScript 双精度。
| Rank | 持久参数片 | 临时完整参数 | 完整本地梯度 | 归约后的梯度片 | 逻辑字节 |
|---|
ReduceScatter 事件同时计入其输入梯度与输出片,随后释放输入。不计 activation、通信 workspace、分配器碎片及缓冲区别名。预取是提前聚合的逻辑顺序,不据此估计真实速度或物理显存峰值。
各策略完成全部事件后,与未分片参考的最大参数差:。此结果独立于当前步进位置。
| 参数 | 规约梯度 | 分片更新后重建 | 未分片参考更新 |
|---|
本例两层前向后都释放时,共四次 AllGather;保留时共两次。两种策略计算相同目标,交换的是完整参数存活量与再次聚合的工作。
下一层参数先到位可能减少实际运行的等待,也可能使多层参数同时存活。这里只展示后一个可计数关系;重叠收益需要 profiler 证据。
训练系统的问题要先用可观测信号定位:计算、显存、dataloader 还是通信。
单 batch loss 下降、checkpoint 可恢复、grad 非零/不爆炸。
区分 compute、dataloader、collective、checkpoint 写入的等待。
拆出参数、optimizer、activation、临时 workspace 与碎片。
每次改一项;验证全局 batch、学习率、warmup 与收敛证据。
原 GPipe/1F1B 为单位 tick、零通信;新增固定前向/旧反向对的双资源 DAG,枚举顺序与逻辑激活包,不含完整双向 DualPipe、PP 通信、SM 分配或测速。原 FSDP 仍为双精度两卡两层 MLP 的逻辑参数/状态账本,不测真实分布式框架或物理峰值。