上个月有个做训练集群的朋友跟我抱怨,说好不容易从供应商那边排到了几十张加速卡,结果一跑起来GPU利用率只有三成多,WBM曲线看一整天都是锯齿,光看一眼就焦虑。我问了他一句:你考虑过你的计算拓扑是平坦的还是有层次的?他愣了半天。这不是个别现象。大家谈AI算力革命,下意识都在比谁的卡多、谁的Tops高,但真实场景里,真正决定效率的,往往是那些看不见的“结构”——卡与卡之间的通信拓扑、算子与算子之间的依赖拓扑、参数在高维空间里的分布形状。
我今年越来越倾向一个判断:拓扑生成范式,可能是把这代大模型真正拆开的一把钥匙。它同时回答两个大问题:一是AI算力怎么组织才不浪费,二是大模型这个黑箱有没有可能不靠猜来理解。这篇文章把我最近的工程实践和思考捋清楚,包含这个范式到底是什么、怎么应用到自动并行和模型可解释性上、实际落地时团队会遇到哪些坑。适合正在做训练推理效能优化、或者想给黑箱模型找工程化解释方案的团队参考,偏AI Infra方向,但算法和平台的同学读起来也不会费劲。
1. 堆卡治标不治本:算力瓶颈多数是结构瓶颈
1.1 千卡集群利用率上不去,问题往往不在芯片
先说现象。很多团队在单卡、单机Oneshot基准上跑得很漂亮,一旦注入真实模型、真实数据,训练吞吐立刻跳水。最常见的有三类:
- 通信墙:张量并行、流水线并行、数据并行各自的集合通信消息在网络上打架,all-reduce和all-gather堆在一起,等通信的时间比算的时间还长。
- 气泡率失控:流水线并行里,stage之间同步代价太高,microbatch数量不够的时候,一整个step里大量时间在空转。
- 依赖链拖尾:计算图里存在天然的长依赖链,某些关键节点(比如loss计算、embedding同步)吞吐能力低,导致整个DAG被拖慢,就像一条生产线中间某道工序只能处理其他工序十分之一的量。
这些问题的共同特征是:它们几乎不涉及单卡算力上限,而是卡与卡之间、算子与算子之间的“结构组织方式”。芯片再快,如果数据要绕很远的路才能从生产者传到消费者,全局效率依然上不去。
1.2 厨房动线类比:效率是“结构”问题
我经常用一个例子来跟团队解释这件事。一个后厨有八个灶台,如果食材、备菜台、炒锅、出菜口随便乱摆,厨师一转身就要穿过三个工位,那无论请多快的厨师,高峰期都出不了多少菜。但如果你把备菜区、热灶区、出餐区做成一条顺畅的动线,同样的灶台数量,出餐速度能翻倍。
后厨的“动线”,就是拓扑。AI集群里的消息传递路径、计算依赖关系、数据排布方式,跟厨房动线在数学上是同一种东西——节点之间怎么连接、信息怎么流动、哪些连接是冗余的、哪些路径是瓶颈。总是抱怨灶台不够多的人,不会注意到真正的瓶颈在动线设计;同样,总在抱怨算力不够的人,也很少意识到他的计算图、通信图、调度图的组织方式可能才是最该动刀的地方。
1.3 结构化视角重新定义瓶颈
一旦你切换到这种视角,很多原来纠缠不清的问题会瞬间变得清晰。比如某个训练作业卡在跨节点通信上,传统排查方式是看网卡流量、看丢包、看拓扑树,但本质上你需要回答的问题只有一个:这张计算图被切成若干片后,片与片之间的边是不是过于密集、过于宽了?
我观察过不少团队,做了很多单点优化——换更贵的网络、改ring算法、调buffer大小——但很少人愿意退一步,先把整个作业画成一张图,然后问自己:这张图的形状是否合理?是否有更好的切分方式?
这种“先结构化,再展开优化”的思路,就是拓扑生成范式的地基。
2. 拓扑生成范式到底是什么:一个三层结构的方法论
2.1 三个层次:观察、建模、生成
为了避免“拓扑生成范式”变成一个自我发明的新词,我给它一个严格且可操作的定义。它不是一个具体算法,而是一套三层结构的方法论。
第一层是观察层。把系统变成一张图:把训练作业的算子变成节点,把张量流动变成边;把一群GPU变成一张通信拓扑图;把模型的参数和激活值变成高维空间里的点云。这一步的关键动作是“翻译”——从代码世界翻译到结构世界。
第二层是建模层。用拓扑指标去描述这张图的性质:它有多少个连通分量?有没有明显的环?有没有“洞”?某个结构在多大尺度上仍然稳定存在?这些指标不是从业务语义出发的,而是纯数学的、客观的、可计算的。它们不依赖你对该模型“理解不理解”,只依赖你能否把系统正确地投影为结构。
第三层是生成层。既然结构可以用数学描述,就可以让AI去做结构搜索——生成一张比人工设计更优的并行拓扑、生成一个剪枝后的子图、生成一个新的参数空间路径。这层是整个范式的关键:它不是用来“解释”现有结构的,而是用来创造新结构的。
这个三层闭环是我认为最核心的东西:先可观测,再可量化,最后可生成。
2.2 为什么以前不流行,现在才被摆上台面
你可能会问:图论和拓扑学了不得,为什么要等到现在才跟AI算力结合?
以前的模型小,几百MB参数的BERT时代,并行策略基本靠论文里的一张表就能解决:DP切几份、MP切几份、PP切几份,复制粘贴就跑。因为搜索空间小,人工经验完全覆盖得住。但到了几千亿参数、数万算子、数千卡训练规模的时候,人工设计的弊端就暴露出来了:算子类型多样,shape动态变化,卡间通信能力并不均匀,带故障恢复的集群里节点还在随时变——没有一个固定公式能给出最优并行方案。
与此同时,结构感知的机器学习工具成熟了。图神经网络可以embedding计算图,强化学习可以在巨大的搜索空间里找可行解,可观测性工具(profiler、分布式trace、拓扑dump)已经能把整个训练过程还原成有向图。以前是“想做做不到”,现在是“工具已经齐了,缺的只是把范式理清”。
2.3 跟传统HPC优化的区别:重在“生成”而非“选型”
传统高性能计算也做拓扑感知优化,比如给MPI进程安排物理拓扑,尽量让通信量大的进程在同一个交换机下。但它通常是一次性的静态优化,作业提交前用工具算一次就定死了。
拓扑生成范式跟这条路径有一个根本区别:整个过程是迭代和动态的。
训练和推理过程中,数据的分布会漂移,某些层的梯度方差会变大,物理集群的坏卡会导致网络拓扑变化,吞吐目标也在变。这意味着最优结构不是固定的,而是需要不断重新生成。早期我把这种方式叫“拓扑巡检”,后来意识到它的核心是“生成”——用算法在每一个时间点重新思考:此时此刻,这张图应该长成什么样才最优。
这跟传统HPC那种“算一次用到老”的思路有本质不同,也是我把它称为范式的原因。
3. 算力革命第一落点:自动生成并行与调度拓扑
3.1 并行策略本身就是拓扑变形
把眼光拉回AI Infra实操,我们会发现:所谓分布式并行策略,本质上就是在对计算图做拓扑变形。
你去看几种主流并行:
- 数据并行,是对整张图做多份拷贝,再把梯度通过all-reduce同步,形成一对“副本”之间的跨副本边。
- 张量并行,是把某个算子的dimension切到多张卡上,每个节点被“撕裂”,过后的all-to-all/ all-reduce节点负责合并。
- 流水线并行,是把天然的长依赖链切成一段段的stage,在stage之间插入通信barrier。
手工调优就是在做一种“拓扑体力活”:人肉判断该切哪张图、用哪种切法、切成几片。问题在于,当模型和集群规模上去后,这个搜索空间是天文数字,人肉穷举必然失败。所以我们需要把“切图”这件事交给生成器,在拓扑指标引导下自动搜索。
3.2 自动并行:从手工矩阵到图搜索
我所在的团队从2023年初开始做自动并行方向的尝试。流程大概是这样:
- 模型构建阶段使用torch.fx或者XLA HLO导出统一计算图,图上每个节点填入FLOPs、激活大小、算子类型,每条边填入张量shape和通信数据量。
- 用一个GNN对计算图和集群物理拓扑分别做编码,把节点的串行计算代价、边上的通信代价、并行切分后可能产生的通信模式都做成特征。
- 强化学习agent根据这些特征生成候选切分方案,每个方案本质上是对“每个算子切片到哪些设备、切片方式是什么、设备间边权重怎么变化”的一次完整决策。
- 把候选方案扔进一个模拟器,估算steptime;再抽一小部分候选方案在小规模集群上真实试跑,拿真实数据回流给agent当奖励。
这一步给我的直接体感是:搜索空间大得可怕,但由于计算图本身有强结构,GNN的嵌入能非常快地把搜索引向可行区域。第一次跑通时,它给出的方案比我手工做的baseline在通信占比上下降了十几个百分点。说实话,效果超出了我的预期。
3.3 一个可操作的最小闭环:评估—生成—验证
如果你也想尝试自动生成并行拓扑,我建议从最小闭环开始,不要一上来就做全量级自动切分。可以先在一个模型的三个关键层上做试点:
# 伪代码:自动并行最小闭环 comp_graph = load_computation_graph("block_001") # torch.fx导出 cluster = load_physical_topology("gpu_pool") # 物理拓扑含NVLink域 for trial in range(max_trials): candidate = policy.generate_parallel_plan(comp_graph, cluster) est_cost = simulator.estimate_step_time(candidate, profiled_data) policy.update(candidate, est_cost) if est_cost < best_plan.cost: best_plan = candidate deploy_best_plan(best_plan) # 在测试集群真实跑2个step record_to_archive(best_plan) # 记录档案,供后续作业迁移这里最有价值的不是最终的并行方案本身,而是那个不断采集profiling数据、不断生成候选结构的循环。跑过一轮之后,你对这个模型的结构弱点会有一个远超表层的认知。
3.4 顺手解决token算力评估问题
这两年大家都很关心“token算力需求如何评估”“一张卡能支撑多少并发”。最常见的误区是直接拿算力峰值除以模型大小,得到一个非常离谱的乐观值。其实在没有结构视角的情况下,评估必然失真。
一个更合理的算法是:推理单个token的计算量约等于两倍的模型参数量(2N FLOPs)。如果你要支撑1000 tokens/s的吞吐,总计算需求大约是2N乘以吞吐。以175B模型为例,2×175B×1000 ≈ 3.5×10的14次方FLOPs,约350 TFLOPs。如果单卡在真实场景的有效算力是500 TFLOPs左右,一张卡就能顶住这个吞吐的理论计算需求——这是理论值,现实还要叠加上memory带宽和通信开销。
这里就是拓扑生成范式的用武之地了。多机推理部署时,张量并行拆分得越碎,通信开销越大,利用率越低。是选4卡张量并行还是8卡张量并行,不能拍脑袋,而要看这张具体的计算图上,非线性节点、embedding节点、moe路由节点占比多少。把这些信息跑进拓扑评估器里,得到的吞吐预估才真正接近线上结果。我们内部现在做容量规划,基本不再纯看卡数,而是先把“部署拓扑”生出来再谈够不够。
3.5 动态拓扑:从“调一次用一年”到“边跑边调”
前面说的是静态自动并行。更进一步的方向,是让拓扑生成成为训练和推理过程的一部分。
训练场景下,遇到坏卡、节点降速、网络拥塞时,传统做法是整个作业回滚重调度。但如果你有实时profiling和自动切分能力,就可以在当前distributed runtime里把受影响的那一段stage重新拓扑化:把流量换路、把卡组重新分配、把TP域收缩到一个NVLink域内。这本质上是把“容错”从重启变成拓扑重构。
推理场景更是如此。白天线上流量大,你希望一个speculative解码的组网结构;凌晨流量小,你又希望把shard合并成更集中的拓扑以省电。这个动态生成过程,我目前只在少数自研系统里见过雏形。它一定不容易做,但谁先把这层能力做成通用产品,谁就真正吃到了算力革命的红利。
4. 黑箱破解第一落点:用拓扑数据分析解剖模型内部
4.1 黑箱的本质:缺少高维结构的语言
说完算力,来过黑箱这一关。为什么大模型难以解释?为什么大家总觉得它是一个不可知的“黑箱”?
我的看法是:不是因为它参数多,而是因为我们缺少一种能描述高维结构形状的语言。翻参数矩阵翻到凌晨两点,你看到的只是数字在跳,完全看不到任何“形状”。但如果你把参数、激活值、梯度全部投影成多维空间里的点云,再观察这个点云在不同尺度下的连通性、环、团簇和空洞,你会发现模型内部不是一团浆糊,而是被人训练出了有规律的结构。
拓扑数据分析(TDA)提供的正是这套语言。
4.2 两个常用工具:持久同调与mapper
我会推荐从两个工具入手,别一开始就扑向复杂算法。
第一个是持久同调(Persistence Homology)。它的核心思路是:在多个尺度下观察点云中“环”和“洞”的出现与消失。一个环如果只在极窄的尺度范围存在,那基本可以判断是噪声;如果一个环跨越了很宽的尺度范围仍然存在,那它大概率是空间里的真实结构。打个比方,从高空看北京和上海的夜景,你会发现各种环形立交桥——小尺度下的圆可能是交通标识的噪声,大尺度下一圈一圈的环路则是稳定的城市骨架。持久同调就是自动发现这些“大尺度下仍然存在的环”。
第二个是Mapper。它的思路更像画地铁图:把高维点云切成很多重叠的小区间,在每个小区间里做聚类,然后根据聚类之间的重叠关系建边,最后得到一个抽象图。这样你就能把几万维的激活空间压缩成一张能看懂的“地铁线路图”,哪些社区连着哪些社区,哪些节点是hub,一目了然。
这两个工具各有用处:持久同调告诉你“这里有没有一个洞”,Mapper告诉你“这个洞长什么样、周围有哪些聚类”。
4.3 能干什么:诊断、剪枝、确定知识拓扑、模型合并
TDA在模型上有很多实际用途,我这里说四个我认为最落地的方向。
方向一是解决训练诊断问题。有时候loss就是不降,看起来像“困在局部最优”,但TDA看损失景观(loss landscape),你会发现模型参数根本不是困在点状坑里,而是陷在了一个拓扑环上——它在环上游荡。这时候光调学习率没用,需要打破环结构,比如用warm restart把参数推出这个环。
方向二是做结构化剪枝。传统剪枝按绝对值大小、梯度重要性排名来砍参数,但TDA可以告诉你哪个子结构是“冗余环”——它几乎不参与主干连通结构,砍掉它对全局拓扑影响极小。用这种思路做的剪枝,往往能保留更好的下游效果。
方向三是判断知识是否局部化。用Mapper分析factual类任务上的激活,你能直观看到是否有一个独立的“事实知识社区”。如果这个社区存在,说明模型把知识存在了特定区域,这对幻觉诊断很有帮助:当某个query的激活点落在知识社区的边缘、而不是中心时,生成结果的不确定性会显著升高。这是幻觉的一种结构特征。
方向四是模型融合判别。两个版本模型的分支之间是否存在低损失的连通路径?如果存在,模型可以安全merge;如果不存在,两者的表征空间断层了,硬融会崩。这个判断本质上是拓扑问题。
4.4 案例推演:3B模型激活流形的环形结构
分享一个我们组里的实际分析案例(细节做了脱敏)。我们对一个开源3B模型跑了一批事实问答,采集了中间层100万条激活向量,抽样后跑到TDA管线里。
结果在第12层到第16层之间,发现了一个非常显著的持久环(H1 lifetime很长)。顺着这个环往下挖,我们定位到一组attention head,它们在序列维度上形成了一个循环依赖结构:A头关注B头关注过的token,B头又回采A头输出,形成一个信息回流环。
这个发现带来了两个直接收益。一是诊断收益:推理时如果对这个环做退化扰动,模型在这类事实问答上的准确率明显掉点,说明它承担的是核心信息路由职能;二是剪枝收益:另一个单独形成离群小簇、几乎不和主干图连接的头,被判定为低价值冗余节点,裁掉后下游任务几乎不掉点。
这里的关键不是“我们找到了几个环”,而是拓扑分析把剪枝和解释从“看运气”变成了“看结构”。这两个操作,用传统统计方法是很难稳定复现的。
4.5 灰箱而不是白箱:边界要说清楚
不过我必须给“黑箱破解”泼一盆冷水。TDA能给你的是一个结构层面的x光片,但不等同于把模型彻底白箱化。它能告诉你“这里有一个知识社区”,但不会告诉你这个社区对应的到底是“法国的首都”还是“猫的品种”。要赋予每个拓扑结构具体语义,还得靠 probe、归因或其他方法去对齐。
我更愿意把它叫“灰箱化”或者“拓扑破窗”:你不透明,但我能在结构层开一扇窗,看到里面的形状。这一点在工程上已经非常够用了——因为剪枝、诊断、容错只需要结构,不要求语义全知。
5. 落地框架:四步走完成一次拓扑化改造
5.1 第一步:把作业变成图
所有分析都从“建图”开始。我这里说的图不只是计算图,还包括数据流图和物理拓扑图。
实际操作上,计算图可以通过torch.fx或者XLA HLO dump拿到。物理拓扑图则需要读取集群的网络配置,至少要区分NVLink域内和跨域的通信代价——这个代价差距动辄一个数量级,绝对不能合并成一个值。数据流图则通过profiler在运行时采集流经每个边的张量shape、数据量、耗时。
注意一个小坑:torch.fx默认是symbolic tracing,碰到动态shape、控制流多的模型会爆。我的经验是先跑一遍静态shape的trace,再做算子归并,把elementwise的小算子合并成节点,再把无关紧要的metadata全丢掉。这样图会从几万节点瘦身到几千节点,后面所有的GNN编码和搜索都会快一大截。
5.2 第二步:量化结构指标
光有图还不够,你得把图变成可以优化的数值。我建议团队先建立自己的结构指标基座。下面是我们内部用的一组指标,可以给你做参考:
| 指标名称 | 定义 | 主要用途 |
|---|---|---|
| 通信计算比 | 单step通信耗时 / 单step计算耗时 | 判断是否通信墙 |
| 关键路径长度 | DAG中最长依赖链的节点数 | 判断天然串行瓶颈 |
| 气泡率 | 流水线等待时间 / 总step时间 | 判断并行切分是否均衡 |
| 模块度 | 社区内边占比度量 | 判断图是否存在清晰集群结构 |
| 持久同调寿命 | 拓扑特征的最大persistence | 判断模型内部是否存在稳定结构 |
这些指标的共同点是不依赖业务直觉:你说“这个模型好像有些冗余”,我不跟你吵,直接把这个指标算出来给你看。数据化之后,跨团队沟通效率会高很多。
5.3 第三步:耦合拓扑生成与可解释分析
这一步是把算力优化和黑箱破解连起来的关节。
我建议在自动并行生成的管线里,额外挂一个TDA分析模块。自动并行负责回答“这张计算图怎么切最优”,TDA负责回答“这张图里哪些子结构是可以塌缩的、哪些是必须保留的主干”。两者一结合,就形成了一个闭环:
自动并行找到通信瓶颈 → TDA告诉你瓶颈子结构是否具有冗余拓扑 → 如果冗余,做结构化剪枝或者算子合并 → 剪完再重新生成并行方案。
我们做过一次实验,对一个中等规模Transformer做这样一轮闭环优化,模型体积压缩了约20%,训练吞吐反而提升了,下游指标没有明显下降。这就是“算力革命”和“黑箱破解”在工程上合流的例子。
5.4 第四步:灰度、基准、回流
拓扑生成越强大,就越需要严谨的灰度策略。我的建议是严格分四层推进:
- 模拟器验证:先跑成本模拟,审查生成方案有没有明显的荒唐点。
- 单机多卡试跑:跑2到5个step,验证数值正确性。
- 小集群对照:和当前最佳人工baseline对照,比step time、通信占比、MFU。
- 生产灰度:按流量比例灰度,观察线上稳定性。
每个环节通过后,把数据写进“拓扑档案”——包括模型名称、计算图hash、生成的并行方案、TDA指标、实测性能。这个档案是团队最宝贵的资产,下一次有相似模型进来,直接用档案里的冷启动方案做初始基线,搜索成本可以省掉一半以上。
5.5 团队与分工方面的建议
这个方向对团队的要求不像想象中那么高,但角色一定要配齐。最少需要三类人:
- AI Infra工程师:负责建图、自动并行、模拟器。
- 算法研究员:负责TDA分析、剪枝策略、模型解读。
- MLOps工程师:负责可观测性、trace采集、灰度部署。
人数不需要多,关键是三类人要在一起办公,而不是各干各的。因为自动并行的输出和TDA的输出经常要互相解释——并行方案为什么差,原因可能藏在拓扑结构里;拓扑结构为什么长这样,原因又可能在并行通信模式里。不在一起,这个反馈闭环根本跑不起来。
5.6 踩坑清单
最后集中说一下我们踩过的坑,希望帮你省几周时间。
第一,别一上来就全自动。搜索空间设得越自由,agent探索得越久,还可能给出“理论上更优但实际上无法落盘”的方案。建议先从固定几个维度(比如TP大小、PP切分点)开始约束,跑通了再逐步放开。
第二,TDA本身很贵。持久同调的时间复杂度对点云规模非常敏感,直接对全量激活跑不现实。我们的做法是先随机采样几千个点,如果结构信号稳定就继续,否则再加大采样。这个策略能省掉90%的计算资源。
第三,过滤半径的超参非常敏感。持久同调的半径上界设太小会满屏噪声,设太大又会把结构全磨平。我的做法是先跑一个尺度的barcode,看寿命分布有没有明显的分层,再用分层点去反推合理的半径范围。
第四,别忽略物理拓扑。很多自动并行论文默认集群是一个完全图,但工程现实完全不是这样。TP组内要尽量放进同一个NVLink域,PP组之间则要选择跨域通信代价最低的路径。默认环境配置不做物理拓扑建模,生成出来的方案一定会在线上翻车。
6. 别神化:这个范式的边界和我个人的判断
现在到处都在讲AI算力革命,讲大模型黑箱,讲范式升级。坦白说,我很担心“拓扑生成范式”这个词被快速消费。它确实解决了一部分真实痛点,但绝不是什么银弹。
它的边界非常清晰。底层数学规律和物理限制决定了:通信带宽就这么大,内存带宽就这么高,算子库的优化空间就那么厚。拓扑优化解决的是“结构组织方式不佳带来的浪费”,解决不了“物理资源本身不够”的问题。如果你的需求本质上就是计算量太大、卡太少,那再复杂的拓扑生成也救不了。
另一个边界是:拓扑分析目前还没有一套行业标准的指标体系和工具链,不同团队用TDA跑同一份数据,可能得到不完全一致的结论。这并不代表方法无效,而是说明这个领域还处在非常早期。谁先把指标体系标准化,谁就能在这个方向上占住生态位。
我个人判断,未来两三年会发生几件事。自动并行会成为大模型训练的默认能力,就像今天的数据并行一样普遍;“拓扑档案”会成为类似CI流水线那样的基础资产,新作业进来先查档案再开跑;模型可解释性不会停留在论文里,而会跟算力治理深度绑定——因为要优化算力,就必须理解模型结构,这是两个问题自然而然的合流。
从我们组的实践体感来说,这套思路最大的价值不是某一个具体工具,而是改变了团队看问题的方式。以前遇到性能瓶颈,第一反应是“哪块慢了”,现在是“这张图哪里长得不合理”;以前遇到模型幻觉,第一反应是“调数据微调”,现在是“先看看激活落在了哪个社区边缘”。这种视角一旦建立起来,后面所有的优化动作都会变得有方向。
如果你也想尝试,建议不要一上来就追求完整的自动并行生成,先从“把你的训练作业画成一张图”开始。等你真正看清了自己的计算拓扑长什么样,你自然会知道下一步该做什么。