Ai2 如何用 GPU 时间预算和分层公平分享调度器优化集群分配
Ai2 AI Infrastructure 团队将基于优先级的 GPU 调度器替换为包含 GPU 时间预算、分层公平分享分配和时间切片合约的系统,管理数千张 NVIDIA H100、B200 和 B300,服务约 150 名内部研究员。此前需求超出容量 2-3 倍,出现 GPU "占坑"、优先级通胀等问题,新系统把 GPU 时间分配从逐案运营任务转为透明的行政预算流程。
Hugging Face 社区博客·2026-10-09 23:20· 36 分钟前AI 评分52
面向 GPU 集群的高影响力调度
AI 导读
Ai2 AI Infrastructure 团队将基于优先级的 GPU 调度器替换为包含 GPU 时间预算、分层公平分享分配和时间切片合约的系统,用于管理数千张 NVIDIA H100、B200 和 B300,服务约 150 名内部研究员,需求超出容量 2-3 倍。
正文
构建集群调度器,优先处理高影响力研究,同时保持满占用率
在 Ai2 的 AI Infrastructure 团队,我们负责提供研究院的 GPU 算力,专门面向大规模分布式训练工作负载。我们把这项任务看作一个由四个指标层层递进构成的金字塔。
基础是可用性:硬件处于健康状态并可供工作的频率。其上是占用率:可用时间中分配给特定工作负载的比例。再上是影响力:最有价值的工作负载被选中获得资源的频率。金字塔的顶端是利用率:在工作负载的整个生命周期内 GPU 容量被使用的比例。
本文讨论的是如何提升我们调度决策的影响力。我们最近将基于优先级的调度器替换为一个包含 GPU 时间预算、分层公平分享分配和时间切片合约的系统。因此,我们把关于每个研究项目应得多少 GPU 时间的争论,从逐案处理的运维任务转变为透明的行政预算流程。
超额承诺
在 Ai2,我们管理数千张 NVIDIA H100、B200 和 B300 GPU,组成规模从 88 到 1024 张 GPU 不等的集群。这些集群专为 AI 模型的大规模分布式训练而构建,服务于约 150 名内部研究员,他们的工作涵盖多样化的 AI 领域,包括 LLM 和 VLM 训练的完整模型流程、机器人强化学习(RL)仿真,以及科学智能体用例的后训练。
和许多实验室一样,我们对 GPU 时间的需求远超供给。根据提交的工作负载,在任何时刻,我们未满足的 GPU 请求量都是可用量的 2-3 倍。一种理解方式是,我们集群上每一个可用的 GPU 小时,都有 2-3 个不同的研究工作负载在竞争。
过去,我们使用基于优先级的调度器,并允许工作负载选择退出可抢占性。每个团队对可免于抢占的工作负载所能使用的并发 GPU 数量设有上限。可抢占的工作负载可以在空闲 GPU 上超出该上限。这种策略产生了可预见的弊病。例如,我们观察到 GPU“占坑”的情况:用户会停放一些空操作工作负载,以便在需要时连接使用。出现这种情况,是因为研究员发现他们无法以足够低的延迟启动调试工作负载来实时解决问题。我们还观察到优先级膨胀,最终 100% 的已调度工作负载都使用 HIGH 优先级。这意味着较低优先级完全得不到 GPU 时间。由于可抢占性是可选的,我们还发现,我们的值班工程师在工单响应时间中,大部分都花在协商有序关闭运行在已知维护问题主机上的不可抢占工作负载。
公地悲剧
当这些问题出现时,我们未能及时找出其根本原因。我们最初尝试确保最重要的工作获得 GPU 时间,重点在于更严格地控制优先级的设定方式,并最终绕过基于优先级的调度器,通过显式地将 GPU 独占权分配给重要项目。虽然我们起初没有意识到,但我们已经建立了一个观察“公地悲剧”的完美实验室。个人在争夺稀缺的共享资源,通过追求个人利益最大化,导致了非最优的全局结果,并滥用了底层资源。
我们远非第一个观察到这种相互作用的人。资源分配是一个引人入胜的研究领域,融合了算法开发、经济学和系统管理。一个核心问题是,用户通常比组织更了解自己工作的价值,但他们可能有动机隐藏这种价值或紧握资源不放,即使这样做会损害整体性能。例如,在 2011 年介绍主导资源公平性的论文中,Ghodsi 等人讲述了一则轶事:一家搜索公司仅为那些用户能保证高利用率的作业提供专用机器。他们很快发现“用户会在代码中散布无限循环,以人为地抬高利用率水平。”硬件在变,但使资源分配变得复杂的根本问题依然存在。
预算而非排期
公地悲剧的经典解决方案是将共享资源私有化——所有者有动力最大化其财产的价值。当我们把一组组 GPU 的独占权分配给团队时,我们已经在做类似的事情,但粒度太粗。由于研究的季节性,这导致 GPU 闲置。团队在不同时间准备好运行实验和训练,因此分配独占权会确保有时没有作业可执行,而另一个团队则在等待容量。
我们是在手动解决一个背包问题,试图将动态变化的研究需求塞进一个静态的排期中。我们想要所有权带来的激励,但也希望保持 GPU 的充分利用。
我们决定在所有权模型上迭代。我们没有向团队发放 GPU,而是选择分配一部分 GPU 时间。预测未来的需求需要知道新颖科学实验的结果,因此无法精确预测。然而,研究工作的优先级是一个战略问题,可以更容易地提前辩论和决定。我们没有试图解决调度难题,而是让领导层像投资者一样思考。在工作负载存在之前,根据他们对每个研究努力可能影响的判断,决定如何用 GPU 时间资助它。调度器随后可以在对到达的工作负载进行优先级排序时使用这些信息。
考虑到这一点,我们设计了一个分层系统,管理者可以按比例将 GPU 时间分配给他们负责的项目和研究人员。如下图所示,这将项目策略直接转化为有保障的 GPU 时间份额。项目 A1 知道它拥有总容量 35% 的份额,无论其他地方有多少其他项目在排队。
括号中的值表示分配给叶子项目的总集群容量。
在这个系统中,每个 GPU 时间请求都必须由预算支持,否则就不受抢占保护。在旧系统中,高优先级不产生任何成本,且不可抢占性允许团队无限期地占满其并发 GPU 上限,因此所有人都使用它们。现在,没有什么是免费的,所以任何获取 GPU 时间的伎俩都会消耗受益用户的分配额度。一个占着资源不干活的工作负载是在白白消耗团队预算。我们的策略是让钻调度器空子比诚实地参与争取更大预算的讨论更昂贵。我们不断迭代这个预算审查流程,但关键要求是研究人员有频繁的机会来争取他们所需的时间,并且决策由对相关权衡最有背景信息的管理者做出。这意味着研究项目内的分配决策由首席研究员做出,研究计划内由首席研究员做出,跨计划由首席计划经理或 CEO 做出。
公平份额
配合这个 GPU 时间预算工具,我们构建了一个分层公平份额调度器,用于管理整个计划树中分配额度的实际占用情况。这里的算法并不新鲜——基于时间窗口的分层公平份额是源自 2009 年的 Hadoop Fair Scheduler 的一脉相承,同样的方法至今仍在 SLURM 的 Fair Tree 和 YARN 的 Fair Scheduler 中积极使用。对我们来说新的是输入:树结构反映了研究计划结构,权重是由管理者设定的预算而非静态配额。
调度器在滑动回看窗口(我们默认 7 天)内跟踪占用情况,并将利用率不足的分配额度中的工作负载排在利用率过高的分配额度中的工作负载之前。这样,在一周的时间范围内,只要各团队持续提交有足够需求的工作负载,我们就能期望每个团队获得其分配的 GPU 时间。
“新调度器让我们感觉多了 30% 的算力。在旧调度器中,如果我们有时不需要用满槽位上限,那部分算力基本上就浪费了。现在有了新调度器,如果出现这种情况,我们之后可以突发超出分配上限,而且我们的作业仍能快速被调度且不被抢占,本质上让我们收回了那部分算力。我们的工作负载往往是突发性的,所以这给了我们大量算力回馈。” —— Chris Clark
调度器区分两种占用。已分配占用是工作负载计入预算的时间。这从工作负载所有者的分配额度中扣除,影响公平份额预算计算,且这些工作负载在其最小运行时间窗口内受到抢占保护。未分配占用不计入任何预算,从一开始就不受保护,可能被任何已分配请求抢占。这使我们即使在分配额度与需求不完全匹配时也能保持 GPU 完全占用,并防止团队拒绝免费的 GPU 周期。
调度契约
分布式训练还有一个特性使得公平的资源分配变得困难,那就是工作负载可以运行很长时间。训练任务通常会运行数小时、数天,有时甚至数周。一旦被调度,一个工作负载可能会在其分配的 GPU 上停留一周或更长时间,让其他人没有机会获得他们应得的预算时间。正是这种系统特性使得 GPU 霸占成为可能。也正是这一点迫使值班工程师与长时间运行任务的所有者协商,以解决持续的维护问题。
为了解决这些问题,我们引入了“调度契约”。作为访问集群的交换条件,工作负载必须声明其最小运行时间,即取得有意义进展所需的最短占用时间。在这段时间内,工作负载受到保护,不会被抢占。这为研究人员提供了进展保证,同时赋予调度器在进展得到保障后重新平衡的权利,自动将可恢复的工作负载重新排队。或者,用户可以将最小运行时间设置为零,表示 GPU 时间不应被分配。这些工作负载始终可能被抢占,但它们也是免费的,因为它们不计入任何预算。
工作负载的生命周期遵循以下模式:
- 工作负载提交时带有最小运行时间,并指明它是否可恢复。
- 工作负载根据公平份额算法进行调度,权重为回溯窗口内实际占用与分配时间的比率。
- 工作负载运行其最小运行时间,这段时间计入其分配额度。
- 只要相关的分配额度继续优先考虑该工作负载而非其他工作负载,它就可以继续运行。这段时间也计入其分配额度。
- 它可能被抢占并重新排队,然后回到第 2 步。
- 工作负载完成,释放其对任何资源的占用。
这些协议共同为我们的调度器增加了时间分片。运行中的工作负载可以被自动移除并重新排队,使公平份额得以收敛,并抑制霸占行为。它们还允许不健康的主机在工作负载达到最小运行时间时将其排空,从而使修复活动可以完全自动化。最后这一点在规划这项工作时比我们意识到的更为重要。它使需要人工介入的修复减少了 74%,这大大节省了值班负担。
模拟
我们知道调度策略的变更可能会产生意想不到的后果。问题的零和性质意味着给一位研究人员时间就意味着从另一位那里拿走时间。在这种交换中受损的用户往往会寻找新的变通方法。在推出基于预算的系统之前,我们希望有一种快速的方法来预测这些更长等待时间可能出现的地方,并测试诸如回溯窗口长度或最小运行时间允许的最大值(我们选择了 8 小时)等配置参数。
我们构建了一个小型模拟环境,它接收一组工作负载及其提交时间表作为输入,并允许调度器做出抢占和 GPU 分配决策。在了解每个工作负载请求的 GPU 数量和总运行时间的情况下,模拟器可以跳转到可调度的时刻,并在几秒钟内为许多模拟日提供队列等待时间、抢占事件以及 GPU 时间在各项目间分布的分析。我们针对历史提交数据和我们希望更好地理解的构造场景运行了模拟器。
我们想要验证的一个假设涉及“调试工作负载”。这些作业需要少量 GPU,最短运行时间为 15 分钟或更短,这足以让用户判断作业是成功启动,还是因 bug 或配置错误而提前崩溃。我们想知道,这些作业的排队等待时间是否会比大型训练工作负载更短,后者通常需要大量 GPU 和数小时运行时间才能取得有意义的进展。直观上,这些较小的作业应该排在队列前面,因为小作业比大作业能容纳的地方更多。但精确的队列延迟很重要。等待一两分钟就能开启一种新的开发实践,而等待十分钟则变得不可行。
我们的模拟需要手工构建的测试用例数据,因为我们的历史记录中没有足够多的这类调试类工作负载。我们的结果支持了这一假设,显示 p90 调试工作负载等待时间从约 6 小时降至仅 5 分钟。
基线(左)和新“分配”调度器(右)的小规模模拟器可视化。每一行是一个 GPU;每个条形是一个作业,按父工作负载着色,每个团队一种色调;斜线标记作业可被中断的时间,红色边缘标记抢占。在基线中,长时间紧急作业从不被中断,较低优先级工作上的抢占也更少。新调度器在每个 GPU 上有更丰富的颜色组合,展示了跨团队的占用轮换。
结果
手握模拟结果,我们在 7 月底开始了逐集群的推广。我们关心的结果是:我们选择资助的工作负载是否获得了它们应得的时间,新系统是否保持了满占用率,以及研究人员能否理解调度器以做出明智决策。
自推广以来,我们观察到用户和团队持续获得其分配的 GPU 时间。我们将欠一个团队的时间计算为其分配量按小时封顶于其实际需求。在 30 天的测试期内,团队获得了其应得 GPU 小时的 98%,15 个团队分配中有 13 个获得了 95% 或更多,最差情况获得了 90%。集群占用率在变更前后稳定保持在 98%,两个时期需求都超过容量 2-3 倍。18% 的已交付 GPU 时间未被分配,这就是我们在已资助用例尚未准备好运行时保持高占用率的方式。
我们的模拟器结果在方向上被证明是准确的,实际结果甚至优于我们的预测。在新调度器下,调试工作负载 p90 队列等待时间从 2 小时降至 30 秒,而基于手工测试场景的模拟预测是从 6 小时降至 5 分钟。值得注意的是,基线中调试工作负载样本量较小,意味着这些测量值方差更高。队列延迟总体上作为时间分片的副作用得到改善:在我们最大的 H100 集群上,中位队列等待时间从 5 分钟降至 24 秒,p90 等待时间下降了约三分之一(从 2.8 小时降至 1.8 小时)。
与我们着手解决的三个问题相比:
占位:短调试工作负载在不到一分钟内启动,降低了占位的价值。这种行为的成本会记入占位者的预算,从而阻止他们在真正需要时获得时间。
优先级膨胀:我们仍然允许工作负载声明优先级,但它只影响团队内部的排序。管理者有动力监控整个团队的优先级,以优化其预算的使用。
值班负担:当工作负载达到最小运行时间时,不健康的主机会自动排空。需要人工介入的修复下降了74%。
挑战
学习曲线比我们预想的更陡峭。我们逐步推出这一变更,因此在早期,研究人员会根据所针对的集群不同而体验到不同的行为。此外,我们的界面保留了一些旧术语(如工作负载优先级),其含义已经改变。仅靠文档无法消除困惑。真正有效的是举办现场讲解会,为研究人员提供一个提问的论坛,并让工程团队使用真实示例更深入地描述调度器如何以及为何做出其优先级决策。
这是一个关键时刻,因为它标志着从早期的挫败感和民间理论转向当前模式,即研究团队更频繁、更广泛地就其实验的GPU需求进行沟通。研究人员现在正以更清晰的认知参与预算讨论,了解为满足任何新请求所做的权衡。
除了现场会议,我们在发布后引入了新的可视化,让用户更好地了解其分配的GPU时间与预期配额的接近程度,并直接暴露用于排序工作负载队列的指标。这提供了一个简单的地方,当工作负载被抢占时可以查看以了解原因。这些可视化也帮助了预算所有者,他们可以看到其管理下各个项目的GPU时间使用情况。
随时间变化的配额使用情况可视化示例。
并非每个用例都得到了改善。除了分布式训练,我们的研究人员还会启动交互式会话,在编写训练代码的同时进行数据分析和测试。在旧系统中,研究人员可以保持这样的会话长达一周。使用时间分片后,他们受到受保护运行时8小时上限的限制,超过配额后会话将变为可抢占。我们没有意识到研究人员在多大程度上依赖这些会话的易变状态。被抢占意味着需要等待获得新会话,并手动重建其状态。在调查研究人员以了解这一问题的广度后,我们创建了两个新的路线图项目。我们正在投资一个紧邻本地存储的纯CPU集群,用于专注于数据准备任务的开发会话。这将为真正需要它的工作负载保留我们的训练集群容量。此外,我们计划为这些纯CPU工作负载构建可恢复的会话。这将使我们能够继续在最小运行时间结束时为维护或时间分片抢占工作负载,同时也能在其他地方恢复会话,而无需研究人员重建。我们可以保留这个新系统在运维和调度方面的优势,同时改善用户体验。
我们持续关注新出现的问题。我们正在调查的一个潜在问题是容量碎片化,这可能会导致最大工作负载的队列等待时间增加。我们的直觉是,最小运行时间保护正被应用于那些过去依赖可抢占机制来超出其团队并发 GPU 限制的作业类型。以前,这些作业可以随时被中断,可能会浪费那段时间,但也使得调度大型作业更容易。现在,调度器可能更少有機會一次性中断许多作业,以放置一个大型待处理工作负载。我们目前正在使用模拟器工具来复现这个问题,同时也在生产环境中测量真实情况。
未来
当我们超越此处描述的调度工作时,我们的目标是金字塔的顶端:利用率。我们需要确保引导、检查点以及训练应用本身都尽可能高效地完成,从而最大化每个工作负载所获得的调度时间的价值。
如果你想与研究人员密切合作来应对这类挑战,我们鼓励你探索 Ai2 的开放工程职位。
来源:Hugging Face 社区博客 · huggingface.co
来源:RadarAI · aihot.news




