我们通过将 Kueue 作为 Kubernetes 准入控制器使用,将 GPU 利用率提升了超过 20 个百分点,同时仍能保障团队的计算容量:为关键工作预留配额,设置可借用空闲容量的共享队列,并在资源所有者需要时通过抢占机制回收容量。保障容量,杜绝硬件闲置。
Runway 在大型 GPU 计算集群上训练最先进的视频生成模型。多个研究和生产团队在隔离环境中共享这些硬件:有些团队运行持续数周的预训练任务,有些团队提供实时生产推理服务,还有些团队进行短期实验迭代。该集群成本高昂且任务关键,因此调度成为重中之重。
我们需要两个通常相互冲突的目标:
- 保障容量。关键训练任务和对延迟敏感的服务需要可预测的 GPU 访问能力。
- 高利用率。闲置的 GPU 意味着预算浪费和研究进度损失。如果一个团队预留了 80 个节点但只使用了 50 个,那 30 个闲置节点每天可能代表数万美元的无效支出。
静态分区可以保障容量但浪费 GPU;完全自由竞争可以最大化利用率但无法提供任何保障。
你真正想要的是一个既能提供保障性预留,又能自动将空闲容量借给共享池,并在所属团队需要时回收的系统。为何选择 Kueue
Kueue 是一个 Kubernetes SIG 项目
kubernetes-sigs/kueue。它遵循 Kubernetes API 规范,作为准入控制器运行,而非替代调度器。这一点很重要:它在现有 Kubernetes 原语之上分层运行,而不是引入自己的调度二进制文件。其功能集涵盖了多租户 GPU 集群所需的一切:组调度、配额管理、抢占、工作负载优先级以及基于队列组的借用机制。
我们考虑过 Volcano 等替代方案,它们拥有更多功能。但 Kueue 凭借其简洁性和集成能力胜出:它与 kube-scheduler 协同工作,而非引入第二个调度器二进制文件。针对我们的使用场景(配额和准入控制,而非自定义放置算法),这个权衡是正确的选择。
Kueue 正在积极开发的两个领域对大规模训练尤为重要:拓扑感知调度(自 v0.14 起为 Beta 功能)。对于多节点训练任务,跨机架/区块/可用区的放置会影响吞吐量。弹性工作负载。在不暂停或重新排队的情况下动态扩缩已接纳任务(仍在完善中)。调度前接纳。
Kueue 位于任务提交和 Pod 创建之间。它决定一个工作负载是否应该启动。Kubernetes 的 kube-scheduler 决定已接纳的 Pod 运行在哪里。
当你提交一个任务时,Kueue 会在 Pod 被创建之前拦截它,并检查集群配额。如果配额可用,Kueue 会接纳该工作负载(将其标记为活跃状态),然后 kube-scheduler 会放置 Pod。如果配额不可用,Kueue 会将其保留在队列中。
当这两种视图一致时,系统运行得非常完美。当它们出现分歧时(而且它们一定会),你就会遇到你职业生涯中最令人困惑的调试过程。预留队列与默认池。
Kueue 的核心抽象是 ClusterQueue:一个带有资源配额以及关于如何使用该配额的规则的命名桶。
以下是我们如何在 Runway 构建队列的:
预留 ClusterQueue 专用于团队或项目。每个队列都有一个
nominalQuota(它拥有的 GPU 数量)。预留队列的 borrowingLimit 为 0:它们不从其他队列借用,但可以回收任何当前正被借用的自身配额。默认 ClusterQueue 是共享的、机会主义的池。它自身有一个较小的 nominalQuota,但可以从预留队列借用未使用的配额。当预留队列空闲或利用率不足时,默认队列会用可中断的工作来填补缺口。
思维模型:一个带有预留许可证的停车场。预留队列就是预留车位:许可证持有者保证有一个车位。默认队列是溢出停车:你可以停在任何一个空的预留车位上,但如果许可证持有者来了,你的车就会被拖走(被抢占),并且你得稍后再回来。
除了预留队列和默认队列,我们还保留了一些特殊用途的队列(例如,本地开发,以便工程师可以在真实的 GPU 上进行迭代,而无需与训练任务竞争;以及用于特征流水线和数据集准备的数据预处理)。出借空闲 GPU。
所有 ClusterQueue 都属于同一个队列组(一组可以共享资源的队列)。在队列组内,Kueue 会追踪每个队列的
名义配额和当前使用量;两者之差即为可借用的资源。示例:三个预留队列加上默认队列。
A 团队预留了 80 块 GPU,但只用了 64 块。B 团队预留了 40 块,但只用了 24 块。C 团队预留了 32 块,但一块都没用。默认队列可以借用这 64 块空闲 GPU,用于运行批量评估、实验和其他可被抢占的工作负载。
从外部看,默认队列的分配量可能很小,但实际的 GPU 使用量却很大。在底层,每一块被借用的 GPU 都归属于某个特定的预留队列,从而实现了资源回收路径。回收资源
当某个预留队列需要默认队列正在借用的容量时:
- Kueue 检测到该预留队列的配额不足。
- Kueue 会选择默认队列中的工作负载进行抢占(优先选择 Kueue 工作负载优先级最低的;若优先级相同,则选择运行时间最短的)。
- Kueue 会挂起被选中的工作负载(终止 Pod)。
- 一旦释放出足够的配额,Kueue 就会接纳该预留队列的工作负载。
这就是让这套系统运转起来的约定:团队获得保障,因为他们总能收回自己的配额;默认队列获得高利用率,因为它能接受中断。如果你将任务提交到默认队列,你的作业必须能够容忍被抢占。抢占并非瞬间完成
在实践中,从“发起抢占”到“预留作业开始运行”之间可能存在 20 到 30 分钟的间隔,原因包括:Pod 终止宽限期、由 Operator 驱动的拆除流程(例如 Ray)和排空序列,以及当默认队列大量借用资源时可能发生的级联抢占。
我们通过两种方式来缓解这个问题:Kubernetes 级别的抢占:我们给默认队列的工作负载分配一个负的 Pod 优先级类(例如 -500),这样当更高优先级的 Pod 处于待处理状态时,kube-scheduler 会主动驱逐它们。应用级别的容错:频繁的检查点、从检查点重启的逻辑以及优雅关闭处理器。两套优先级系统,两个层面
Kueue 和 Kubernetes 各自拥有一套优先级系统;它们是独立的,控制着工作负载生命周期的不同部分。
| 系统 | 控制内容 | 作用范围 | 示例 |
|---|---|---|---|
| Kueue 工作负载优先级 | 准入排序以及队列内部/队列之间的 Kueue 级别抢占 | Kueue 准入控制器 | 训练任务(优先级 1000)与常规评估任务(优先级 500) |
| Pod 优先级类别 | kube-scheduler 抢占机制:节点回收的激进程度 | kube-scheduler | 默认 Pod(-500)会被快速驱逐;预留 Pod(0)则不会 |
在实践中,我们通常希望:默认队列:低 Pod 优先级(快速被驱逐)和不同的 Kueue 优先级(控制哪些任务存活最久)。预留队列:正常 Pod 优先级(0)和反映内部重要性的 Kueue 优先级(例如大型预训练任务)。当配额与现实脱节时
Kueue 基于配额而非物理节点进行决策。关键不变条件是:已分配的配额不得超过集群容量。
在我们的设置中,两个配置源必须保持同步:
- Kueue 预留配置(ClusterQueue 的 nominalQuota)。
- 节点池配置(物理容量)。
我们通过一个 CI 门禁来强制执行这一点,如果总预留量超过总静态容量,则阻止部署。
当这个不变条件被破坏时,症状会非常令人困惑:Kueue 接纳了一个工作负载(配额显示有空余),但 kube-scheduler 无法放置这些 Pod(实际上没有可用节点)。该工作负载在 Kueue 中显示为“已接纳”,但在 Kubernetes 中显示为“待处理”。抽象层断裂之处:已接纳但处于待处理状态
工作负载被 Kueue 接纳,但 Pod 始终无法调度。常见原因:配额与节点容量不一致。Kueue 未统计的 GPU 消费者(DaemonSet、调试 Pod、系统组件)。节点选择器不匹配(工作负载指向不存在或不可用的节点)。抢占速度缓慢
即使 Kueue 挂起了默认工作负载,拆除延迟也可能延迟预留任务的启动。瓶颈通常在于操作算子和关闭顺序。配额变更不会重新调度正在运行的任务
减少
nominalQuota 不会立即抢占正在运行的工作负载。Kueue 通常避免干扰已接纳的工作负载;协调操作仅在提交新任务需要时才会发生。幽灵接纳
Kueue 可能在配额在纸面上有空余时接纳一个工作负载,但物理资源尚未就绪(记账与节点现实之间存在时间差)。完整的接纳路径
分两遍阅读:正常路径:提交 → Kueue 准入(配额)→ kube-scheduler 调度(节点)→ 运行。争用路径:预留任务到达 → 默认策略是借用 → Kueue 抢占默认任务 → 准入预留任务。
反馈循环是关键:默认任务在借用的时间片内运行,当预留工作负载需要容量时便让出资源。我们学到的经验
准入与调度是清晰的边界划分,但你必须对两个层面都进行调试。大多数运维痛点源于 Kueue 的资源核算与集群物理状态之间的不匹配。能够并排展示两种视图的工具是操作体验方面最大的成功。
默认任务作为借用者的模式行之有效。为关键工作负载设置预留队列,其他一切使用默认队列并自动借用,这样无需人工管理即可保持高利用率。实践中我们的利用率约为行业标准的 2 倍。
对抢占的容忍度是文化问题。推广过程不仅仅是配置变更;它需要检查点机制、重启基础设施,以及明确告知默认任务可能被中断的预期。
保持配置同步,否则将自食其果。配额与容量之间的一致性是我们运行中最重要的约束条件。我们的 CI 门禁防止配置漂移,其避免的事故数量超过其他任何单一检查手段。
在此规模下进行 GPU 调度、分布式训练基础设施和集群编排,处于系统工程与机器学习的交叉领域。如果这些问题让你感兴趣,欢迎加入我们。这里有大量激动人心的工作等待完成。
产品 探索 示例 角色 GWM-1 通用世界模型 机器人 SDK Gen-4.5 Aleph Act-Two API
倡议 AI 峰会 2026 ↗ 工作室 AI 嘉年华 ↗ Gen:48 学院 ↗ 资源 创意合作伙伴计划 Runway Builders
公司 我们的研究 出版物 职业 关于我们 客户故事 新闻 人才网络 ↗ 安全
开始使用 面向企业 面向教育 登录 定价 帮助中心 ↗ 数据安全 更新日志
联系 媒体 合作伙伴关系 品牌指南 聚会 ↗ Twitter ↗ Instagram ↗ YouTube ↗ Discord ↗