8 卡跑完 13B 训练:数据并行、张量并行与流水线并行的实测对比

举报
yd_238528621 发表于 2026/11/07 12:42:38 2026/11/07
【摘要】 8 张 A100 80GB 上跑 13B,把数据并行配 ZeRO、张量并行 8 路、流水线并行 4 段乘 2 路三条路线在同一套条件下各跑 300 步,给出显存峰值、全卡吞吐、通信占比三组数字,并给出按显存与是否跨机判断的选型顺序。

触发点很具体。8 卡机器上跑 13B,最直觉的做法是套一层数据并行,脚本起来不到两分钟就炸,报的是 CUDA out of memory,Tried to allocate 2.00 GiB,而此前已经分配到 79.8 GiB。第一反应是减批大小,从 16 减到 8 再减到 1,还是炸。这才反应过来占显存的不是激活,是优化器状态。于是干脆把三条并行路线都跑一遍,条件固定,只换切分方式。

一、实验设置

下面的所有数字都在这套条件下取的,换掉任何一项就不具备可比性。

  • 硬件是 8 张 A100 80GB,单机 NVLink 全互联,不跨机
  • 模型 13B,bf16 前向反向,AdamW,权重衰减 0.1
  • 序列长度 2048,全局批大小固定 64,梯度累积只在流水线方案里用
  • 每套方案跑 300 步,取第 100 到 300 步的平均步时
  • 显存峰值取 torch.cuda.max_memory_allocated 的最大值,通信占比取 nsys 里 NCCL kernel 累计时间除以步时

全局批大小固定这一点很关键。市面上很多并行方案的对比数字互相不可比,一方偷偷把批大小放大四倍换吞吐,最后比出来的差异跟切分方式没关系。换掉显卡型号或者互联方式,绝对数字会变,但判断顺序不变。

二、纯数据并行配 ZeRO-1:显存账最直观

先把账算清楚。13B 参数在 bf16 下权重占 26GB,AdamW 的 fp32 主权重 52GB,一阶、二阶动量各 52GB,合起来 182GB,还没算激活和临时缓冲。8 张卡各存一份完整状态,等于每张卡都要扛 182GB,80GB 的卡必然炸,这就是那句 tried to allocate 2 GiB 的真正来源。

ZeRO-1 只切优化器状态,每卡 182 除以 8 约 23GB,再加上完整的 26GB 权重,实测显存峰值 71GB,能跑,但余量只剩 9GB,序列一拉到 4096 就重新 OOM。

  • 单卡显存峰值 71GB,通信占比 8.3%
  • 全卡吞吐 15200 tokens/s
  • 每步一次梯度 all-reduce,单机 NVLink 下这部分开销几乎被计算盖住
  • 步时波动小,300 步的标准差不超 4%,这是它最大的优点

数据并行的通信量只跟参数量有关,跟切几路无关,所以它永远是通信最省的那条路。前提只有一个,塞得下。

三、张量并行 8 路:显存立刻舒服,吞吐掉得也干脆

张量并行把每层的权重矩阵按列或按行切开,8 路之后每卡只留 26/8 约 3.3GB 权重,加上切开的优化器状态,实测显存峰值 24GB,序列拉到 8192 也不紧张。

代价在通信次数。每层前向要做两次 all-reduce,反向再来两次,通信从每步一次变成每层四次,13B 大约 40 层,量级完全不同。

  • 单卡显存峰值 24GB,通信占比 34%
  • 全卡吞吐 8900 tokens/s,比纯数据并行低 41%
  • 单步里 NCCL 累计约 410ms,计算部分只有 790ms
  • 把 all-reduce 换成 reduce-scatter 加 all-gather 的组合,吞吐回到 9600,提升 8%

张量并行的切分粒度太细,通信次数与层数成正比。它在单机 NVLink 内还划得来,跨机这么切基本等于把时间全送给网络。

再补一组跨机的反例。把这套张量并行 8 路改成跨两台机器,每机 4 卡,25Gbps 网络,吞吐直接掉到 3100 tokens/s,通信占比冲到 71%。同一份代码只把切分从机内搬到机间,性能差了三倍,切法必须跟着拓扑走。

四、流水线并行 4 段乘数据并行 2 路:气泡率是可算的

流水线把模型按层切成 4 段,每组卡跑一段,组内再做 2 路数据并行。每卡权重 26/4 等于 6.5GB,优化器状态也跟着分段,实测显存峰值 38GB。

它的问题不在显存,在气泡。段数 p 为 4、micro-batch 数 m 为 8 时,气泡率是 (p-1)/(m+p-1),等于 27.3%,超过四分之一的时间有卡在空转。

  • 单卡显存峰值 38GB,通信占比 12%
  • 全卡吞吐 11700 tokens/s
  • micro-batch 从 8 提到 16,气泡率降到 15.8%,吞吐升到 13100,显存峰值同时涨到 54GB
  • 段数从 4 降到 2,气泡率降到 11.8%,但每卡权重回到 13GB,显存峰值 61GB

这三个参数互相咬。段数涨,显存降但气泡涨;micro-batch 涨,气泡降但显存涨。没有单点最优,只有一组勉强能接受的折中。

顺便提一句 ZeRO-3,它按层切参数,实测每卡 41GB、吞吐 14300 tokens/s。同样是把状态切开,它比张量并行 8 路高出 60% 的吞吐,原因就是通信次数少了一个量级。

五、选型边界

把三套方案的数字并排看,判断顺序其实很固定。先看显存放不放得下,再看通信代价,最后才谈吞吐。

  • 单卡放得下整个训练状态,就走纯数据并行或 ZeRO-1,别做任何并行切分,切了纯亏通信
  • 单卡放不下但模型能进单机,优先 ZeRO-3,不要第一反应上张量并行
  • 必须跨机时,切法只能沿层走,也就是流水线加数据并行,张量并行最多切到单机内 8 路
  • 70B 以上一般是张量并行 8 路乘流水线 4 段再乘数据并行,任一段单独放大都会撞上显存或者气泡

所有并行方案的本质都是拿通信时间换显存。先算清通信占比,再决定拿什么换,比照着别人的配置抄要靠谱得多。

小结

这次对比最有用的一条经验是,报错里那句 tried to allocate 2 GiB 会骗人。看着像激活不够,其实是优化器状态把底座占满了,这时候减批大小只会在原地打转。先把每张卡的显存账拆开算清楚,权重、主权重、动量、激活分开记,再用单卡放不放得下、要不要跨机这两个问题定位路线,选型的纠结基本就消失了。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。