GPU 贵,空转更贵。很多团队的问题不是「卡不够」,而是调度策略让卡看起来永远不够。
先搞清楚你在调度什么
GPU 调度至少有三层:
- 进程层:谁占着 CUDA context / 显存。
- 作业层:训练 / 推理 / 评测任务如何排队。
- 集群层:多机多卡、亲和性、故障转移。
只盯利用率(nvidia-smi 的 %)不够——显存占用 + 有效 tokens/s 才更接近真相。
显存估算的粗公式
对 Transformer 推理,粗略记住:
- 权重大小 ≈ 参数量 × 字节/参数(FP16 ≈ 2)
- KV cache ≈ batch × layers × heads × seq_len × …(随并发与上下文暴涨)
- 激活 / 碎片留 10%–20% 缓冲
实操建议:
- 为每个模型维护一张「安全并发表」:
(model, max_len) → max_batch - 上线前用真实 Prompt 长度压测,而不是用
"hello"。
共卡策略
常见模式:
| 模式 | 适合 | 风险 |
|---|---|---|
| 一卡一模型常驻 | 延迟敏感线上服务 | 利用率可能偏低 |
| 多模型分时加载 | 低频模型多 | 冷启动抖延迟 |
| 张量并行 / 流水并行 | 超大模型 | 运维与通信复杂 |
| MIG / 虚拟化切分 | 多小作业隔离 | 硬件与驱动门槛 |
经验法则:
- 高频小模型:常驻 + 明确并发上限。
- 低频大模型:按需加载,接受秒级冷启动,或用更小量化版兜底。
- 训练与推理混部:尽量分池;训练抢占推理会直接打穿 SLO。
队列与抢占
一个可落地的队列策略:
- FIFO + 优先级:线上 > 评测 > 实验。
- 资源预留:为线上留「永不被抢」的卡池。
- 超时驱逐:实验任务超时自动释放,防止占坑过夜。
- 公平份额:按团队配额,避免一个人扫光所有卡。
# 伪配置:两池隔离
pools:
serving:
gpus: [0, 1]
preemptible: false
batch:
gpus: [2, 3]
preemptible: true
max_runtime: 4h
可观测指标清单
- 每卡:利用率、显存、温度、PCIe / NVLink 吞吐
- 每作业:排队时长、启动时长、有效运行时长
- 业务:因 GPU 不足导致的 429 / 超时比例
如果「排队很长但利用率很低」,多半是碎片或加载风暴,而不是真缺卡。
小结
GPU 调度的目标不是把曲线拉满,而是:在 SLO 内,用最少的卡完成最多的有效工作。先分池、再限额、后优化并行——顺序反了,容易在错误层级上堆复杂度。