Arganzheng's Blog

stay hungry, stay foolish

大规模训练工程(08):分布式 checkpoint——格式、异步保存与重分片恢复

Distributed Checkpoint: Format, Async Save and Resharding

更新 @2026-09-06:本文 torchtitan 部分基于 v0.3.0 刷新;其余源码引用仍以 PyTorch 2.13.0 / Megatron Core 0.18.0 / DeepSpeed 0.19.2 为准。 前四篇解决的是”怎么配、怎么跑满”。配置定了、MFU 到了预期,任务开始按一个月的日程往前跑。这时候训练引擎面对的第一个可靠性问题不是故障本身,而是一个更朴素的问题:这一千多 GB 到几 TB 的状态,怎么写到磁盘上,写多久一次,写的时候要不要停。 Llama 3 论文(Dubey et al. 2024)给了一组值得反复引用的数字:16K 张 H100、54 天预训练、466 次任务中断,其中 419 次是意外的。折算下来集群平...

大规模训练工程(07):千卡配置实战——并行搭配、micro-batch、激活重计算与 MFU 调优

Configuring a Thousand-GPU Job: Parallelism, Micro-batch, Recompute and MFU

更新 @2026-09-06:本文 torchtitan 部分基于 v0.3.0 刷新;其余源码引用仍以 PyTorch 2.13.0 / Megatron Core 0.18.0 为准。 前三篇把一个训练任务拆成了四种状态、把并行策略拆成了”复制还是切分”的选择、把三个框架拆成了”一个 bf16 参数的一生”。这些是零件。本篇把零件装回去:拿到一份模型规格和一份集群规格,坐下来算出一组配置,跑起来,然后面对那个所有人都会遇到的数字——MFU 比预期低了 10 个点。 配置一个千卡任务没有搜索空间可以穷举。TP、PP、DP、CP 四个维度、micro-batch、重计算策略、重叠开关、精度、编译,任意组合都要几分钟到几十分钟才能跑出一个 MFU 数字,一...

大规模训练工程(06):三个框架对比——Megatron-LM、DeepSpeed 与 torchtitan

Megatron-LM, DeepSpeed and torchtitan Compared

更新 @2026-10-27:本篇拆成四篇。源码导读分别移到 03《Megatron-LM》、04《DeepSpeed》、05《torchtitan》,本篇只留三者的对比。 前三篇各读了一个框架的源码。Megatron 把一个 DP 副本内的所有 bf16 参数拍进一段连续 buffer,梯度也拍进另一个 buffer,优化器只看自己那 \(1/N_d\) 段(03);DeepSpeed 让每个参数在不用的时候只剩 \(1/N_d\) 的碎片,用到时临时拼回来、用完立即打碎(04);torchtitan 根本不保留常驻的 bf16 参数——常驻的是 fp32 分片,bf16 只在一层前向、反向的几十毫秒里存在(05)。 02《并行策略全景》结尾用公式算出...

大规模训练工程(05):torchtitan——用 PyTorch 原生原语组合并行的架构与源码导读

torchtitan: Architecture and Source Guide

说明 本文按 torchtitan v0.3.0 的源码路径讲解;该版 release 验证 PyTorch 2.14.0,本文的 CPU/gloo 玩具在 PyTorch 2.14.1 上运行。 上一篇(02《并行策略全景》)给出每参数 16 字节与各并行维度的通信账。本篇沿同一条 bf16 参数的生命线读 torchtitan v0.3.0:常驻的是 fp32 Shard(0) DTensor 分片,bf16 只在每层计算期间临时出现。参数通信由 FSDP hook 与 DTensor placement 驱动。三个框架并排的对照在 06《三个框架对比》,本篇只读 torchtitan。 一个 bf16 参数在 torchtitan 里存在哪里...

大规模训练工程(04):DeepSpeed——从优化器状态切起的架构与源码导读

DeepSpeed: Architecture and Source Guide

说明 本文源码引用以 DeepSpeed v0.19.2、PyTorch 2.13.0 为准。 上一篇(02《并行策略全景》)给了 ZeRO-1/2/3 的字节账与通信账。本篇沿同一条 bf16 参数的生命线进 DeepSpeed 0.19.2 的源码:Stage 3 里 param.data 只是一个壳,完整的 bf16 参数在用到前由 hook all-gather 出来、用完立即打碎,常驻的是每参数 \(1/N_d\) 的 ds_tensor 碎片和扁平 fp32 分区。三个框架并排的对照在 06《三个框架对比》,本篇只读 DeepSpeed。 一个 bf16 参数在 DeepSpeed Stage 3 里存在哪里、什么时候被 all-gat...

