4. GPU资源调度基础
GPU资源调度是连接“用户提交的计算任务”与“底层硬件算力”之间的核心枢纽。与CPU调度主要关注时间片轮转不同,GPU调度必须同时处理计算资源(SM/CUDA Core)、显存带宽、PCIe/NVLink传输以及多租户隔离等多维约束。理解调度器类型、调度策略与资源分配模型,是后续进行性能调优的前提。
一、核心原理:GPU调度的三层视角
GPU资源调度并非单一模块,而是从硬件到软件分层协作的结果。我们可以将其拆解为三个层次:
- 硬件层(GPU内部调度器):GPU硬件自带的Work Scheduler(工作调度器)负责将线程块(Thread Block / CTA)分发到SM上。它遵循“先到先服务+负载均衡”的硬件逻辑,每个SM可同时驻留多个线程块,直到资源(寄存器、共享内存)耗尽。
- 驱动/运行时层(CUDA Runtime API):负责将kernel启动参数、显存分配请求转化为硬件指令。此层决定stream(流)的优先级、事件同步以及默认的“广度优先”或“深度优先”调度顺序。
- 集群管理层(Kubernetes + Device Plugin / Slurm + GPU插件):这是数据中心最关注的层。它决定“哪个容器/任务获得哪块GPU”,以及“一块GPU是否被多个任务共享”。
二、调度器类型与策略
根据调度范围与决策频率,GPU调度器可分为三类,各自策略差异显著:
| 调度器类型 | 决策粒度 | 典型策略 | 适用场景 |
|---|---|---|---|
| 集群级调度器 | 容器 / 任务 / Pod | Binpack(装箱)、Spread(扩散)、GPU拓扑感知 | 多租户AI平台、混合训练与推理 |
| 运行时调度器 | CUDA Stream / Context | 默认流串行、多流并发、优先级流 | 单卡多任务、流水线并行 |
| 硬件调度器 | 线程块 / Warp | 硬件轮转、贪心填充SM、Warp级抢占 | 所有kernel执行 |
在集群层面,Binpack策略倾向于将任务尽量集中到少数GPU上,以释放空闲GPU供大任务使用;Spread策略则相反,将任务分散到多张GPU以降低故障爆炸半径。对于多卡训练任务,还需考虑NVLink拓扑亲和性——若两个通信频繁的进程被分配到跨PCIe Switch的GPU上,带宽可能下降30%以上。
三、资源分配模型:从独占到细粒度共享
现代GPU资源分配模型经历了从“整卡独占”到“细粒度切片”的演进,核心模型包括以下四种:
- 整卡独占(Exclusive):一个任务独占整张GPU,显存与计算完全隔离。优点是性能稳定、调试简单;缺点是利用率低,尤其对于推理等轻量任务。
- 时间切片(Time Slicing):多个任务轮流使用GPU,每个任务运行一个时间片。实现简单,但存在上下文切换开销,且不适合延迟敏感型任务。
- MIG(Multi-Instance GPU):A100/H100等硬件支持将GPU切分为多个独立实例,每个实例拥有专属的SM、显存带宽和L2缓存。硬件级隔离,性能可预期,但实例数量固定且无法动态调整。
- MPS(Multi-Process Service):允许多个进程共享同一GPU的SM,但显存仍各自独立。适合多个小batch推理任务并发,但需注意显存容量限制。
四、案例:Kubernetes 下GPU调度配置
以下展示一个使用NVIDIA Device Plugin进行GPU资源分配的示例。假设集群中有4张A100(每张40GB显存),需要部署两个推理服务:
# 推理服务A:请求整卡独占
apiVersion: v1
kind: Pod
metadata:
name: inference-a
spec:
containers:
- name: triton
image: nvcr.io/nvidia/tritonserver:23.10
resources:
limits:
nvidia.com/gpu: 1 # 独占1张A100
---
# 推理服务B:请求MIG切片(1g.5gb,约5GB显存)
apiVersion: v1
kind: Pod
metadata:
name: inference-b
spec:
containers:
- name: triton
image: nvcr.io/nvidia/tritonserver:23.10
resources:
limits:
nvidia.com/mig-1g.5gb: 1 # 使用MIG实例
调度器根据资源请求与节点剩余资源进行匹配。若节点上已有Pod占用了2张整卡,剩余2张卡中,一张被MIG切片占用,则调度器会优先将服务A调度到空闲整卡上,将服务B调度到MIG实例所在节点。若未配置MIG,则服务B只能等待整卡释放。
五、常见误区与复盘
复盘案例:某团队在K8s上运行多个PyTorch训练任务,发现GPU利用率仅40%。排查后发现:所有任务都请求了整卡独占,但每个任务实际只使用约10GB显存(卡容量40GB),且batch size较小,SM占用率低。调整为MPS共享后,将4个任务合并到2张GPU上,利用率提升至75%,同时释放出2张空闲卡供其他团队使用。此案例说明,资源分配模型的选择直接影响集群整体效率,需要结合任务实际资源画像进行决策。
最后需要强调:GPU调度不是“一次配置永久生效”的静态过程。随着业务负载变化,应定期复盘调度策略,利用nvidia-smi、DCGM等工具监控SM占用、显存带宽、MIG实例利用率等指标,动态调整资源分配模型,才能实现GPU集群的高效运转。