Arganzheng's Blog

stay hungry, stay foolish

大规模训练工程(05):分布式 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 次是意外的。折算下来集群平...

大规模训练工程(04):千卡配置实战——并行搭配、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 数字,一...

大规模训练工程(03):三个框架——Megatron-LM、DeepSpeed 与 torchtitan 的架构对比与源码导读

Megatron-LM, DeepSpeed and torchtitan: Architecture and Source Guide

更新 @2026-09-06:本文 torchtitan 部分基于 v0.3.0 刷新;其余源码引用仍以 PyTorch 2.13.0 / Megatron Core 0.18.0 / DeepSpeed 0.19.2 为准。 上一篇结束在一个数字上:Llama 3 405B 用 TP 8 / PP 16 / DP 128 训练时,每张卡常驻的参数、梯度、优化器状态只有 13 GB,而在途激活可以到 73 GB。这个数字是从公式里算出来的,公式假设”bf16 参数在每张 TP×PP 分片上完整、fp32 主参数被 ZeRO-1 切成 128 份”。但公式不会告诉你:那份 bf16 参数在显存里是一个 nn.Parameter 还是一段大 buffer 的切...

大规模训练工程(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,80 层就是 180 GB。每个 token 的前向加反向要 4.5×10¹¹ 次浮点运算,一条 8192 token 的序列在一张卡上就算满了也要 3.7 秒。 这几个数字是本系列后面七篇的全部起点。并行策略要解决的是”1.13 TB 放到哪些卡上”;micro-batch 与激活重计算要解决的是”180 GB 的激活怎么塞进剩下的显存”;MFU 调优要解决的是”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、准备把训练任务从几张卡放大到几百几千张卡的工程师,系统讲解一个大规模训练任务是如何被配置、跑满、并且长期跑住的。 它回答的问题是: 一个千卡训练任务,怎么配、怎么跑满...

通信与互联(08):MoE 的通信——all-to-all、DeepEP 与 GPU 发起的通信

Communication for MoE: All-to-All, DeepEP and GPU-Initiated Networking

前七篇处理的通信有一个共同点:参与者之间交换的字节数在调用之前就是确定的。all_reduce 的每个 rank 拿同样大小的 buffer,all_gather 的每个 rank 贡献同样大小的一片,KV 传输的 block 列表由 scheduler 事先算好。第一篇给 all_to_all 留了一句话——”\(n(n-1)\) 条不同的流,无法从绕环一圈里得到好处,跨节点时会同时压满所有链路,是 MoE 训练最难对付的通信模式”——然后就再没有回来。本篇回到这里。 MoE 把它变成了训练和推理里最重的一种通信。一层 MoE 的前向,每个 token 由 router 选出 top-k 个专家,专家分布在 EP 组的所有 rank 上,于是 token 要被分...

通信与互联(07):推理侧的通信——custom all-reduce 与 KV 传输

Communication on the Inference Side: Custom All-Reduce and KV Cache Transfer

前六篇建立了一条完整的路径:第一篇的 α-β 模型给出任何一次通信的理论下界,第二、三篇给 α 和 β 填上 NVLink、PCIe、InfiniBand 与 RDMA 的真实数字,第四篇讲 NCCL 如何把这些硬件能力组织成一次 ncclAllReduce,第五篇讲 PyTorch 如何在 stream 上使用它,第六篇把这一切变成 nccl-tests 的曲线和一棵排障决策树。这些内容的默认场景是训练:消息几十 MB 到几 GB、参与者固定、通信可以和反向计算重叠。 推理把这套方法推到两个极端。第一个极端是张量并行的 decode:batch 很小、hidden 维度固定,每一层两次 all_reduce,每次只有几十到几百 KB,一个 decode step...

通信与互联(06):nccl-tests、调优与排障——从带宽曲线到 hang

nccl-tests, Tuning and Debugging Hangs: From Bandwidth Curves to Flight Recorder

前五篇建立了一条完整的因果链:第一篇的 α-β 模型给出一次集合通信的理论时间,第二、三篇给出链路能提供的 β 和 α,第四篇讲 NCCL 如何在探测到的拓扑上选 ring/tree、channel 数、算法与协议去逼近这个上限,第五篇讲 ProcessGroupNCCL 如何把 NCCL kernel 放到自己的 stream 上、watchdog 如何盯着每一个 WorkNCCL。这条链上每一环都可能出错,而错误的表现只有三种:慢、卡、结果不对。本篇的任务是把前五篇变成一套可操作的方法——面对这三种现象,先测什么、先看什么、先改什么。 性能这一半的核心工具是 nccl-tests。它做的事情很简单:对一组消息大小依次调用同一个集合通信原语,报告时间、algbw...

通信与互联(05):PyTorch 的通信栈——ProcessGroupNCCL、stream 语义与计算通信重叠

PyTorch's Communication Stack: ProcessGroupNCCL, Stream Semantics, and Compute-Communication Overlap

上一篇沿着 ncclAllReduce 走完了 NCCL 内部的全部路径:bootstrap、拓扑探测、ring/tree 搜索、transport 建连、调优表、enqueue、一个 kernel 里 nChannels 个 block 各跑一条环,跨机时由 proxy 线程替 GPU 驱动网卡。那一篇的结论可以压缩成一句话:NCCL 是一个把集合通信编译成 CUDA kernel 的库,ncclAllReduce(sendbuf, recvbuf, count, dtype, op, comm, stream) 的最后一个参数决定了这个 kernel 排进哪条队列。这一篇就从这最后一个参数开始。 绝大多数人不直接调 NCCL,而是写 dist.all_redu...

×