卡数、显存与并行方式#
在交互实验室的「布局」步骤中逐个点击图示。先确认各阶段能放下且学习正确,再优化每秒有效样本数。
从多少张卡起步?#
实验室按每节点 8 GPU,参考 H100/H200 级别、高速互联服务器的仓库配方。这些是配方起步值,不是实测最小值,也不保证这一档所有硬件均能直接运行。模型配方默认回复上限为 131,072 tokens(128K),GLM-5.3 为 262,144(256K),均启用 CP,每轮 8 个 prompt、各采样 8 次;prompt 长度仍计入显存。MoE 和 Qwen 默认启用 CPU Adam 与重计算。
模型 |
训练卡数 |
TP / PP / CP / EP |
每个推理引擎卡数 |
来源 |
|---|---|---|---|---|
GLM-4.7-Flash |
8 |
2 / 1 / 4 / 8 |
8 |
|
GLM-4.7 |
64 |
8 / 4 / 2 / 16 |
32 |
|
GLM-5.3 |
256 |
4 / 8 / 8 / 32 |
64 |
|
Qwen3.8-27B |
32 |
4 / 2 / 4 / 1 |
2 |
Flash 使用 TP2 / CP4 / EP8 和单流水线阶段,将 128K 序列分散到更多卡上。导出的配方启用 --log-probs-chunk-size 1024,降低 log-prob 与 SC 计算的临时显存。Qwen3.8 复用匹配架构配置,此次文档修改尚未对新 checkpoint 做 GPU 验证。第一次建议用 9B 或 Flash 理解循环,再对目标模型做短实验,测量峰值显存后分配长任务资源。
同卡训推分配一个池;训推分离需训练卡数加 rollout 卡数。PD 将 rollout 池分为完整 prefill/decode 引擎;外部推理资源不计入训练 Ray 集群。只增加卡数而不调整模型并行,可能只是增加副本,并不减少每卡模型显存。
显存账本#
以一种混合精度 Adam 为例,\(P\) 个参数的 BF16 权重占 \(2P\) 字节、FP32 梯度 \(4P\)、FP32 master weights \(4P\)、两份 FP32 moments \(8P\):
实际 precision-aware 优化器的状态精度可能不同。激活、buffers、临时转换、分配器预留、reference policy 副本、KV cache 还要另算。30B 的 BF16 权重约 60 GB,两份 FP32 moments 约 240 GB,尚未分片。MoE 存储要看总参数量,不能只看激活参数量。
flowchart TB
T[训练显存] --> W[权重 + 梯度]
T --> O[优化器状态]
T --> A[保存的激活]
T --> B[Buffers + 临时分配]
O --> C[CPU Adam:主机存储和计算]
A --> R[重计算:少保存,再算一次]
S[推理显存] --> SW[权重]
S --> KV[KV cache + workspace]
理想的阶段 offload 使同卡显存需求接近 \(\max(M_{\rm train},M_{\rm rollout})\),还需考虑常驻 buffers 与切换开销。分离布局则分别满足两个池的容量约束。
TP:拆一个层#
按矩阵列拆分:
各卡计算一片;后续按输入行拆分的层计算 \(Z=Y_0V_0+Y_1V_1\),需要归约各卡的部分输出。这解释了显存节省和频繁通信的来源,TP 应优先放在高速互联内。Sequence parallelism 还拆分部分激活操作,不能替代 CP。见 Megatron 论文和并行指南。
PP:拆模型层#
flowchart LR
A[前面的层] -->|激活| B[中间的层]
B -->|激活| C[后面的层]
C -->|梯度| B
B -->|梯度| A
每个 stage 只保存自己的层。假设 \(p\) 个等耗时阶段、\(m\) 个 microbatch、每阶段耗时 \(\tau\),简单 forward 流水线耗时 \((m+p-1)\tau\)。利用率为 \(m/(m+p-1)\),填充与排空的 bubble 比例为 \((p-1)/(m+p-1)\)。实际训练还受 backward 调度、通信与分层不均衡影响。增加 microbatch 数能摊薄 bubble,但每个 microbatch 仍要放得下。见 Megatron 论文。
EP:拆 MoE 专家#
对选中的专家集合 \(K(x)\):
不同 GPU 保存不同专家。All-to-all dispatch 把 token 送到专家所在卡,combine 返回加权输出。权重均匀分片不代表 token 流量均匀,专家负载倾斜可能成为瓶颈。见 GShard。
Dense 层常用卡数关系为 \(N=TP\cdot PP\cdot CP\cdot DP\)。专家层有另一套含 expert TP、expert DP 的分组,不能在 dense 关系上再乘 EP。本实验室使用 expert TP=1,检查卡数能被 \(TP\cdot PP\cdot CP\) 和 \(EP\cdot PP\) 整除;模型维度与 Megatron 还会带来其他约束。
CP:拆 token#
CP 按 token 位置分配 queries;attention 仍需远端 keys/values,因此引入通信。它减少本地序列激活,不会自动拆模型权重。
单条 8-token 序列、CP2 |
Rank 0 |
Rank 1 |
|---|---|---|
默认 zigzag |
0、1、6、7 |
2、3、4、5 |
slime allgather CP |
0、1、2、3 |
4、5、6、7 |
Zigzag 将每条补齐后的序列切为 \(2c\) 块,rank \(r\) 得到第 \(r\) 与 \(2c-r-1\) 块。前后配对平衡 causal attention:8 个位置连续切分时两卡分别处理 10、26 个 query-key 对,图中的 zigzag 各处理 18 对。这是配对数,不是 sparse kernel 真实耗时。
slime 的 --allgather-cp 打包序列,将补齐后的整体 token 流连续切分。DSA backend 收集所需远端 attention/index 数据,loss 处理再恢复样本归属。它不同于 zigzag 逐序列切分;不兼容的 backend 上误开 flag 会打乱 token 顺序。
flowchart LR
A[Rank 0 本地 queries] --> C[对所需 keys 做 attention]
B[Rank 1 keys / values] -->|backend 通信| C
C --> D[Rank 0 本地输出]
Zigzag 描述布局,不等同于某一个固定 ring 算法;通信由 attention backend 决定。Allgather 可能产生较大聚合张量,所以 CP 不会将每类内存等比例缩小。
CP > 1 时,slime 当前只允许 DeepseekV32ForCausalLM 和 GlmMoeDsaForCausalLM 使用 allgather CP。实验室的 GLM-5.3 通过模型配置启用它,其他配方保持支持的布局。图示按钮不修改运行 flag。见参数校验、打包、CP 索引和 Megatron 指南。
ZeRO 与 distributed optimizer#
数据并行副本处理不同样本。ZeRO 依次分片优化器状态(stage 1)、梯度(stage 2)、参数(stage 3)。沿用每参数 18 字节示例,\(D\) 个副本上的理想持久状态开销为:
推导即先将 master weights 和 moments 除以 \(D\),再依次将梯度、BF16 权重除以 \(D\);未计临时通信 buffers。\(P\) 可以是本地模型并行分片,\(D\) 是对应副本数;专家参数分组可能不同。见 ZeRO。
slime 默认启用 Megatron use_distributed_optimizer,分片优化器状态与更新计算,再聚合更新后的参数。这不等于完整 ZeRO-3 参数分片,也不表示使用 DeepSpeed runtime。见后端默认参数。
CPU Adam 与重计算#
Adam 保存 moments 并做偏差修正:
CPU Adam 在主机保存优化器状态并执行更新。开关导出 --optimizer-cpu-offload、--overlap-cpu-optimizer-d2h-h2d 和 --use-precision-aware-optimizer。分片决定哪个 rank 负责状态;offload 决定该 rank 在哪里保存和更新状态。主机内存、CPU 算力和 PCIe 带宽接过一部分显存负担,激活与 KV cache 不受影响。背景见 Adam、ZeRO-Offload,slime 使用 Megatron 实现。
独立的重计算开关保存边界,在 backward 时重做部分 forward,以 FLOPs 换激活显存,见激活 checkpointing。训练 OOM 先判断状态还是激活占主导,再选 offload、更多模型并行或更小的 token microbatch。推理 OOM 则检查权重、KV 精度、并发、回复长度和引擎卡数。通过 profiling逐项测量。