大模型训练慢、显存炸?这16个硬核优化方案把卡用到极致

去年我们团队在国产加速卡上调一个百亿参数模型,8卡跑起来,GPU利用率只有40%出头,训练一个epoch要等两天。更离谱的是,同样的代码换了长序列数据直接OOM。

老板问:这卡是不是不行?

其实卡没问题。是默认的训练框架根本没把卡的潜力挖出来。

如果你也在做大模型训练,大概率踩过类似的坑:

  • 通信等待时间比计算还长,卡在那空转
  • 长序列一上就OOM,显存永远不够用
  • MoE专家负载不均衡,有些专家忙死有些闲死
  • 变长序列训练效率感人,短序列干等长序列

这篇文章基于一次大模型训练优化的内部技术培训,整理了16个从通信、显存、调度到并行策略的实战方案。每个方案都经过实测验证,能直接落在生产环境里。


一、通信优化:让数据搬运不再拖后腿

大模型训练最大的瓶颈往往不是计算,是通信。

1. TP通信计算融合(flux kernel)

痛点:张量并行(TP)中,通信和计算是串行的。gemm算完→等待all-reduce→再算下一层。等通信的时间卡全闲着。

解法:把通信操作替换为flux kernel,让通信和计算重叠起来。

优化后

Gemm+通信并行

下一层计算

优化前

Gemm计算

等待通信

下一层计算

核心改动是把TP通信换成flux.GemmRS算子,同时保存前向all-gather的结果直接给反向用,省掉一次重复通信。实测下来,典型模型性能提升约5%。

2. MOE All-to-All通信重叠

痛点:MoE架构的all-to-all通信是刚性开销。专家数量越多,通信占大头。

解法:在两个micro-batch之间做流水线重叠——上一个batch在做计算时,下一个batch的通信已经在跑了。

0 1 2 3 4 5 6 7 8 9 10 11 12 Dispatch Compute Dispatch Combine Compute Combine Batch N Batch N+1 MoE A2A Overlap 流水线

效果取决于规模:卡数越多提升越明显,大规模集群下性能提升可达两位数百分比。

3. DualpipeV:改进版流水线调度

痛点:传统interleaved 1F1B在MoE场景下,attention部分的TP通信和EP通信会互相抢带宽,形成资源竞争。

解法:DualpipeV把attention模块的计算拆开重新排流水线,让通信域错峰使用。

核心思路:

  • 将attn部分的qkv计算、core attention、linear projection拆成独立阶段
  • 重新编排micro-batch的forward/backward顺序
  • 让TP通信和EP通信不再同时抢占带宽

实测对特定网络拓扑的负载均衡场景,DualpipeV相比interleaved 1F1B有明显优势,且同时支持fp16和fp8训练。

4. All-to-All量化通信

痛点:MoE的all-to-all通信数据量大,int8量化虽然能压缩一半,但int4量化精度损失又太大。

解法:在all-to-all通信前将数据量化为int8发送,接收端反量化恢复。

bf16 输入

量化

int8 传输

All-to-All

int8 输出

反量化

bf16 输出

实测int8量化通信功能稳定,精度损失在可接受范围内。int4目前loss差异较大,不建议生产使用。

5. 低秩分解通信压缩(EDGC)

痛点:分布式训练中梯度同步的通信量和模型参数量成正比,模型越大通信越疼。

解法:EDGC用三个模块动态压缩梯度通信——

  • 梯度采样器:随机采样子集快速估计梯度信息熵
  • 压缩量化模型:建立「压缩秩→通信耗时」的映射关系
  • 动态对齐压缩器:预热后按熵值动态调整压缩强度,还按pipeline stage差异化分配压缩率

在GPT2系列模型上验证,EDGC收敛速度和最终loss都与全量通信几乎一致,但通信量大幅下降。

6. SDP4bit:4位通信量化

痛点:数据并行虽然能缓解显存压力,但梯度同步的通信量随模型变大成为新瓶颈。8位量化已经到极限了吗?

解法:SDP4bit做了两件事——

  1. 权重差异量化:不量化权重本身,而是量化「当前迭代权重 - 上次迭代权重」的差值。差值分布更集中,4bit量化误差更小。
  2. 两级梯度量化:节点内用8bit、节点间用4bit,配合Hadamard变换平滑差异。

训练精度损失几乎可以忽略。


二、显存优化:榨干每一兆内存

7. 参数副本复用

痛点:大模型训练维护两份参数——一份FP32做主副本、一份BF16做实际计算。两份同时占着显存。

解法:既然FP32和BF16不会同时被访问,那就把FP32拆成「BF16 + 残差」存起来。前向用BF16干活,反向更新时用BF16+残差恢复FP32。

省出一份BF16参数的内存,性能损耗不到1%。如果用分布式优化器,总节省 = BF16参数量 / DP数,损耗同样控制在1%以内。

8. Pipeline-Aware激活值卸载

痛点:流水线并行中,前向计算的激活值要存着给反向用。层数多了激活值吃显存很凶。

解法:前向算完就把激活值offload到CPU内存,反向开始前再reload回GPU。

CPU GPU CPU GPU Forward Layer 1 Offload Activation 1 Forward Layer 2 Offload Activation 2 Forward Layer 3 Reload Activation 2 Backward Layer 3 Reload Activation 1 Backward Layer 2

支持对attention和MLP的多个模块单独配置卸载策略。实测卸载attention部分后,显存峰值下降约8%,性能损耗很小。

9. Block-wise Scaling INT8

