异构算力的统一调度:混合集群的现实

理想中的算力池是一池同质的水,现实中的集群是一柜一柜的拼盘:不同厂商的卡、不同代际的卡、不同规格的机柜挤在同一个机房。此前的调度文章讲了 Kueue 这类队列机制,但那是以资源同质为前提的;异构才是常态。这篇讲混合集群的调度现实:为什么统一这么难,哪些路线可行,哪些统一不值得做。

混合集群为什么是常态

供给侧决定的拼盘

混合集群的成因在供给侧。高端卡的供应受出口管制与产能约束,国产替代在政策与供应链双重驱动下进入采购清单,多数中大型团队的采购历史就是一张供应链波动的记录表:哪年买到什么卡,什么卡便宜什么卡能买到,决定的不是架构偏好而是到货现实。结果就是同一个机房里不同代际共存,再加上逐步到货的国产卡,形成三代同堂、两家共处的拼盘。混合不是架构选择的失败,是供应链现实的结果,调度体系必须按常态而非例外来设计。

需求侧的异构同样真实

需求侧也在制造异构。推理服务的流量不稳定,适合弹性调度;训练任务大而长,需要整块资源;预处理与评估这类任务对加速卡需求很低。不同业务对不同卡型的适配度也不同:新卡性能强,留给训练与高价值推理;旧卡跑离线批处理与低频推理;国产卡承接可迁移的业务逐步放量。资源与业务的匹配本身就是调度问题的一部分,而不是调度之外的业务细节。此外还有时间维度:新卡到货时旧卡还没退,退役窗口重叠期的集群是两边都有;业务迁移到新平台需要验证期,验证期内两套资源都要保。静态的池划分在这种过渡期会失真,调度策略要能表达「过渡期临时池」这类概念。组织因素同样在制造异构:不同业务团队的技术栈与迁移速度不同,有的团队早早支持新卡,有的团队守着旧栈不动,集群的现实形态就是这些节奏的叠加。调度体系的设计者要接受这个现实,用池与标签表达节奏差异,而不是幻想所有团队同一步伐迁移。

统一调度的三道坎

驱动栈与运行时

第一道坎是软件栈的碎片化。不同厂商的驱动、运行时与容器化方案各成体系,同一个调度器提交的任务,在不同卡型上要经过不同的设备挂载与生命周期管理。K8s 的设备插件机制此前文章讲过,它提供了接入框架,但插件只解决「让调度器看见资源」,不解决「让任务在资源上正确高效地跑」。镜像层面同样分裂:同一个推理框架要为不同卡型准备不同的镜像与依赖,构建与测试的维护成本随卡型数量线性增长。镜像治理是这条坎上最重的日常:为每类卡型维护基础镜像,业务镜像在其上分层构建;基础镜像的升级要有节奏与公告,否则半年后集群里会同时存在十几个版本的镜像,安全补丁推不动,兼容问题查不清。镜像仓库的命名与标签规范看似小事,却是异构集群能否长期维持秩序的分水岭。

算子与生态兼容

第二道坎在更深一层:算子生态。训练与推理框架在不同硬件上的支持深度不同,最新模型结构往往先在主流生态跑通,其他平台的适配滞后数周甚至数月;某些算子在特定卡型上没有高效实现,性能断崖式落后。这让「同一个任务随便扔到任何一张卡」的理想在很多时候物理上不成立——不是调度器调度不动,是任务本身跑不动或跑不快。适配责任的分工要提前谈清楚:厂商承诺适配到框架层还是算子层、滞后多久、由谁验证;自研算子与定制结构谁来移植。这些问题的答案应该写进采购合同与合作协议,而不是等到新模型跑不起来时再扯皮——采购国产卡不只是买硬件,也是买它的软件适配承诺。

性能口径不一

第三道坎是度量。名义算力接近的两张卡,实际训练吞吐可能相差悬殊,调度器若按统一单位做配额与抢占,公平性立即失真。可行的做法是以实测吞吐为口径给每类卡型建立换算系数,配额与成本核算都按系数折算,并定期用基准任务刷新系数。异构调度的第一性问题是度量统一,软件统一反而是其次。度量问题不解决,后面所有路线的账都算不平。系数还会漂移:框架升级与算子优化都会改变相对性能,半年前标定的系数可能已经失真。固定一套基准任务集,定期重跑刷新系数,并把系数的版本记进成本报表——不同时期的成本对比要有可比性,靠的就是系数口径的一致。成本核算也要跟上度量口径:不同卡型的采购成本与折旧周期不同,按统一系数折算后,各业务的算力成本才可比;成本不透明是异构集群治理混乱的放大器——业务方看不到自己消耗的真实成本,就不会主动迁移到更经济的卡型。

三条路线:分池、标签、抽象层

按作业分池

最务实也最常见的路线是分池:把相同或相近卡型的机器划成独立资源池,训练池、推理池、国产卡池各自独立调度,池间不做透明迁移。分池牺牲了全局利用率,换来每池内部的同质性,任务排队的确定性大大提高。分池的粒度是关键决策:按卡型分最细,按用途分更稳,多数团队选择用途优先、池内再分卡型。池间也不是老死不相往来:空闲资源可以临时出借,借出方保留召回权,任务要有被抢占迁移的准备;借还的规则与优先级要在调度层显式配置,否则「谁都在用谁的空闲」会在第一次资源紧张时演变成互相踩踏。

