确保Kubernetes集群中GPU分配的平衡:基于时间片的公平调度
NVIDIA Run:ai v2.24引入了基于时间片的公平调度,这是一种新的调度模式,为Kubernetes集群带来了具有时间感知能力的超额资源公平调度。这项能力构建于驱动NVIDIA Run:ai的开源KAI调度器之上,解决了共享GPU基础设施中一个长期存在的挑战。
考虑这样一个场景:两个优先级相同的团队共享一个集群。团队A持续提交较小的作业,而团队B需要运行一个需要更多资源的大型作业。每当资源释放时,团队A的小作业总能立即适配并得到调度。团队B的大型作业则持续等待,直到有足够的资源可用。但在那之前,团队A的下一个小作业又Claim了释放出来的容量。结果是:尽管两个团队具有相同的优先级和权益,团队A的作业一个接一个地运行,而团队B的作业却在队列中无限期等待。
基于时间片的公平调度通过赋予调度器“记忆”来解决此问题。调度器不再仅仅计算某一瞬间的公平份额,而是跟踪历史资源使用情况,并根据过去的消耗量调整每个队列的份额。最近使用较多资源的团队在超额分配中获得较低的分数,而一直等待的团队则会获得提升。
基于时间片的公平调度确保了在数天或数周内计算时间的比例性。这实现了GPU资源的真正时间共享,为偶发的大型作业提供了突发访问能力,并使资源规划与每周或每月的GPU小时预算保持一致。重要的是,保障配额和队列优先级完全不受影响,继续按原样工作。
本文更详细地解释了该问题,通过一个真实用例进行说明,并演示了如何在NVIDIA Run:ai和KAI调度器中启用基于时间片的公平调度。
为什么超额配额GPU资源的公平性很重要?
企业部署显示出一个一致的模式:当组织从静态GPU分配转向动态调度时,集群使用变得动态得多。超额配额资源(保障配额之外的共享池)成为使用最频繁的资源类型之一。团队经常超出其保障配额,从而提高了GPU利用率,也为研究人员带来了更多的计算时间。
这使得超额配额的公平性变得至关重要。当集群价值的很大一部分来自这个共享池时,该池需要随着时间的推移被公平地划分。
无状态公平共享调度是如何工作的?
经典的无状态公平共享算法分两个阶段划分集群资源。首先,它分配“应得配额”,即每个队列有权获得的保障资源。此分配始终优先进行,不受历史使用情况的影响。基于时间片的公平调度不改变此行为。
满足应得配额后,任何剩余容量成为“超额配额池”,一个队列根据其权重竞争的共享剩余资源。这正是瞬时公平性失效的地方。
在划分超额资源时,调度器会:
- 按优先级级别对队列进行分组,从最高层级开始
- 基于该层级内的权重计算公平份额:
- 使用量低于其公平份额的队列优先获得资源
- 使用作业提交时间打破平局
- 如果资源仍有剩余,则移至下一个优先级层级并重复
问题就在这里。考虑以下两种竞争超额资源的队列类型。
- 当队列具有相同权重时:两者获得相同的计算公平份额。当一个作业完成后资源变得可用时,两个队列处于完全相同的状态——相同的分配量(零)、相同的公平份额、都有待处理作业。调度器无法区分它们,只能诉诸于打破平局的规则(队列创建时间戳,然后按字母顺序),结果总是同一个队列胜出。
- 当队列具有不同权重时:权重较高的队列获得更大的公平份额,这是正确的。但瞬时计算并不跟踪队列是否随时间获得了其比例份额。例如,如果队列A权重为3,队列B权重为1,调度器正确计算出A有权获得超额资源的75%(3/4),B有权获得25%(1/4)。但如果队列A提交大型工作负载,而队列B提交许多较小的工作负载,队列B更容易在其公平份额内适配,而队列A的大型作业则使其超出公平份额。调度器会继续偏好队列B,因为在每个决策点它看起来都“分配不足”。随着时间的推移,队列B最终运行的工作负载远远超过其25%的权益。
在这两种情况下,调度器都没有记忆。它不知道一个团队刚刚完成了一个作业,而另一个团队已经等待了数小时。
基于时间片的公平调度是如何工作的?
基于时间片的公平调度的核心思想很直接:对于每个队列,比较它在配置的时间窗口内实际消耗的超额资源比例,与基于其权重本应收到的比例。然后相应地进行调整。
例如,如果队列A权重为3,队列B权重为1,那么队列A应收割75%的超额资源,队列B应收割25%。如果调度器回顾过去一周,发现队列A实际消耗了90%,而队列B只获得了10%,它将提升队列B的有效权重并降低队列A的有效权重,使未来的分配向75/25的比例平衡。
其他一切保持不变。应得配额仍然首先得到保障。优先级顺序仍然适用。队列层次结构照常工作。基于时间片的公平调度仅改变超额资源池的划分方式。
基于时间片的公平调度如何计算?
调度器使用三个输入来调整每个队列的有效权重:
- 权重: 队列根据其配置的相对于其他队列的权重应获得的比例
- 使用量: 队列在可配置的时间窗口内实际消耗的资源量(默认:一周)
- K值: 调度器纠正不平衡的激进程度。值越高意味着纠正越快。
当一个队列消耗超过其公平份额时,其有效权重会降低。当它被饿死时,其有效权重会提升。这样,分配会随着时间的推移自然地向预期比例漂移。
基于时间片的公平调度可以直接从用户界面启用或禁用(参见NVIDIA Run:ai文档的节点池部分),而窗口大小、窗口类型和衰减率等参数可以通过API进行调整,以在响应性和稳定性之间取得平衡。由于这些设置是按节点池配置的,管理员可以在专用节点池上进行实验,而不会影响集群的其余部分。有关完整详细信息,请参阅基于时间片的公平调度文档。
一些值得注意的细节:
- 使用量是根据集群容量衡量的,而不是根据其他队列的消耗量。这可以防止团队因使用原本闲置的GPU而受到惩罚。
- 优先级仍然优先。基于时间片的公平调度在每个优先级层级内运行。无论历史使用情况如何,高优先级队列仍然在低优先级队列之前获得资源。
示例场景:一个集群,多种工作负载类型
本节通过一个现实场景展示基于时间片的公平调度如何解决异构集群中的资源争用问题。
一个100-GPU的集群由两个具有截然不同工作负载模式的机器学习团队共享。大语言模型团队专注于后训练和推理,保障了30个GPU。视觉团队专注于计算机视觉研发,保障了20个GPU。两个团队的超额配额权重相等。剩下的50个GPU来自超额配额池,可用于突发工作负载。
大语言模型团队运行面向客户的推理端点,服务于生产流量。这些推理工作负载持续使用10个GPU。它们至关重要,绝不能中断。其配额中剩余的20个GPU,加上对超额配额池的访问权限,可在团队偶尔需要根据客户反馈改进模型时用于后训练作业。
视觉团队专注于计算机视觉研究:运行VSCode、测试架构、超参数搜索和训练目标检测模型。他们有稳定的训练作业流,经常利用超额配额池。
问题:突发访问被阻塞
有一天,大语言模型团队完成了一批客户反馈的分析,准备启动一次后训练运行。该作业需要60个GPU:他们自己的20个配额加上来自超额配额池的40个。下面概述了启用和不启用基于时间片的公平调度时会发生的情况。
为了说明此场景,我们使用了来自KAI调度器的开源基于时间片的公平调度模拟器。此工具允许您建模不同的集群配置,并可视化资源如何随时间分配。下面的模拟精确展示了我们示例场景中发生的情况。
未启用基于时间片的公平调度
- 大语言模型团队的推理端点继续在其10个保障GPU上运行(应得配额受到保护)。
- 视觉团队一直在持续运行计算机视觉训练作业,消耗超额资源。
- 大语言模型团队的60-GPU后训练作业进入队列。
- 每当超额资源空闲时,视觉团队总有更多待处理作业准备就绪。
- 视觉团队的作业继续被优先调度。发生这种情况是因为大语言模型团队的40-GPU超额请求超过了其公平份额。当视觉团队仍有待处理作业Claim其份额时,调度器不会分配超出公平份额的资源给大语言模型团队。大语言模型团队必须等待,直到视觉团队的超额使用量下降。
- 大语言模型团队的后训练作业等待……再等待……再等待。
大语言模型团队的推理服务正常,保障配额完美工作。但他们的后训练作业实际上被饿死了,因为一个具有持续工作负载的团队垄断了超额配额池。偶尔使用的用户永远轮不到。
图1. 未启用基于时间片的公平调度时,大语言模型团队的突发作业保持待处理状态,而视觉团队继续使用超额资源
启用基于时间片的公平调度
关于在NVIDIA Run:ai用户界面中节点池下配置基于时间片的公平调度的详细说明,请参阅NVIDIA Run:ai文档或KAI调度器文档。
启用基于时间片的公平调度后,调度器会跟踪历史使用情况。当大语言模型团队提交其后训练作业时:
- 视觉团队因持续进行计算机视觉训练而积累了较高的历史超额使用量
- 大语言模型团队的历史超额使用量极低(他们一直在配额内运行作业)
- 大语言模型团队的有效公平份额因其在超额资源上被“饿死”而得到提升
- 大语言模型团队的60-GPU作业被调度
如果后训练作业运行时间足够长,两个团队最终将时间共享超额资源。大语言模型团队运行一段时间,积累使用量。随着他们的历史使用量增长,视觉团队相对变得更“饿”,开始获得优先权。资源在两个团队之间来回振荡(有时大语言模型作业运行,有时视觉作业运行),从而实现随时间的公平共享,而不是一个团队垄断资源池。
图2. 启用基于时间片的公平调度后,大语言模型团队的突发作业被调度,资源在团队之间公平地振荡
基于时间片的公平调度支持几种重要的模式,包括:
- 保护关键工作负载: 推理端点和其他生产服务运行在保障配额上,完全不受公平性调整的影响。
- 需要时获得突发访问: 不持续消耗超额资源的团队在需要时仍然可以获得突发能力,而不会长时间甚至永久地被阻塞。
- 随时间公平共享: 没有团队可以无限期垄断超额配额池。每个人都能在配置的时间窗口内获得其比例份额。
- 更公平地对待大型工作负载: 在瞬时公平调度中,拥有大型作业的队列常常被降级,因为其他队列的小作业更容易适配。基于时间片的公平调度改进了这一点:随着拥有大型作业的队列积累的使用量变少,它会获得越来越高的优先级,直到获得运行机会。
开始使用NVIDIA Run:ai基于时间片的公平调度
基于时间片的公平调度解决了瞬时公平调度中的一个根本性限制:缺乏记忆。通过跟踪历史使用情况,调度器在时间窗口内公平地分配超额资源,而不仅仅是在每个调度决策点。保障配额保持不变——像推理端点这样的关键工作负载仍然受到保护。
准备好开始了吗?NVIDIA Run:ai v2.24包含了基于时间片的公平调度,可以通过平台用户界面进行直接配置。设置是按节点池配置的,因此很容易在专用池上进行实验,而无需在整个集群中强制使用新模式。有关设置细节,请参阅基于时间片的公平调度文档。
基于时间片的公平调度也在开源KAI调度器中可用。完成配置步骤,启用Prometheus,设置您的参数,然后开始调度。
想在部署前尝试基于时间片的公平调度吗?请查看基于时间片的公平调度模拟器,您可以在其中对队列随时间的分配进行建模。在一个简单的YAML文件中定义您的队列、权重和工作负载,运行模拟,并观察资源如何在竞争团队之间振荡。
要了解有关基于时间片的公平调度以及NVIDIA Run:ai v2.24版本中其他功能的更多信息,请参加即将举行的网络研讨会“通过简化的工作负载管理提升您的AI运维”。FINISHED