4. GPU调度与队列治理

GPU集群的容量治理,最终要落到调度器上。调度器决定了“谁先拿到卡、谁必须等、谁可以被抢、谁最多只能用多少”。Kubernetes、Slurm、YARN 是三类典型代表:Kubernetes 以 Pod 为调度单元,通过设备插件和扩展资源暴露 GPU;Slurm 以作业和分区为核心,天然支持 GRES(Generic Resource)与 QOS;YARN 则以队列和容器为抽象,通过 Capacity/Fair Scheduler 管理资源。理解它们的 GPU 调度机制,是做好队列治理和成本控制的前提。

一、三种调度器的GPU资源模型

在 Kubernetes 中,GPU 是节点上的扩展资源,由 NVIDIA Device Plugin 或类似组件注册为 nvidia.com/gpu。Pod 通过 resources.limits 申请整数张 GPU,调度器 kube-scheduler 在 Filter 阶段检查节点剩余 GPU 数量,在 Score 阶段结合亲和性、拓扑等打分。Kubernetes 默认不共享 GPU,一张卡只能分配给一个容器,除非使用 MIG、时间片或 vGPU 方案。

Slurm 中 GPU 通过 Gres=gpu:2 或 --gpus=2 申请,由 slurmctld 统一分配。Slurm 支持 GPU 与 CPU、内存的联合约束,并可通过 --gres-flags 控制是否允许跨节点绑定。YARN 中 GPU 由 ResourceManager 的 yarn.resource-types 声明为可数资源,NodeManager 上报,容器申请时以 yarn.io/gpu 形式出现,Capacity Scheduler 或 Fair Scheduler 按队列分配。

三种调度器的GPU资源模型与队列治理对照 Kubernetes 调度单元:Pod GPU资源:nvidia.com/gpu(整数) 队列抽象:Namespace + PriorityClass 配额:ResourceQuota / LimitRange 抢占:PriorityClass + Preemption 公平:无原生公平,靠配额与优先级 共享:MIG / 时间片 / vGPU 默认独占,需插件支持 治理要点 配额防超卖,优先级保关键任务 抢占需谨慎,避免训练中断 Slurm 调度单元:Job / JobStep GPU资源:Gres=gpu:N 队列抽象:Partition + QOS 配额:GrpTRES / MaxTRES 抢占:PreemptType=preempt/qos 公平:Fairshare / Priority 共享:MPS / MIG / 独占 支持GPU绑定与拓扑感知 治理要点 QOS+Fairshare实现多租户公平 抢占策略需与检查点配合 YARN 调度单元:Container GPU资源:yarn.io/gpu 队列抽象:Queue(树形) 配额:Capacity / MaxCapacity 抢占:Preemption(Capacity) 公平:Fair Scheduler / DRF 共享:不支持GPU共享 容器独占GPU 治理要点 队列树+容量保证多租户隔离 弹性队列提升利用率

二、队列优先级与抢占机制

优先级是队列治理的核心杠杆。Kubernetes 通过 PriorityClass 定义优先级数值,高优先级 Pod 在调度队列中优先出队;当资源不足时,kube-scheduler 可以驱逐低优先级 Pod 来腾出资源,这就是抢占。但 GPU 训练任务被抢占后往往需要从检查点恢复,因此抢占策略必须与任务的可中断性匹配。

Slurm 的抢占由 PreemptType 和 PreemptMode 控制。常见配置是 PreemptType=preempt/qos,高 QOS 作业可以抢占低 QOS 作业;PreemptMode=CANCEL 直接取消,PreemptMode=SUSPEND 挂起,PreemptMode=REQUEUE 重新排队。对于 GPU 作业,REQUEUE 配合应用层检查点是最温和的方式。

YARN 的 Capacity Scheduler 支持队列间抢占,当某队列资源低于其保证容量时,可以从其他队列抢占容器。Fair Scheduler 则通过 fairSharePreemptionTimeout 触发抢占,保证队列在超时后获得公平份额。YARN 的抢占粒度是容器,GPU 容器被抢占后同样面临任务中断问题。

三、公平共享与配额管理

公平共享的目标是让多个团队或用户在长期维度上获得与其权重相称的资源。Slurm 的 Fairshare 基于历史使用量计算每个账户的份额因子,使用越少优先级越高,从而自动纠偏。YARN Fair Scheduler 使用 DRF(Dominant Resource Fairness)算法,在多维资源(CPU、内存、GPU)中找主导资源,按主导资源份额进行公平分配。

