深度学习模型上线后,一个普遍现象是推理服务的GPU利用率常年徘徊在20%以下。模型参数加载占用了大量显存,但请求是间歇性到达的,计算单元大部分时间在空转。传统Kubernetes的GPU调度是整卡分配,一张A100哪怕只用百分之十的算力,也会被独占式地分配给单个Pod,其他任务只能排队等待。GPU池化要解决的问题,就是把物理GPU的算力和显存抽象成可切分、可调度、可共享的资源池,让多个推理容器安全高效地共享同一块显卡。

为什么整卡分配模式在推理场景下行不通
Kubernetes原生的device plugin机制只支持把GPU作为整数资源分配,配置nvidia.com/gpu: 1意味着Pod独占一张卡。这种模式对训练任务是合理的,训练通常需要长时间满载运行。但推理负载的特点完全不同:单个请求的耗时常在几十毫秒到几百毫秒之间,而流量有明显的波峰波谷。为了扛住高峰,团队往往按峰值部署副本,结果就是夜间低谷期大量显卡闲置,硬件投入回报率极低。
更麻烦的是显存问题。像LLM这类大模型,光是加载权重就可能占用几十GB显存,但实际推理时的KV Cache增量并不大。显存是整卡分配的硬约束,即使计算侧还有余量,显存不够也无法再部署第二个实例,这进一步加剧了资源碎片化。很多团队被迫买更多机器来放新模型,而不是想办法利用已有的空闲算力。
因此推理场景真正需要的是细粒度资源切分:能按显存大小分配,能按算力比例限额,还能在不同任务之间做到故障隔离,避免一个容器的显存越界把同卡的其他服务一起拖垮。这些能力都需要GPU池化方案来提供。
三类主流池化方案的技术对比
目前业界的GPU池化大致分为三类。第一类是NVIDIA官方提供的MIG(Multi-Instance GPU),从A100、H100等数据中心级显卡开始支持。它通过硬件层把GPU物理切分成最多7个实例,每个实例有独立的SM计算单元和显存分区,隔离性最强,性能损耗接近于零。缺点是切分粒度固定,必须重启GPU才能重新配置,且只支持高端卡型号。
# 开启MIG并按算力比例切分(以A100为例) nvidia-smi -mig 1 # 创建2个3g.20gb实例和1个2g.10gb实例 nvidia-smi mig -cgi 9,9,14 -C # Kubernetes中通过资源名申请MIG实例 # resources: # limits: # nvidia.com/mig-3g.20gb: 1
第二类是软件层面的vGPU切分,代表性项目包括腾讯的HAMI、第四范式的vGPU方案以及开源的k8s-device-plugin扩展。这类方案在设备插件层拦截显存申请,配合CUDA库劫持限制容器可见的显存大小,部分实现还能通过时间片机制限制算力占比。它的优点是粒度灵活,可以按显存任意切分,兼容消费级显卡,成本门槛低;缺点是算力隔离是软性的,高负载下存在抢占,故障隔离也不如硬件方案彻底。
apiVersion: apps/v1
kind: Deployment
metadata:
name: inference-svc
spec:
template:
spec:
containers:
- name: triton
image: nvcr.io/nvidia/tritonserver:24.04-py3
resources:
limits:
# 使用HAMI扩展资源,按显存3GB申请
nvidia.com/gpumem: 3000
# 算力限制为单卡的30%
nvidia.com/gpucores: 30第三类是应用层的多实例共享,即一个GPU上运行一个大的推理引擎进程(如Triton、vLLM),内部通过动态批处理聚合多个模型的请求。这不改变Kubernetes的资源模型,但配合前两类方案使用效果很好:外层用vGPU切分给不同模型分配资源边界,内层用连续批处理榨干算力。实际生产中往往是三层手段的组合,而不是单选其一。
池化方案的调度与落地实践
选型只是第一步,真正落地还要解决调度层面的问题。原生调度器不了解GPU的拓扑关系,可能把两个都申请半张卡的Pod调度到不同节点,导致每台机器都留下一半空闲资源。引入拓扑感知调度或二进制打包策略后,调度器会优先把碎片化任务聚拢到同一张卡上,腾出完整显卡给大任务。HAMI等方案自带调度器扩展,支持显卡维度的binpack和spread两种策略,前者省电省资源,后者利于性能隔离,可以按业务重要性分别配置。
另一个关键点是配额与优先级。池化之后同卡混布了多个服务,必须用ResourceQuota限制每个命名空间的显存总量,用PriorityClass区分在线推理和离线任务。当资源紧张时,低优先级的离线批处理可以被抢占或驱逐,保证在线服务的时延SLA。监控方面,除了常规的Pod指标,还需要采集每张物理卡的SM利用率、显存水位和NVLink带宽,基于这些指标做弹性伸缩才靠谱,因为池化后单Pod的GPU指标已经不能反映真实负载了。
# 基于池化后集群总显存水位做扩容判断的简化示例
def need_scale_out(cluster_metrics):
gpu_util = cluster_metrics["avg_sm_util"]
mem_usage = cluster_metrics["total_mem_used_ratio"]
p99_latency = cluster_metrics["p99_ms"]
# 算力、显存、时延三维度综合判断
if gpu_util > 0.85 or mem_usage > 0.9 or p99_latency > 200:
return True
return False最后给一个务实的选型建议:预算充足且使用A100以上卡型、对隔离性要求极高的核心业务,优先用MIG;卡型混杂、希望在存量消费级卡上快速提升利用率的团队,选HAMI这类软件切分方案起步;同时无论选哪条路线,都应在推理引擎侧开启动态批处理,并建立以物理卡为单位的监控体系。GPU池化不是某一个组件的功能,而是调度、隔离、引擎、监控四层协同的系统工程,分阶段演进比一步到位更容易成功。
KubernetesGPU池化推理服务修改时间:2026-09-13 19:50:01