GPU 算力调度:白天推理、晚上训练,一块卡怎么掰成两半用?
做一个思想实验。
假设你是一家 AI 公司的 CTO,公司刚花 2000 万采购了一批 A100 GPU。财务总监走过来问你:"这批卡的利用率是多少?"
你看了看监控面板,沉默了。
55%。
也就是说,将近一半的算力,正在空转。这不是你一家的问题——业界调研数据显示,大多数 GPU 集群的平均利用率在 55%-65% 之间。OpenAI 自己都承认,即便有六个月的训练任务积压,他们的集群仍有 43% 的时间处于闲置状态。
2000 万的 GPU,有 800 多万在"睡觉"。
问题出在哪?不是 GPU 不够用,是用法不对。白天,推理服务忙得冒烟;凌晨,推理请求断崖式下跌,GPU 却不知道该干嘛。训练任务呢?排在队列里等着,因为调度器不敢把它塞进正在跑推理的卡里。
这篇文章,我想跟你聊聊怎么让 GPU 集群从"半梦半醒"变成"全年无休"——从 Kubernetes 分时调度到混部隔离,从朝夕潮汐策略到推理训练的调度差异,一套组合拳打下来,利用率从 55% 拉到 85% 以上,不是梦。
为什么你的 GPU 集群有一半在"睡觉"?
要回答这个问题,你得先搞明白一件事:推理和训练,根本不是一类工作负载。
打个比方。推理服务就像医院的急诊室——7×24 小时在线,随时可能来病人,每个病人要求"快",10 毫秒给结果,100 毫秒就算超时。但急诊室有个特点:忙闲不均。白天人满为患,凌晨三点可能空无一人。
训练任务呢?更像住院部。病人住进来,少则几天、多则几周,不着急出院,但要求病房稳定——你不能把人半夜赶出去腾床位。训练任务要的是持续、大块的计算资源,动辄跑几天甚至几周,中途被打断代价极高。
矛盾就来了:
- 推理服务白天吃满 GPU,晚上空着
- 训练任务想要整块 GPU 跑个三天三夜,但白天抢不到资源
- 调度器左右为难——给训练吧,推理来了怎么办?不给训练吧,晚上卡闲着也是闲着
这就好比一条高速公路,早高峰堵得水泄不通,凌晨空空荡荡。你不可能把公路拆了重建,但你可以让它在不同时间段服务不同的车流。
所以问题的本质不是"GPU 不够",而是调度策略跟不上工作负载的节奏。推理和训练像两个生物钟完全不同的室友,你得学会让他们分时使用同一张床。
不是 GPU 不够用,是你的调度器还活在"一人一卡"的石器时代。
那 Kubernetes 有什么招?
Kubernetes 怎么把一块 GPU 掰成几份?
传统 Kubernetes 调度 GPU 的方式简单粗暴——一个 Pod 申请 nvidia.com/gpu: 1,就独占一整块卡。哪怕你的推理服务只用了 20% 的显存和 10% 的算力,剩下的也白白浪费。
这就像你去住酒店,只想睡个午觉,前台说"不好意思,最少租一晚"。
好消息是,2025-2026 年,GPU 的"分时出租"能力有了质的飞跃。目前主流的方案有三种:
方案一:Time-Slicing(时间片轮转)
最简单的共享方式。多个 Pod 轮流使用同一块 GPU,每个 Pod 分到一个"时间片"。就像大学里的自习室——没有固定座位,谁来了谁坐,到点换人。
NVIDIA Device Plugin 原生支持这种模式,配置极其简单:
# NVIDIA Device Plugin 时间片配置
apiVersion: v1
kind: ConfigMap
metadata:
name: nvidia-device-plugin
data:
config: |
sharing:
timeSlicing:
replicas: 4 # 一块卡虚拟成 4 份
failRequestsGreaterThanOne: false
关键在 replicas: 4 这一行——它把一块物理 GPU "复制"成 4 个逻辑设备,Kubernetes 调度器就能把 4 个 Pod 塞进同一块卡了。
但 Time-Slicing 有个致命缺陷:没有隔离。四个 Pod 共享显存和算力,一个 Pod 吃光了显存,其他三个直接 OOM。这就好比合租公寓不锁门——和平时期岁月静好,一旦有个室友半夜打游戏外放,全楼遭殃。
方案二:MIG(多实例 GPU)
NVIDIA 从 A100 开始支持的硬件级分区技术。它能把一块 GPU 在物理层面切成最多 7 个独立实例,每个实例有自己专属的 SM(流处理器)和显存。
这就不是合租公寓了,这是把一栋别墅改成了 7 套独立公寓,每套有独立的水电表、独立的入户门。隔壁炒菜你闻不到味道。
缺点也明显:粒度不够灵活(只能按固定 profile 切分),而且只有 Ampere 及以上架构才支持。
方案三:KAI Scheduler(NVIDIA 2025 开源)
2025 年 1 月,NVIDIA 开源了 KAI(Kubernetes AI)Scheduler。它做了一件 Kubernetes 原生调度器做不到的事——分数级 GPU 分配。
你可以这样写:
resources:
requests:
nvidia.com/gpu: "0.25" # 只要 1/4 块卡
0.25 块卡、0.5 块卡、2000MiB 显存——随你定。KAI 还支持层级队列、拓扑感知调度和基于时间的公平共享(time-based fairshare),追踪历史 GPU 使用量来分配超额资源。
调度的本质不是"公平分配",而是"把对的资源在对的时间给对的任务"。
但分完蛋糕还有一个更棘手的问题——怎么保证一个人吃蛋糕时不会喷另一个人一脸奶油?
混部隔离:最难啃的骨头
如果说 GPU 共享是"让两个人住同一间房",那混部隔离就是"确保一个人打呼噜时另一个人还能睡着"。
这是整个 GPU 调度领域最难的问题,没有之一。
为什么难?因为 GPU 和 CPU 不一样。CPU 有成熟的 cgroup 机制,Linux 内核天然支持进程级资源隔离。但 GPU 是一个"黑盒"——它有自己的内存管理、自己的调度器、自己的执行引擎,操作系统对它的控制力远不如 CPU。
让我用一个真实踩坑故事来说明这有多危险。
NVIDIA MPS 的"连坐"噩梦
NVIDIA MPS(Multi-Process Service)是一种让多个 CUDA 进程共享 GPU 的技术。它的原理是把多个进程的 GPU kernel 合并到同一个 CUDA Context 里执行,减少上下文切换开销。
听起来很美好,但有一个致命问题:进程间错误传播。
当一个进程在执行 GPU kernel 时出错退出,共享同一个 IPC 和 UVM 的其他进程也会被连带退出。一个 Pod 崩溃,整块卡上的所有 Pod 一起殉葬。
所以,混部隔离的核心挑战可以总结为三个层次:
第一层:显存隔离
最基本的隔离。推理服务 A 申请了 10GB 显存,训练任务 B 申请了 30GB,两者不能互相侵占。MIG 在硬件层面做到了这一点,Time-Slicing 做不到。腾讯的 qGPU 和开源项目 HAMi 则通过 GPU 虚拟化在软件层面实现了显存配额管理。
第二层:算力隔离
比显存更难。即使显存隔离了,两个任务仍然在争抢 SM(流处理器)。MPS 的策略是"贪心调度"——尽可能多地把 kernel 塞进 GPU,最大化利用率。但这也意味着:延迟敏感的推理任务在排队等待,因为 GPU 正在忙训练任务的大 batch 计算。
USENIX ATC 2025 的一篇论文提出了"快速上下文切换"方案——当推理请求到来时,可以在微秒级别暂停训练 batch、切换到推理模式、完成推理后再切回来。类似于 CPU 的中断机制,但在 GPU 上实现起来要难得多。
第三层:故障隔离
也就是 MPS 踩的那个坑。MIG 通过硬件分区彻底解决了这个问题——每个 MIG 实例有独立的 ECC 错误隔离和独立的 CUDA Context,一个实例崩溃不影响其他实例。
我的判断是:在生产环境中搞混部,MIG 是底线,不是选项。没有硬件级隔离就搞推理+训练混部,就像不系安全带上高速——大多数时候没事,出事就是大事。
2025 年新出现的 CRIUgpu 项目值得关注——它实现了 GPU 容器的全透明 checkpoint/restore,让训练任务可以在微秒级别被"冻结"和"解冻",不丢失任何进度。这为更精细的混部隔离打开了新的可能。
隔离不是技术问题,是信任问题。你敢不敢把推理 SLA 押在隔离机制上,取决于隔离做得有多硬。
解决了隔离,下一个问题是:怎么让 GPU 在白天和晚上干不同的活?
朝夕调度:白天推理,晚上训练
如果你在北京开过车,你一定见过"潮汐车道"——早高峰进城方向多一条车道,晚高峰出城方向多一条。车道没变多,但通行效率提高了 30%。
GPU 的朝夕调度(Tidal Scheduling),就是算力世界的潮汐车道。
核心逻辑:推理和训练的时间差
看一下典型的推理请求量曲线:
- 9:00-22:00:用户活跃期,推理请求量高峰,GPU 需要保障低延迟服务
- 22:00-次日 9:00:请求量跌至白天的 10%-20%,大量 GPU 闲置
而训练任务恰好相反——它不关心什么时候跑,只关心能跑多久。凌晨给它 11 个小时的连续 GPU 时间?求之不得。
这就是天然的互补关系。
实操:Kubernetes + Kueue 的潮汐策略
Google 的 GKE 文档给出了一套完整的混合工作负载方案,核心组件是 Kueue——一个 Kubernetes 原生的任务队列系统:
# Kueue 配置:推理优先级高于训练
apiVersion: kueue.x-k8s.io/v1beta1
kind: WorkloadPriorityClass
metadata:
name: inference-high
value: 1000 # 推理任务优先级
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: WorkloadPriorityClass
metadata:
name: training-low
value: 100 # 训练任务优先级(可被抢占)
关键在第二个配置——训练任务标记为"可被抢占"。白天推理高峰来了,Kueue 会自动暂停训练任务、释放 GPU 给推理服务;晚上推理流量下降,训练任务自动恢复。
但这里有个关键问题:训练被打断了,进度怎么办?
Checkpoint:训练任务的"存档点"
训练任务不像推理——中断即丢失。你跑了 8 个小时的训练,被推理抢占后直接 kill 掉,那 8 个小时就白费了。
解法是 checkpoint 机制。训练任务定期把模型权重、优化器状态、训练步数保存到持久化存储(通常是 NFS 或对象存储)。被抢占时,保存当前 checkpoint;恢复时,从最近的 checkpoint 继续。
2025 年的一个重要进展是 CRIUgpu——它把 checkpoint 做到了 GPU 容器级别。不需要应用层代码做任何修改,直接在容器层面冻结整个 GPU 上下文(包括显存内容),恢复时原样解冻。零代码侵入,零稳态性能开销。
最好的调度不是跟时间对抗,而是顺势而为——推理追太阳,训练追月亮。
但要把潮汐调度做好,你还得搞清楚一件事:推理和训练的调度需求,到底差在哪?
推理和训练的调度,到底差在哪?
很多团队在做 GPU 调度时犯的最大错误,就是用同一套策略调度推理和训练。这就像用管理外卖骑手的方式去管理货运卡车——都是"送东西",但节奏完全不同。
外卖骑手(推理):每单要快,10 分钟超时顾客差评,高峰期要弹性扩容,一个骑手可以同时接几单小订单。
货运卡车(训练):不赶时间,但一趟要拉满,中途卸货代价巨大,需要提前规划路线、预留停车场。
具体来看,核心差异有三个维度:
| 维度 | 推理(Inference) | 训练(Training) |
|---|---|---|
| 优化目标 | 延迟(P95/P99 < 100ms) | 吞吐(tokens/秒、samples/秒) |
| Batch 大小 | 1-32(动态 batching) | 4096-65536(越大越快) |
| 任务时长 | 毫秒级(单次请求) | 小时到周级(持续运行) |
| 容错要求 | 单次失败可重试 | 中断需 checkpoint 恢复 |
| 网络需求 | 低延迟、多并发 | 高带宽(all-reduce 通信) |
| 扩缩容 | 秒级弹性(按请求量) | 固定资源(按任务规模) |
调度策略的根本分歧:抢占 vs 预留
推理服务需要抢占式调度——新请求来了,必须立刻有资源响应。GPU 空闲?用。GPU 在跑低优先级任务?踢掉,先服务我。延迟是硬指标,差 50 毫秒用户就能感知到。
训练任务需要预留式调度——给我 8 块 A100,锁定 72 小时,中间不要来抢。训练跑到一半 GPU 被拿走,即使有 checkpoint,恢复也要花时间重新加载模型、暖 GPU 缓存。
反直觉的是,这两种看似矛盾的策略,恰好可以在时间维度上共存。白天推理抢占一切,晚上训练预留整块——这不就是朝夕调度的理论基础吗?
调度器设计的进化
传统 Kubernetes 调度器(kube-scheduler)对 GPU 的理解是"整数设备"——要么给一整块,要么不给。这在 CPU 时代可以接受,但在 GPU 时代完全不够用。
2025-2026 年的趋势是GPU 感知调度器的崛起:
- Kubernetes DRA(Dynamic Resource Allocation):1.31 版本 GA,支持细粒度 GPU 分区和时间片
- NVIDIA KAI Scheduler:分数级分配 + 层级队列 + 拓扑感知
- Google Kueue:原生任务队列,支持优先级抢占和公平共享
- SIRIUS(学术界):在推理-训练混部场景中达到 89% 的 SLO 合规率
搞清楚推理和训练的差异,不是为了把它们分开,恰恰是为了把它们更好地放在一起。
未来:GPU 调度会像电网一样自动
回到开头那个思想实验。
2000 万的 GPU 集群,55% 的利用率。如果通过本文讨论的这套组合拳——MIG 硬隔离 + KAI 分数调度 + Kueue 优先级抢占 + 朝夕潮汐策略——把利用率从 55% 拉到 85%,意味着你在不加一块卡的情况下,等效多出了 550 万的算力。
这不是小钱。
但我认为,今天我们讨论的这些方案,还只是"手动挡"。三年后回看,GPU 调度会像今天的电网调度一样——你打开灯,电就来了,你不需要知道这一度电是火电还是风电、是本地发的还是西电东送的。
我做两个预测,给自己设个 deadline:
预测一:2027 年底之前,主流云厂商会提供"GPU 电网"服务。用户提交任务,声明 SLA 和预算,平台自动决定用哪种卡、在哪个时区、什么时间段执行。推理、训练、微调的调度边界对用户完全透明。
预测二:2028 年,GPU 集群的平均利用率会从今天的 55% 提升到 80% 以上。驱动力不是硬件升级,而是调度软件的成熟。就像从手动挡到自动驾驶,硬件没变,软件让一切不同。
一年半后回来看看,我说得对不对。
参考资料
- Red Hat - Optimizing GPU ROI: Inference by Day, Training by Night (2025)
- USENIX ATC 2025 - Colocating ML Inference and Training with Fast GPU Context Switching
- CIO - How Kubernetes is Solving the GPU Utilization Crisis (2025)
- Google GKE - Optimize Resource Utilization for Mixed AI/ML Workloads
- NVIDIA KAI Scheduler - GitHub
- Tally: Non-Intrusive Performance Isolation for Concurrent DL Workloads
- CRIUgpu: Transparent Checkpointing of GPU-Accelerated Workloads
- ACM Computing Surveys - Deep Learning Workload Scheduling in GPU Datacenters
- 知乎 - Kubernetes 容器平台下的 GPU 集群算力管控
- 腾讯云 - 提升 GPU 利用率:探索 NVIDIA 的 MIG 与 MPS 虚拟化技术