Kubernetes 没有原生公平调度,通常用 ResourceQuota 限制 Namespace 的 GPU 总量,用 LimitRange 限制单 Pod 的 GPU 申请范围。如果需要更细的公平性,可以引入 Volcano、Koordinator 等批调度器,它们支持队列、组调度、公平份额和 GPU 共享。

配额管理的关键是“硬配额防超卖、软配额促利用率”。硬配额保证关键团队在高峰期有卡可用;软配额允许空闲时借用,但需要时可回收。两者结合,才能兼顾稳定与成本。

四、实操示例:Slurm QOS 与配额配置

下面是一个 Slurm 中为 GPU 集群配置 QOS 和账户配额的示例。假设集群有 64 张 GPU,分为 train 和 infer 两个账户,train 保证 40 张,infer 保证 16 张,剩余 8 张作为共享池。

# slurm.conf 关键片段
SelectType=select/cons_tres
SelectTypeParameters=CR_Core_Memory
GresTypes=gpu
PreemptType=preempt/qos
PreemptMode=REQUEUE

# QOS 定义
QOSName=train_qos
QOSFlags=DenyOnLimit
QOSTRES=gres/gpu=40
QOSMaxTRESPerUser=gres/gpu=20

QOSName=infer_qos
QOSFlags=DenyOnLimit
QOSTRES=gres/gpu=16
QOSMaxTRESPerUser=gres/gpu=8

# 账户与 QOS 绑定
sacctmgr add account train Description="Training" QOS=train_qos
sacctmgr add account infer Description="Inference" QOS=infer_qos
sacctmgr add user alice Account=train
sacctmgr add user bob Account=infer

提交作业时,用户通过 --qos 指定 QOS,通过 --gres=gpu:4 申请 GPU。如果 train 账户已用满 40 张,新的训练作业会排队;此时如果有 infer 的低优先级作业占用 GPU,且 train_qos 优先级更高,Slurm 会触发 REQUEUE 抢占。被抢占的推理作业重新排队,等待资源释放后继续。

五、结果观察与判断依据

配置完成后,需要观察几个关键指标来判断治理是否生效。第一,队列利用率:sinfo -o "%P %G %C" 查看分区 GPU 总量与分配情况;squeue -o "%.10i %.9P %.10q %.10a %.4C %.10b %T" 查看作业的 QOS、账户、GPU 数和状态。第二,抢占事件:sacct -S today -o JobID,JobName,State,ExitCode 中若出现 PREEMPTED 或 REQUEUED,说明抢占已发生。第三,公平性:sshare -l 查看各账户的 Fairshare 因子,因子长期偏离权重说明配额或权重需要调整。

在 Kubernetes 中,可以用 kubectl describe node 查看 GPU 分配,用 kubectl get pods -o wide 观察 Pending 原因;如果大量高优先级 Pod 长期 Pending,说明配额过紧或节点不足。YARN 则通过 ResourceManager UI 查看各队列的 Used/Configured Capacity 和抢占容器数。

抢占不是免费的。GPU 训练任务被抢占后,如果没有检查点,可能损失数小时计算。建议对可抢占队列设置 PreemptMode=REQUEUE,并在训练脚本中定期保存检查点;对不可中断任务,使用独立的高优先级队列并设置硬配额,避免被抢占。

六、治理策略选择建议

选择哪种调度器,取决于集群的主要负载形态。如果以容器化推理和在线服务为主,Kubernetes 更合适,配合 ResourceQuota 和 PriorityClass 即可满足大部分需求;如果以大规模批处理训练为主,Slurm 的 QOS、Fairshare 和抢占机制更成熟;如果已有 Hadoop 生态,YARN 的队列树和容量保证可以复用。无论哪种,核心原则一致:用配额防止超卖,用优先级保障关键任务,用公平共享提升整体利用率,用抢占作为最后手段而非日常手段。

实际治理中,建议先按团队或项目划分队列,为每个队列设置保证配额和上限配额;再定义 2~3 个优先级等级,明确哪些任务可被抢占;最后通过监控数据持续调整权重和配额。GPU 是昂贵资源,调度策略的每一次调整都直接影响成本和交付效率,因此需要以数据为依据,小步迭代。