痛点:INT8量化的老问题——大值区间精度够,小值区间相对误差大。FP8虽然动态范围好,但硬件支持还不够普及。

解法:引入block-wise scaling,把向量分块后各自独立scale。缩小了小值区间INT8的劣势。

向量内积实验对比:相同chunk size下INT8信噪比略优于FP8。实际在Mixtral和Llama2-7B上训练验证有效。


三、调度策略优化:让流水线不再空转

10. Recompute In Bubble(RiPiple)

痛点:1F1B流水线的warmup和cooldown阶段存在天然气泡——前面的卡算完了要等后面的卡。

解法:别让气泡白白浪费。在气泡时间里主动触发重计算,把本应在反向计算时做的recompute提前做了。

0 1 2 3 4 5 6 7 8 9 10 Forward idle Forward Recompute in Bubble Backward Backward Device 1 Device 2 RiPiple: 气泡中重计算

重计算和反向计算解耦后,调度更灵活,气泡利用率大幅提升。

11. Seq1F1B:序列维度切分

痛点:长序列(比如64K token)的attention计算量是平方增长的,一张卡放不下、算不动。

解法:把sequence维度切分成多个chunk,每个chunk独立做1F1B调度。

Seq1F1B切分

原始序列

64K Token Sequence

Chunk 1: 4K

Chunk 2: 4K

Chunk 3: 4K

Chunk 4: 4K

结构简单但效果很好。长序列场景下显存和性能都明显优于普通1F1B,尤其64K以上序列优势突出。

12. Dynamic Context Parallel

痛点:真实数据里,序列长度极端不均衡。大部分是短序列,少数超长序列。传统Context Parallel按最长序列切分,导致短序列被强行切分、增加不必要的通信。

解法:三位一体动态调度——

  1. 工作负载配额:不按固定数量打包样本,按计算量动态分配
  2. 动态CP度:长序列多卡分担、短序列单卡处理
  3. 模拟器+求解器:预演分布式环境,求解最优并行策略

Dynamic-CP

长序列

短序列

长短序列分离

序列长度

多卡分担 High CP

单卡处理 Low CP

传统CP

长序列+短序列混在一起

统一按长序列切分

短序列被强制切分
通信冗余

GitHub数据集加速比达到1.48x,CommonCrawl达到1.25x。

13. Vocabulary Parallelism

痛点:1F1B流水线中,transformer层均匀分布在各stage,但第一stage多了输入embedding层、最后一stage多了输出层。负载不均产生气泡。

解法:把词汇层(embedding + output head)单独切出来做并行,不跟transformer层混在一起。

优化后流水线

Device1: Transformer均衡

Device2: Transformer均衡

Device3: Transformer均衡

Device4: Transformer均衡

词汇层并行独立

优化前流水线

Device1: Embed+Transformer

Device2: Transformer

Device3: Transformer

Device4: Transformer+Head

原始负载越不均衡,提升越明显。实测训练性能提升可达40%以上。


四、专家并行与MoE专项优化

14. DeePEP高性能专家并行

痛点:MoE模型的all-to-all通信是关键路径,延迟稍微高一点就拖慢整个step。

解法:DeePEP提供两套内核——

  • 高吞吐内核:NVLink+RDMA混合转发,适合训练和预填充阶段
  • 低延迟内核:纯RDMA通信,适合实时解码场景

同时支持FP8低精度计算和基于hook的通信计算重叠,不占用SM资源。

15. 热专家弹性克隆(ECHO)

痛点:MoE模型中,有些专家被频繁路由(热专家),有些几乎没流量。负载不均让部分卡过载、部分卡空转。

解法:动态克隆热专家到空闲的EP rank上。

克隆后

决策克隆

参数同步

梯度合并

克隆前

专家A 过载

专家B 空闲

专家A 原实例

专家A 克隆

ECHO策划器

ECHO调度器

克隆专家的参数和梯度需要同步保持一致性,同时限制克隆数量以平衡通信开销。反向传播时所有克隆副本的梯度合并回主专家。


五、组合拳:DualpipeV + CUDAGraph + 数据并行分离

把dualpipeV的通信重叠优势和CUDAGraph的kernel提交开销优化结合起来,再加上数据并行域分离,是目前正在跟踪的前沿方向。

CUDA Graph的核心价值:大模型训练有大量细碎kernel调用,每次下发kernel虽然只要几微秒,但几万个kernel累积起来就很可观。Graph把整个计算流程定义为一个图,一次下发启动多个GPU操作。

目前已支持1F1B + CUDAGraph + 数据并行分离方案,dualpipeV的版本还在推进中。


总结

这篇文章覆盖了16个训练优化方向,大致可以归为四类:

类别 方案 核心思路
通信优化 flux TP融合、A2A Overlap、量化通信、EDGC、SDP4bit 让通信和计算重叠/压缩通信量
显存优化 参数副本复用、激活值卸载、Block-wise INT8 省显存、降低精度成本
调度优化 RiPiple、Seq1F1B、Dynamic CP、Vocabulary Parallelism 消灭流水线气泡
MoE专项 DeePEP、ECHO 专家负载均衡、低延迟通信

大模型训练优化没有银弹。不同模型结构、不同规模、不同网络拓扑,最优方案都不一样。最好的策略是把这些方案都集成进训练框架,根据实际任务按需组合。

如果你也在折腾大模型训练,欢迎交流踩坑经验。

Logo

免费领 150 小时云算力,进群参与显卡、AI PC 幸运抽奖

更多推荐