
1. 从一篇论文说起百万卡为什么还能叫「一台计算机」第一次看到「百万卡还算一台计算机」这个说法我脑子里蹦出来的第一个念头是这不就是营销话术吗一百万张加速卡横跨好几个机房光是光纤都能绕地球好几圈你跟我说这是一台计算机但把华为廖恒那篇论文翻来覆去读了几遍之后我改主意了。这个说法不是修辞而是一个有严格技术定义的工程命题。它背后牵扯到两个非常硬核的东西一个是BSP模型的六层重构一个是冯·诺依曼架构的向外扩展。把这两件事讲清楚「百万卡一台机」这个结论就自然成立了。这篇文章我打算按自己读论文、做系统设计的思路来拆。不搞那种「首先介绍背景、然后分析意义」的八股而是直接进入问题本身为什么大规模并行系统会「散架」BSP和冯·诺依曼各自卡在哪里六层套娃是怎么套的Unified Bus和超节点在其中扮演什么角色。如果你正在做昇腾相关的分布式训练、或者对大规模并行系统的架构设计感兴趣这篇应该能给你一些可以直接拿走用的思路。先给一个最粗的结论方便你带着框架往下读传统冯·诺依曼架构定义了「一台计算机」的内部秩序BSP模型定义了「并行计算」的执行秩序而六层BSP套娃 Unified Bus总线扩展把这两个秩序从单机尺度一路保持到了百万卡尺度。秩序没丢所以它还是一台计算机。秩序丢了它就是一堆计算机的集合。这个判断标准很关键后面所有的拆解都围绕它展开。2. 先搞清楚BSP到底是什么为什么它成了大规模并行的「骨架」2.1 BSP模型的三段式结构BSP是Bulk Synchronous Parallel的缩写中文一般叫「整体同步并行」。它的核心结构特别简单就三段计算段Computation每个参与的计算单元各自干活互不干扰通信段Communication计算单元之间交换数据同步段Synchronization所有单元对齐确认这一轮全部完成再进入下一轮你可以把它想象成一个大型合唱团。每个人唱自己的声部计算唱完一小节后互相听一下有没有跑调通信然后指挥举手示意所有人对齐同步再进入下一小节。这个「计算-通信-同步」的循环就是BSP的一个超步Superstep。为什么这个模型在大规模并行里这么重要因为它把「并行」这件事的复杂度给锁住了。如果没有同步点每个计算单元各跑各的你根本不知道谁跑到哪了调试、优化、容错全都无从下手。BSP用同步点把整个执行过程切成一段一段每一段内部可以乱但段与段之间是干净的。这就是秩序。2.2 传统BSP在大规模下的三个致命伤BSP模型在几百卡、几千卡的规模下工作得很好。但到了十万卡、百万卡问题就来了。第一个问题是同步开销随规模爆炸。同步的本质是「等最慢的那个」。一万个单元里有一个卡了其他九千九百九十九个都得等。规模越大出现「最慢单元」的概率越高同步的等待时间就越长。这个在工程上叫「长尾效应」是分布式系统里最让人头疼的问题之一。第二个问题是通信拓扑的维度不够。传统BSP假设通信是「全对全」或者「固定拓扑」但在百万卡规模下物理连线不可能做到任意两卡直连。你必须分层卡内、卡间、节点内、节点间、机架间、机房间。每一层的带宽和延迟差好几个数量级。单一层次的BSP模型根本描述不了这种多层异构的通信结构。第三个问题是故障成为常态。一百万张卡假设单卡年故障率是1%那平均每天就有二十多张卡出问题。传统BSP的同步机制对故障非常敏感一个单元挂了整个超步就卡死了。你必须有一套分层的容错和重构机制。这三个问题就是六层BSP要解决的核心矛盾。2.3 为什么是「六层」而不是三层或十层这里我要插一句自己的理解。分层这件事层数不是随便定的。层数太少每层的跨度太大描述不精确层数太多层间开销累积起来反而拖慢系统。六层这个数字我推测是基于当前硬件物理层级和软件调度粒度的实际匹配关系定下来的。从物理上看典型的层级大概是芯片内计算单元 → 芯片内多核 → 单卡多芯片 → 节点内多卡 → 机架内多节点 → 跨机架/跨机房。这正好是六个物理层级。BSP的六层套娃本质上是让每一层BSP对应一个物理层级让同步和通信在每一层内部解决而不是全部推到最顶层。这个设计思路非常聪明。它把「全局同步」这个最贵的操作拆解成了六个层级的「局部同步」。每一层的同步只需要在该层内部对齐层与层之间通过接口传递状态。这就好比一个公司不需要CEO直接管每个员工而是组长管组员、经理管组长、总监管经理层层对齐。全局对齐的成本被分摊到了各个层级。3. 冯·诺依曼往外扩从「一台机器」到「一个系统」的架构延伸3.1 冯·诺依曼架构的核心是什么聊完BSP我们来看第二个核心概念冯·诺依曼架构。很多人对冯·诺依曼的理解停留在「存储程序」这四个字上但我觉得更本质的是它定义了一套秩序计算单元和存储单元分离通过总线连接指令和数据统一编址放在同一个存储空间里顺序执行程序计数器驱动指令流这套秩序的精髓在于它让「一台计算机」有了明确的边界。边界内所有东西通过总线通信共享地址空间遵守同一套执行规则。边界外的东西需要通过IO接口才能访问。所以「一台计算机」的定义本质上不是物理尺寸而是是否共享同一套地址空间和执行秩序。这个定义非常重要它是理解「百万卡一台机」的钥匙。3.2 向外扩展的三个维度冯·诺依曼架构要往外扩能往哪些方向扩我梳理了一下主要是三个维度第一个维度是存储墙的突破。传统冯·诺依曼架构里计算单元和存储单元之间的带宽是瓶颈叫「冯·诺依曼瓶颈」。在大规模并行系统里这个瓶颈被放大了无数倍。解决办法是引入多级存储层次寄存器、缓存、片上内存、HBM、节点内存、分布式共享内存。每一级都有自己的带宽和延迟特性通过硬件和软件协同管理。第二个维度是总线拓扑的扩展。传统冯·诺依曼用一条系统总线连接CPU和内存。到了百万卡规模这条总线必须变成一个分层的网络片内总线、片间总线、节点内总线、节点间总线。Unified Bus统一总线就是在这个背景下出现的。它的目标是把不同层级的物理连接抽象成一套统一的通信语义让上层软件感觉不到底层的物理差异。第三个维度是地址空间的扩展。这是最难的。传统冯·诺依曼架构里所有内存共享一个物理地址空间。到了百万卡规模每张卡都有自己的内存怎么让它们看起来像一个统一的地址空间这需要硬件层面的地址映射和软件层面的分布式共享内存管理。昇腾的超节点架构很大程度上就是在解决这个问题。3.3 Unified Bus为什么是关键拼图Unified Bus这个概念我理解它的核心价值是统一语义。在没有统一总线之前片内通信用一套协议片间通信用另一套节点间通信用第三套。每换一层软件就要换一套编程接口复杂度呈指数级上升。Unified Bus做的事情是把这些异构的物理连接抽象成一套统一的通信原语。上层软件只需要调用统一的接口不需要关心底层是片内总线还是跨机房光纤。这就好比TCP/IP协议栈不管你底层是以太网、WiFi还是光纤上层应用看到的都是socket接口。这个抽象层的价值在于它让「一台计算机」的边界可以无限延伸而不需要改变上层的编程模型。程序员写的代码在单卡上能跑在百万卡上也能跑只是性能特征不同。这就是冯·诺依曼架构往外扩的核心意义。4. 六层BSP套娃的具体拆解每一层在干什么4.1 第一层到第三层芯片内的微观秩序最底层的三层BSP发生在芯片内部。第一层是计算单元级。昇腾NPU内部有多个计算核心比如AI Core每个核心内部又有多个计算单元。这一层的BSP同步粒度最细通常在指令级或微指令级。计算段是矩阵乘加运算通信段是寄存器之间的数据搬运同步段是流水线对齐。这一层的开销最小但频率最高。第二层是核心级。多个AI Core之间的BSP同步。这一层开始涉及片上网络NoC的通信。计算段是每个核心独立处理自己的数据块通信段是通过片上内存交换中间结果同步段是核心间的栅栏同步。这一层的设计关键是片上内存的带宽和容量它直接决定了核心间通信的效率。第三层是芯片级。单颗昇腾芯片内部可能包含多个die或者多个计算簇。这一层的BSP同步涉及片内总线和片间互联。计算段是芯片级的并行任务通信段是通过HBM或片间总线交换数据同步段是芯片级的全局同步。这一层的设计难点是功耗和散热的平衡因为芯片内的通信密度极高。这三层的共同特点是物理距离极短通信延迟在纳秒级同步开销可以忽略不计。它们构成了整个系统最内层的秩序基础。4.2 第四层到第六层节点间和系统级的宏观秩序从第四层开始物理尺度跳到了厘米级和米级通信延迟从纳秒跳到了微秒甚至毫秒级。第四层是节点级。一个计算节点内通常有8到16张加速卡通过节点内总线比如PCIe或专用的卡间互联连接。这一层的BSP同步涉及节点内的全局栅栏。计算段是节点级的并行任务通信段是卡间的AllReduce或AllGather同步段是节点内的同步屏障。这一层的关键是卡间带宽它直接决定了数据并行和模型并行的效率。第五层是机架级。一个机架内通常有多个节点通过机架级交换机连接。这一层的BSP同步涉及跨节点的通信。计算段是机架级的任务分片通信段是跨节点的数据交换同步段是机架级的同步。这一层的设计难点是网络拓扑的选择胖树、环面、还是 dragonfly不同的拓扑对不同的通信模式有不同的优势。第六层是系统级。这是最顶层涉及跨机架、跨机房的全局同步。这一层的BSP同步就是传统意义上的「全局同步」但它的实现方式已经被下面五层大大简化了。因为大部分同步已经在低层完成了顶层只需要处理跨机架的那部分。计算段是整个系统的任务调度通信段是跨机房的广域通信同步段是全局的检查点对齐。这六层套在一起就形成了一个分层的秩序体系。每一层都有自己的BSP循环层与层之间通过明确定义的接口交互。全局同步被分解成了六个层级的局部同步每一层的开销都被控制在该层物理条件允许的范围内。4.3 层间接口的设计要点六层BSP能不能套得稳关键在层间接口。我总结了几条设计要点接口语义要统一每一层对外暴露的接口应该尽量一致这样上层软件不需要为每一层写不同的代码。Unified Bus在这里起到了关键作用。状态传递要轻量层与层之间传递的状态信息要尽量少否则接口本身就成了瓶颈。通常只传递同步信号和必要的元数据。故障要隔离在层内某一层出故障应该尽量在该层内部解决不要向上传播。这需要每一层都有独立的容错机制。性能要可观测每一层的同步延迟、通信带宽、队列深度都要有监控指标否则出了问题根本不知道是哪一层的锅。这几条听起来简单但实际做起来非常考验工程能力。尤其是故障隔离在百万卡规模下每天都有硬件故障发生如果每一层都能把故障吃掉整个系统的可用性就能做到很高。5. 百万卡「一台计算机」的判定标准秩序是否统一5.1 统一地址空间是硬指标回到最开始的问题百万卡凭什么算一台计算机我的判断标准是看它是否共享统一的地址空间和执行秩序。如果一百万张卡上的内存可以被统一编址任何一个计算单元都可以通过标准的内存访问指令访问其他单元的内存当然延迟不同那它在逻辑上就是一台计算机。这就像NUMA架构。在NUMA系统里CPU访问本地内存和远程内存的延迟不同但你不会说NUMA系统是「多台计算机」因为它共享统一的地址空间。百万卡系统如果做到了统一地址空间那它本质上就是一个超大规模的NUMA系统。昇腾的超节点架构我理解就是在往这个方向走。通过Unified Bus和分布式共享内存管理让跨卡的内存访问看起来像本地访问一样虽然延迟更高。这是「一台计算机」的物理基础。5.2 统一编程模型是软指标光有统一地址空间还不够还需要统一的编程模型。如果程序员需要为每一层写不同的代码那这个系统在软件层面还是「多台计算机」。统一编程模型的核心是同一份代码可以在不同规模上运行只是性能特征不同。这需要编程框架比如昇腾的CANN、MindSpore能够自动处理任务的分层映射和通信调度。程序员只需要描述「要算什么」不需要描述「在哪算、怎么通信」。这个目标很难完全实现但方向是明确的。BSP六层套娃的价值就在于它为统一编程模型提供了执行秩序的保障。每一层的BSP循环对上层是透明的上层只需要按BSP的方式组织代码底层的分层细节由运行时系统处理。5.3 统一容错和调度是工程指标最后一个指标是容错和调度。一百万张卡故障是常态。如果每次故障都需要人工介入那这个系统运维成本会高到不可接受。统一容错的意思是系统能够自动检测故障、隔离故障、重构任务而不需要上层应用感知。这需要每一层BSP都有独立的健康检查和任务迁移机制。某一层的某个单元挂了该层自动把它踢出去重新分配任务然后继续同步。上层应用看到的只是性能略有波动而不是任务失败。统一调度的意思是系统能够根据当前的资源状态和任务需求自动决定任务在哪一层执行、用多少资源。这需要一套跨层的调度器能够感知六层BSP的状态并做出全局最优的决策。这三个指标——统一地址空间、统一编程模型、统一容错调度——共同定义了「一台计算机」的工程标准。百万卡系统如果在这三个维度上都做到了统一那它确实可以被称为一台计算机。6. 实操视角这套架构对做分布式训练的人意味着什么6.1 并行策略的选择会变如果你正在做昇腾上的大规模分布式训练这套六层BSP架构会直接影响你的并行策略选择。传统上我们选并行策略主要看模型大小和卡数小模型用数据并行大模型用模型并行或流水并行。但在六层BSP架构下你需要额外考虑每一层的通信开销。举个例子假设你要在1024张卡上训练一个百亿参数的模型。如果纯用数据并行每次迭代的AllReduce通信量是模型大小的两倍。在六层BSP架构下这个AllReduce会被分解成六层卡内、节点内、机架内、系统级。每一层的通信开销不同你需要根据实际的带宽和延迟数据来决定在哪一层做多少通信。我的经验是尽量把通信压到低层。能在节点内解决的不要推到机架级能在机架内解决的不要推到系统级。因为每往上一层延迟就增加一个数量级。这需要你在切分模型和數據时有意识地让通信局部化。6.2 同步频率需要重新调优BSP的同步频率是一个关键参数。同步太频繁开销大同步太少收敛慢。在六层BSP架构下每一层的同步频率可以独立调整。我的建议是低层高频高层低频。芯片内和节点内的同步可以很频繁因为开销小系统级的同步要尽量少因为开销大。具体怎么调我通常会先跑一个基准测试测量每一层的同步延迟。然后根据训练任务的收敛特性设定每一层的同步间隔。比如芯片内每步同步节点内每10步同步系统级每100步同步。这个比例不是固定的需要根据实际任务调。6.3 故障处理要分层设计百万卡规模下故障处理是必须考虑的一环。六层BSP架构给了你一个天然的故障隔离框架。我的做法是每一层都实现独立的健康检查和任务迁移。芯片内某核心挂了芯片级BSP自动屏蔽它节点内某卡挂了节点级BSP自动重新分配任务机架内某节点挂了机架级BSP自动接管。只有跨机架的故障才需要系统级介入。这样设计的好处是大部分故障在低层就被吃掉了不会影响全局。系统级的故障处理频率大大降低整体可用性提高。7. 常见问题与排查技巧实录7.1 同步超时怎么排查问题现象训练任务卡住日志显示某个同步点一直不返回。排查思路按六层BSP逐层排查。先看芯片内是否有核心异常再看节点内是否有卡掉线然后看机架内是否有节点失联最后看系统级是否有网络抖动。我的经验大部分同步超时都是低层问题引起的。我遇到过好几次最后发现是某张卡的散热问题导致降频拖慢了整个节点。所以排查时要从低层往高层查不要一上来就怀疑网络。7.2 通信带宽不达预期怎么调问题现象AllReduce的实际带宽只有理论值的30%。排查思路先确认通信发生在哪一层。如果是节点内检查卡间总线的配置如果是机架级检查交换机配置和拓扑如果是系统级检查跨机房链路的实际带宽。我的经验最常见的原因是通信和计算没有重叠好。BSP模型里通信段和计算段是分开的但实际硬件支持通信和计算并行。如果你没有利用这个特性通信时间就会白白浪费。解决办法是用异步通信原语让通信在后台进行计算继续跑。7.3 任务迁移后性能下降怎么办问题现象某张卡故障后任务自动迁移到备用卡但整体性能下降了20%。排查思路检查迁移后的任务分布是否均衡。六层BSP架构下任务迁移应该尽量在低层完成。如果迁移到了高层通信开销会增加。我的经验任务迁移后一定要重新做一次负载均衡。我通常会预留一些备用资源在每一层故障时优先在层内迁移实在不行才往上层迁。这样可以把性能损失控制在最小。7.4 常见问题速查表问题现象可能原因排查层级解决方向同步超时低层单元异常芯片级/节点级逐层排查隔离故障单元带宽不达预期通信计算未重叠节点级/机架级使用异步通信原语迁移后性能下降任务分布不均衡机架级/系统级重新负载均衡训练收敛慢同步频率不当全层级调整各层同步间隔系统级抖动跨机房网络问题系统级检查广域链路质量8. 我对这套架构的一点个人判断读完整篇论文我最大的感受是「百万卡一台计算机」这个说法本质上是在重新定义「计算机」的边界。传统上我们习惯用物理尺寸来定义计算机一台笔记本、一台服务器、一个机架。但在大规模并行系统里物理尺寸已经失去了意义。一百万张卡分布在几个机房里物理上它们是分离的但逻辑上它们可以是一个整体。这个「逻辑整体」的判定标准就是我在第5节里说的三条统一地址空间、统一编程模型、统一容错调度。这三条做到了它就是一台计算机做不到它就是一堆计算机的集合。六层BSP套娃和冯·诺依曼往外扩本质上都是在为这三条服务。BSP提供了执行秩序的框架冯·诺依曼扩展提供了地址空间和编程模型的延伸Unified Bus提供了物理层的统一语义。三者合在一起才让「百万卡一台机」从口号变成了工程现实。当然这套架构还有很多工程细节需要打磨。比如层间接口的开销能不能再降故障隔离能不能做得更彻底编程模型能不能更透明。这些都是后续需要持续优化的方向。但方向是明确的。如果你正在做大规模分布式系统的设计或优化我建议你认真读一下这篇论文尤其是六层BSP的拆解部分。它提供的不是一个具体的实现方案而是一个思考框架如何用分层的秩序来管理超大规模的复杂性。这个框架比任何具体的参数配置都更有价值。