大规模训练工程(03):Megatron-LM——按模型结构切的架构与源码导读

Megatron-LM: Architecture and Source Guide

说明 本文源码引用以 Megatron Core core_v0.18.0、PyTorch 2.13.0 为准。 上一篇(02《并行策略全景》)给的是公式:每参数 16 字节、ZeRO-1 的 2N 通信、TP/PP/DP 的组合代价。本篇沿同一条 bf16 参数的生命线往下走,进 Megatron Core 0.18.0 的源码:那段 bf16 参数在显存里是一段连续 buffer 的视图,fp32 主参数是优化器按字节区间切出的私有拷贝,梯度在另一段连续 buffer 里走 reduce-scatter。三个框架并排的对照在 06《三个框架对比》,本篇只读 Megatron。 一个 bf16 参数在 Megatron 里存在哪里、什么时候被 a...

大规模训练工程(02):并行策略全景——每种并行切的是哪种状态

A Map of Parallelism: Which State Does Each Strategy Shard

上一篇算出了一个数字:混合精度 + Adam 下,每个参数在训练时要占 16 字节。一个 70B 的模型光是参数、梯度和优化器状态就是 1.13 TB,还没算激活;405B 是 6.5 TB。任何一张 80 GB 的卡都放不下其中的零头。所以这些字节必须被切开放到很多卡上——怎么切,就是并行策略的全部内容。 习惯上并行策略被当作一组 API:DDP、FSDP、ColwiseParallel、Schedule1F1B、--tensor-model-parallel-size 8。这样理解的问题是你记住了十几个名字,却回答不了”这个配置为什么慢”。换一个角度:训练的状态只有四样——参数、梯度、优化器状态、激活——每一种并行策略无非是决定这四样东西的哪一样、沿哪个维度、...

大规模训练工程(01):训练任务的状态解剖——显存账与 MFU

Anatomy of Training State: Memory Accounting and MFU

一张 H100 有 80 GB 显存、标称 989 TFLOPS 的 bf16 算力。一个 70B 参数的模型,用 bf16 混合精度加 Adam 训练,参数、梯度和优化器状态加在一起是 1.13 TB——是那张卡的 14 倍。序列长 8192 时,它每一层的激活值还要 2.3 GB(每层约 34·s·b·h 字节,\(34 \times 8192 \times 1 \times 8192 \approx 2.28 \times 10^9\);系数 34 的逐项来源见第四章第 1 节),80 层就是 180 GB。每个 token 的前向加反向要 4.5×10¹¹ 次浮点运算,一条 8192 token 的序列在一张卡上就算满了也要 3.7 秒。 这几个数字是本系...

大规模训练工程:从并行策略到容错恢复(总纲)

Large-Scale Training Engineering, from Parallelism to Fault Tolerance

内容简介 更新 @2026-09-06:本文”框架与版本基线”及第三至十一篇的 torchtitan / torchft 部分基于 torchtitan v0.3.0、torchft v0.2.0 刷新(两者发布于本系列之后);其余源码引用仍以 PyTorch 2.13.0 / Megatron Core 0.18.0 / DeepSpeed 0.19.2 为准。 《大规模训练工程:从并行策略到容错恢复》是一组共十一篇正文加一篇总结的系列文章,面向已经会用 PyTorch 写训练循环、了解 DDP、准备把训练任务从几张卡放大到几百几千张卡的工程师,系统讲解一个大规模训练任务是如何被配置、跑满、并且长期跑住的。 它回答的问题是: 一个千卡训练任务...

通信与互联(09):系列总结与通关自测

Communication and Interconnect: Series Recap and Final Self-Test

八篇正文回答了一个问题:一次 all_reduce 从调用到完成,数据在 PCIe、NVLink、InfiniBand 上是怎么流动的,为什么有时候是带宽的问题、有时候是延迟的问题。第一篇造尺子(α-β 模型与 ring 的推导),第二、三篇给尺子填上真实刻度(链路带宽、拓扑等级、RDMA 的三条路径),第四篇讲 NCCL 如何在这些刻度上做决定,第五篇讲 PyTorch 如何使用 NCCL 而不浪费它,第六篇把前五篇变成一条曲线和一棵决策树,第七、八篇把同一套方法用到推理的 decode TP、PD 分离和 MoE 的 all_to_all 上——那里 NCCL 不再是答案,绕开它的三种办法各自付了什么代价。 本文不讲新内容,做三件事:把八篇压成一张表与八段回顾...

×