1593 字
8 分钟
共享 GPU 省下的一半卡,是原本留给突发的余量

多团队共用一批 GPU,谁要谁借。同一条任务时间线跑完,共用比按团队专给只慢 0.5%,占卡量是专给的 47%。两个数都是我测的。我的判断是:省下的那 53% 不是凭空多出来的卡,是专给模式下的空转余量,而空转余量正是突发要用的那部分。这套机制该做成「有团队明确要才开」,默认不开。

三种给卡方式的用时与占卡量对照

省下的一半卡是空转#

实验集群没有 GPU。我用 KWOK 伪造了 50 台和生产同形的机器,每台 8 张 4090,共 400 张卡,上面跑真实的 HAMi 和 Kueue。负载取 Modal 公开的那条「自动研究」五阶段时间线,固定之后压缩 120 倍,真实 1 分钟压成 0.5 秒。三种给卡方式同时跑同一条时间线:

给法用时卡·秒
专给 40 张卡458.8 秒预留 18352
名义 40 张额度,可借别队空卡461.3 秒实占 8629
只给一台 8 卡工作站1116.8 秒—

共用慢 0.5%,占卡 47%。

这条时间线对卡数的需求不平。前面是一批单卡实验,后面是 5 个 8 卡验证作业。专给必须按峰值 40 张预留,低谷期那些卡空着,账上仍然算你占着。借用方式只在真跑的时候占卡。「不慢」和「省一半」能同时成立,因为省下的 9723 卡·秒全是空转时间,没有从运行时间里抠出来一秒。

一台工作站慢 2.4 倍是同一件事的反面:8 张卡同时跑不下那批单卡实验,五个阶段只能串行。

那段空转正是突发要用的#

集群已有 70% 卡被占用时,跑同一条时间线用时 453 秒,没变慢。同一次实验里,平台为了腾出整机,停掉了其他团队 21 个单卡任务。

腾整机的实现就是驱逐。高占用率下「性能没下降」这个结论,说的不是系统变强了,是成本转移到了别的租户身上。被停的 21 个任务要重跑,这笔时间不进我测的任何一个数。

专给模式下那 53% 的空转,是峰值来的时候随时能用的卡。共用之后它被别队填上了。再有突发,要么等,要么停别人。我测的是「停别人」那条路,453 秒就是这么来的。

开不开这套机制,先是个约定问题:得和同集群其他使用方谈好额度和「谁能停谁的任务」,范围也只限指定的那组机器。

开之前要先调好四处配置#

同一套组件按默认装好,四个实验各自失效一次,原因互不相同,没有一次是卡不够。

限速。默认配置 90 秒内,40 个整卡请求只分到 29 个,80 个 1/10 卡请求只分到 17 个。HAMi 每给一个 pod 选机器要访问 Kubernetes 约 5 次,默认客户端限速每秒 5 次、突发 10 次,折算下来全集群每秒只分得出约 1 个 pod。400 张卡全空着也是这个数。改成每秒 100 次、突发 200 次之后,整卡请求 95% 在 1.52 秒内分到,次日复跑 2.01 秒。

放置策略。全分散时,5 个 8 卡整机请求一个也放不下,集群还空着 280 张卡:每台机器都被插了一两个小任务,而整机要的是 8 张卡在同一台。空卡总量够,没有一台凑得齐。全集中能避免碎片,代价是整卡请求 95% 要等 34.57 秒。按机器分两组——10 台接小请求、40 台接整机——5 个整机请求全部放下,小请求的 95% 等待从 4.97 秒涨到 9.73 秒。

额度口径。10 张卡的额度下同时提 3 个 8 卡请求,按显存记账时 3 个全被放行,10 张卡的额度里放进了 24 张卡,超 2.4 倍。HAMi 能按显存把一张卡切成 10 份,额度的计量单位就成了可任意细分的 GiB,没有哪条约束说这些 GiB 必须来自不同的物理卡。换成按卡数记,一次只放行一个。

抢占。只靠 Kueue 抢占回收额度,150 秒内 5 个 8 卡请求 0 个落地。Kueue 还的是额度,不管被停的任务散在哪几台机器上。额度确实回来了,空出的卡散在几十台机器上,整机请求的拓扑条件一条都没满足。自己写一段逻辑,按机器挑出一台、把它上面的任务腾空,之后 10 个请求全部落在为它腾出的机器上,两次实验的中位时间 30.7 秒和 36.6 秒。

腾整机的第一版还踩了一个竞态:5 次实验 25 个 8 卡请求,7 个落到了没为它腾的机器上。顺序是「列出这台机器上的任务 → 挨个停掉」,而「让机器停止接新任务」在集群里异步生效,列清单和停掉之间的窗口里仍有新任务被调度进来。改成每秒复查一次、直到这台机器确实没有占卡任务为止,10 个全对。

没测到的,和最后的账#

时延只量到「pod 被分到某台机器」。拉 20 GB 级镜像、CUDA 初始化、加载模型全不在测量窗口里;被停掉的任务也不等它收尾和释放显存。KWOK 的节点只在 Kubernetes 里登记、不跑容器,控制面的一切是真的,数据面的一切是假的。实验环境自己也不稳,16 小时内 HAMi 调度器重启了 66 次,源头是本地存储和 etcd 卡顿。时间数字只能当量级看。

跟集群大小无关的是那四种失效方式和它们的根因。突发时「等」那条路我没测,只测了「停别人」。

收益是真的,但前置要先调四处配置,运行期要和别队谈好谁能停谁,而收集需求的群里只有一个研究专项提过要单独提交 GPU 作业。要的人只有一个,代价摊在整个集群上。默认不开,有团队点名要才开。