最近圈子里都在传某大模型团队拿下了巨额融资的消息,各种讨论大多停在钱上面。但我看了几个版本的消息,真正让我在意的不是那笔资金,而是里面反复提到的一个数字:十六万张国产AI加速芯片。这个量级对绝大多数团队来说已经不是“多买点卡”的问题了,而是整个工程体系要从零重新设计的问题。
从一万张卡到十六万张卡,不是把服务器数量乘以十六,而是把所有曾经可以靠人肉运维、靠运气、靠小规模试错掩盖的问题全部放大到不可忽视的程度。我陆续参与过几个不同规模的集群建设项目,也在模拟项目X里研究过万卡以上的训练调度,今天想从工程视角拆一拆,十几万张加速卡组成一个训练集群,真正难啃的骨头到底在哪儿。
1. 先看本质:从一千张卡到十六万张卡,越过的是质变门槛
1.1 故障率是第一个照进现实的数字
很多人对大规模集群没有直觉,我先给一组可以自己按计算器的数据。假设一张加速卡的年度故障率在1%~2%之间,这是行业里比较常见的数字,折算成平均无故障时间大概是50万小时量级。那么十六万张卡每小时预期损坏多少张?用十六万除以五十万,结果是0.32张每小时。
换句话说,你大概每三个小时就会遇到一张卡物理损坏。这还只是加速卡自身的故障,没算电源、内存、光模块、交换机、线缆、硬盘。光模块的故障率实际比加速卡还高,万卡规模的集群里,每个月换下来的光模块能装一小箱。
千卡阶段,一张卡坏了,运维看到了,手动摘掉,重跑任务,损失可控。到了十万卡阶段,“等坏了再处理”的思路直接失效。因为故障不是偶发事件,而是一个稳定的速率。你刚把第100张坏卡换下来,第101张已经在路上了。集群调度系统必须在设计之初就把故障当成常态来对待。
1.2 规模折损:理想带宽曲线与实际吞吐曲线的分离
另一个容易被忽略的指标叫规模折损。小规模训练的时候,多加点卡,训练速度几乎线性提升。但当集群规模超过几千卡,通信开销开始占据训练时间的显著比例,加速比会明显偏离理想曲线。等到五万卡、十万卡级别,单纯堆卡带来的加速收益非常有限,甚至会因为通信拥堵出现负收益。
所以十六万张芯片的真正挑战不是“怎么买到那么多卡”,而是“怎么让那么多卡真的同时干活”。这背后是一连串的组网、存储、调度、稳定性问题。钱能解决采购,解决不了工程。
2. 并行策略决定网络拓扑,而不是反过来
2.1 三种并行维度的通信画像
大模型训练里最核心的并行思路包括三种:数据并行、流水线并行、张量并行,还有现在大模型常用的专家并行。我的经验是,在设计集群之前,必须先画出不同并行维度下的通信矩阵,否则网络拓扑就是拍脑袋。
张量并行的通信频率最高。每个Transformer层的前向和反向都要做多次AllReduce,参与张量并行的卡之间几乎每时每刻都在互相传数据。如果一组做张量并行的卡被分散在不同交换机下面,网络延迟会把训练速度拖到不可接受。
数据并行的通信频率相对低一些,主要在梯度同步阶段。但梯度本身的数据量不小,几百亿参数模型一次全量梯度同步就是几百GB级别的流量。流水线并行则要求相邻流水段之间的激活传递低延迟,通信模式和前面两种又不一样。
专家并行更特殊,token要按路由结果被送到对应专家所在的设备,流量模式不是固定的“矩阵型”而是动态的“散弹型”。这种通信模式对网络拥塞的敏感度极高。
2.2 通信矩阵估算:一个可以复现的小算例
我习惯用一个小算例来估算:假设模型参数量是2000亿,训练采用张量并行度为8。每个Transformer层的权重大约在几十亿参数量级,一次AllReduce需要传输的数据量约等于两层权重之和。
每层AllReduce的通信量大概在几个GB到十几个GB之间,而模型有几十层上百层,每个step要做的AllReduce次数非常可观。按每step传输200~400GB通信量估算,除以step时间几十秒,可以得到集群内部需要支撑的通信带宽是每秒几十GB到上百GB。
这个数字意味着,做张量并行的卡之间的网络带宽需求是远超普通数据中心的。这也是为什么很多团队在设计拓扑时,会选择把张量并行组放在同一个接入交换机下,用机内网络或高速背板通信来规避跨交换机瓶颈。
2.3 大型集群的真实拓扑选型约束
到了十万卡级别,麻省理工学院台式机式的“一个接入交换机带几十台服务器”的思路已经不够用了。业界常见的是多层Clos架构,也就是叶脊拓扑,通过三层交换机把整个集群连成一张大网。但具体怎么做分区、每个分区放多少卡,完全取决于训练框架的并行策略。
我给过一个建议:先拿着训练框架跑一组小规模通信基准测试,把实际能达到的带宽和时延记录下来,再决定网络拓扑。直接照搬别人的“推荐架构”不靠谱,因为你的并行策略、模型形状、数据管线都可能不一样。实测下来的数一定比纸面设计可靠。
3. 高速网络与拥塞控制:集群里最容易被低估的瓶颈
3.1 包丢在交换机端口会发生什么
算力集群的网络不是简单的“通不通”,而是“顺不顺”。训练过程中最常见的拥塞场景是AllReduce的incast流量:多张卡同时向一个目标发送数据,交换机的某个出口瞬间被打满,数据包开始排队。队列满的时候,丢包出现,TCP或RoCE的流控机制会触发重传,而重传带来的延迟惩罚对同步训练是致命的。
整个训练任务会因为一个重传包卡住几百微秒,而几百微秒在万卡规模的全局同步中会被放大成几秒的等待。更麻烦的是,拥塞会导致蝴蝶效应:一个交换端口的丢包引发多个GPU任务的等待,进而让更多任务在同一时间点发起通信,造成更大的拥塞。这种正反馈一旦建立,集群的通信效率会断崖式下跌。
解决思路是端到端的流控与拥塞控制配合。网络设备要开启显式拥塞通知和优先级流控,同时把训练流量和其他流量严格隔离。实际操作中,我见过太多集群因为监控没配好,出现PFC死锁导致整个集群吞吐归零的情况。
3.2 无阻塞比例与故障域:钱要花在咽喉处
很多人以为网络升级是简单的“越多越好”,其实带宽是建筑成本的大头。在十万卡集群里,网络设备的总成本可能达到总硬件成本的20%到30%,甚至更高。
关键决策点是无阻塞比例。理想状态下,每个端口的接入带宽不应该被上联收敛,这样才能保证任意两张卡之间的通信和本机通信一样快。但做到完全无阻塞非常贵,很多项目会选1.2:1到1.5:1的收敛比,牺牲一点整体吞吐来换成本。
我的看法是,对于训练集群,至少要保证主干网的长期利用率不超过设计上限的70%,否则拥塞控制会非常难受。高优先级训练任务要跟低优先级的探索性任务分到不同的故障域,避免一个任务占满链路导致另一个任务全链路踩踏。
另外一个不容易注意到的点是故障域。核心交换机一旦出问题,可能让几千张卡同时断连。所以关键的设备必须冗余,但这会让成本再上一个台阶。口袋里的预算是有限的,钱要优先花在保证“故障不扩散”上,而不是一味堆性能。
4. 存储与数据管线:让十万张卡时刻有数据可算
4.1 数据吞吐不够,训练再快也是空转
计算集群的存储系统常常被低估。十五万张卡全速训练时,每秒钟要读取的训练样本数量是惊人的。假设每张卡每秒钟处理几十个样本,十五万张卡就是每秒几百万样本。如果每个样本几十KB,那存储系统需要支撑的读取带宽就是每秒几十GB到数百GB。
大多数传统分布式存储系统在几十GB每秒的连续读场景下还能撑住,但训练数据不是顺序读取。数据会被反复打乱顺序,不同的worker要随机访问不同的样本,这就变成了高并发随机读。传统存储系统在这个场景下性能会急剧下降,出现大量元数据操作和目录锁竞争。
解答的原因是,训练数据要做预处理、打包、排序。把数百万个小文件打包成一批大文件,让每个worker顺序读取一个大文件的不同分片,同时在内存里做shuffle,才能绕开小文件随机读的雷区。这是一个不改存储架构就永远解决不了的问题。
4.2 Checkpoint和断点续训是“隐性杀手”
另一个比数据读取更大的坑是Checkpoint。大模型训练每隔一段时间要把模型参数和优化器状态存下来,等训练中断后从这里恢复。
一个几千亿参数的模型,参数加优化器状态动辄几百GB甚至上TB。如果每个Checkpoint都同步写到中心存储,瞬间的写入压力会把存储系统打垮。而且Checkpoint如果写得太频繁,训练时间的很大比例会花在等写入上;写得太少,一旦故障就要回退很多step,浪费算力。
我见过的做法是分级存储:先写本地NVMe盘,形成快照后异步拷贝到并行文件系统,最终再落到对象存储。这个过程要设计得足够平滑,否则每写一次Checkpoint,整个集群的I/O就卡顿一次。
断点续训的隐性成本和Checkpoint一样。恢复之后,所有worker要重新加载参数,重新建立通信组,重新同步学习率和随机数种子。从故障到恢复,一个数千卡的任务顺利的话也要几分钟,期间算力完全停摆。
5. 稳定性与自动容错:在不可靠硬件上训练可靠模型
5.1 同步训练为什么是“玻璃地板”
大模型训练普遍采用同步训练,也就是所有worker在每一步结束时做一次全局同步,得到统一梯度,再更新模型。这个模式最致命的弱点是:最慢的那张卡决定所有人的速度。
一张卡因为散热、供电或网络抖动慢了0.5秒,整个集群都等它。如果这张卡彻底掉线,训练任务基本就断了。在小规模场景下,这种问题靠人工重启能解决;在十万卡场景下,你的人力根本跟不上故障速度。
所以集群系统必须做到自动检测、自动剔除、自动拉起新worker。通信库本身要对拓扑有感知能力,在某个节点掉线时能用替代路径重发数据,而不是傻等超时。
5.2 故障自愈的实操链路
自愈系统做起来比听起来麻烦得多。首先是故障检测,要同时处理心跳超时和疑似假死,不能一超时就误判,否则频繁重启任务会造成更大的性能抖动。我的做法是设置多级阈值:短期失联先做隔离观察,超过一段时间才判定为故障。
然后是训练任务本身的快照与恢复。每次梯度同步完成之后,把必要的状态同步到备份节点。当出故障时,备份节点能在一个同步周期之内接管工作,不需要从Checkpoint重跑。这种机制把故障恢复时间从小时级压到了分钟级。
最后还有“脏数据”问题。有些卡不是完全不能用,而是时不时算错,产生损坏的梯度。这类故障比硬故障更难发现,因为训练还在继续但loss曲线开始莫名其妙跳动。需要加入针对梯度数值的检查和额外的校验机制,把训练推向一个“宁可慢一点也要稳一点”的运行状态。
6. 电力、散热与运营成本:钱不只是买卡的钱
6.1 一张卡几百瓦,十六万张卡意味着什么
假设单张加速卡的平均功耗是400瓦左右,16万张全速运行就是64兆瓦,还不算服务器其他部件、交换机和制冷系统的额外开销。加上配套设备,整个集群的IT负载轻松上百兆瓦。这个数字放到现实里,相当于一个中型城市的民用电力负荷。
要支撑这种规模,机房需要的不是普通的市电扩容,而是从变电站开始就要为这个项目单独拉线路。备用的柴发油机也是一个难题:几小时的断电,需要巨量的柴油储备和投递保障。
散热的挑战更直接。风冷在单机柜功率密度超过二三十千瓦的时候就已经很吃力了,而训练集群的机柜功率密度常常能到五六十千瓦。所以近几年的新建项目普遍转向液冷,但液冷对管道、泵、水质、防漏要求极高。机房里漏一次水,损失的不是一台服务器,而是一排机柜。我参与过的某次液冷改造,光做漏水检测和抽调测试就花了一个多月。
6.2 算力调度与利用率:算力空闲是最贵的消耗
建设成本是一次性的,电费和折旧是持续性的。一张卡买回来,即使不开机也在折旧;一旦开机跑不满,等于把折旧费用摊薄在更少的有效计算上。
训练集群的调度策略必须实现优先级的大小任务穿插:主训练任务独占一部分分区,用剩余的空闲算力跑数据预处理、推理评测、小规模调参实验。这种做法的难点在隔离,不能让小任务影响主任务的网络和存储,否则省下的资源不如不省。
我个人的经验是,利用率从30%优化到60%,靠的不是把机器开满,而是把任务的粒度切得足够细。一个指令队列,有训练任务时让训练任务优先,空闲时自动填充低优先级任务,同时通过弹性伸缩控制排队长度,才算是一个真正能打的大规模调度系统。
7. 芯片间互联受制时的算法补偿
7.1 带宽受限时,先压缩通信再升级硬件
国产加速芯片的实际表现里,单卡算力和高速互联带宽跟国际一线产品相比有差距,这是整个项目不得不面对的现实。如果网络升级的成本太高,算法层面就要想办法降低通信量。
一个非常有效的做法是梯度压缩。AllReduce之前先把梯度做稀疏化,只传绝对值最大的那部分元素,或者把梯度量化到较低精度。对于很多模型,这能把通信量压缩到原来的十分之一甚至更低,收敛质量损失有限。我实测过,在大规模训练中应用TopK稀疏化之后,训练时间缩短了百分之三十以上,最终收敛效果基本持平。
通信量变少之后,AllReduce的流量压力大幅下降,需要的网络带宽也降下来了。这套“算法补硬件”的思路,在互联带宽受限的国产芯片平台上尤其值得深入。
7.2 MoE负载均衡和序列打包,从源头减少搬迁
专家并行模型里,最怕的是某个专家成为热点,大量token被路由到同一个专家所在的节点上,局部网络瞬间拥塞,再好的流控也扛不住。
应对办法是两方面的:一方面设计负载均衡的router,让每个step的token分布尽量均匀;另一方面做离线重排,把同一批token中属于同一专家的部分尽量聚拢在同一个计算分批,减少跨节点传输。MoE模型在国产芯片集群上能不能跑出效率,很多时候不是算力问题,而是负载均衡的调度问题。
另一个从算法层解决问题的角度是序列打包。长序列训练时,把多个短样本拼成一条长序列,可以减少填充token造成的算力浪费,也能让计算更加规律,进而让通信模式可预测,更容易做网络预留。
写在最后的几点实际建议
从几十张卡到几百张卡,靠的是代码和运气;到几千张卡,靠的是流程和监控;到十几万张卡,一切问题都是系统性问题,单点英雄式排查已经救不了整个集群。
如果让我总结一句最想分享的经验,那就是:大规模集群里没有“小问题”。一条线缆接触不良、一个参数配错、一段代码里一次不合理的超时重试,都会在集群规模下被放大成“训练中断数小时”级别的损失。一定要把故障当成设计输入,把自动恢复当成默认选项。
另外,别把十六万张芯片的融资当作项目成功的终点,它只是让工程挑战正式开始的门票。能在十万卡级别真的稳定跑出一个训练结果,都是一件非常了不起的事。工程的价值,不在账面数字,而在那些最后被你驯服的硬件和它们身上每一根沉默的光缆。