标签化调度

标签化是折中方案:所有机器进同一个调度器,用节点标签标注卡型、代际、用途与网络能力,任务提交时声明资源约束,调度器按标签匹配。它保留了单一调度入口的简洁,又不假装资源同质。代价是任务模板里的标签约束要有人维护,标签体系一旦失真,调度行为就开始玄学化,标签治理是这条路线的长期成本。

抽象层统一提交

第三条路线是建一层提交抽象:上层作业只声明逻辑需求,由适配层负责把任务路由到合适的卡型并完成镜像与参数的自动选择。这层抽象的价值随业务规模上升,多团队共用集群时它几乎是必需品,否则每个业务方都要自学一遍全集群的卡型地图。抽象层的实现深度差异很大,从简单的路由表到完整的编译适配,投入产出要在自己团队的现实约束下评估。实现可以从最薄的一层起步:一张卡型能力表加一个路由规则文件,先解决「任务发到哪」;随业务积累再逐步把镜像选择、参数适配与成本核算吸进来。一步到位的重抽象往往建在错误的假设上,薄起步、随需求长厚,是更稳的路径。三条路线不互斥:常见的成熟形态是分池打底、标签做池内细分、抽象层做统一入口。

训练与推理的异构适配策略

训练与推理对异构的耐受度不同,策略应当分开设计。训练任务重吞吐与稳定性,跨卡型的混合训练在实践中很少划算:通信效率、数值一致性与算子覆盖都构成障碍,主流做法是单个训练任务固定一种卡型,不同实验按优先级分配到不同池。推理则相反,它天然适合异构:模型可以按卡型分别量化与部署,同一服务维持多个硬件后端,流量路由按卡型容量与成本动态分配。此前讲的分布式推理并行策略与量化文章的技术积累,在异构推理场景全部用得上——每个后端一套并行与量化配置,服务层对用户屏蔽差异。工程落地还有一个具体问题:任务提交模板的异构适配。同一个业务往往维护多套提交模板——每类卡型一套资源声明与镜像参数,模板之间的漂移是常见的故障源;把模板生成收敛到抽象层或统一工具,让业务方从「维护多套模板」变成「声明一次、多处渲染」,异构的复杂度就被关进了工具层。训练异构的收益是采购弹性,推理异构的收益是成本优化,两条线的投入产出完全不同,不要用同一套方法硬套。

新卡型投产:接入的全流程

混合集群的运维节奏里,新卡型接入是周期性事件,值得沉淀成标准流程。第一步是评测:用自有业务的真实负载跑基准,厂商宣传性能与自家场景的收益经常对不上,评测结论决定这张卡在集群里的定位。第二步是软件栈准备:驱动、运行时、基础镜像与监控采集器按既有矩阵逐项落地,兼容问题在这一步集中暴露。第三步是试点:选一两个容忍度高的业务小规模验证,跑通调度、监控、日志与故障处理的完整链路。第四步才是放量与业务迁移:按池的规划逐步把适配的业务搬过去,每一步都有回退路径。接入流程标准化之后,新卡型的投产周期可以从按月摸索压缩到按周执行,这正是异构集群走向成熟的标志。

什么不值得统一

统一调度不是越统一越好,有几类边界值得明确。驱动栈差异过大、软件生态尚在早期的卡型,强行纳入统一池只会制造事故,先独立分池观察是更诚实的做法;低时延要求苛刻的核心推理链路,专用池加最短路径比统一调度省心得多;一些遗留的专用系统,改造成本超过收益,维持现状划出集群边界即可。判断标准只有一条:统一带来的利用率收益,是否大于适配与运维的成本。调度体系的演进应该由事故与利用率数据驱动,而不是由架构洁癖驱动。留一块不被统一的飞地不丢人,丢人的是统一层自己天天出事故。判断这件事还有一个组织维度:统一调度需要有人对这层负责,如果团队里没有这样的人力,宁可先分池维持秩序,等有了再统。还有一类边界是网络拓扑强绑定的任务:对互联带宽与物理布局敏感的大规模训练,任务与集群拓扑的耦合很深,把它们纳入跨池调度会破坏亲和性,维持专用池是最省事的选择。

小结

混合集群是供应链现实与需求异构性共同作用的常态,不是可以等它消失的过渡状态。统一调度面前横着三道坎:驱动栈与运行时的碎片化、算子生态的适配滞后、性能口径的不可比,其中度量统一是第一性问题,不解决它,后面所有路线的账都算不平。务实路线是三条并用的组合:分池打底保同质与确定性,标签体系做池内细分与调度匹配,抽象层提供统一提交入口并沉淀卡型地图。训练与推理要分开设计:训练按任务固定卡型、按池分配,推理按卡型多后端部署、流量动态路由。统一有边界,生态未熟的卡型先隔离观察,专用链路保留飞地,一切以利用率收益大于适配成本为判据。异构调度的成熟标志,不是架构图上的一池统管,而是新卡型到货后能在既定流程内快速投产、业务方提交任务时不必关心卡在哪家——现实一点,先做到前者。

← 返回资讯列表

读者留言

COMMENTS 暂无
仅本站原创文章开放留言 · 请勿留下手机号、邮箱等个人信息

还没有留言,来说第一句?