背景:GPU 能共享,不等于共享得安全
企业部署大模型推理服务时,经常同时面对两类压力:一方面,大规格 GPU 成本较高,单个低流量模型长期独占整卡会造成利用率浪费;另一方面,把多个租户或模型简单塞进同一张 GPU,又容易出现显存互相挤占、尾延迟抖动和故障扩散。
问题的关键不是”能否让多个进程看到同一张 GPU”,而是要明确三种不同的共享语义:
- MIG(Multi-Instance GPU):把支持的 NVIDIA GPU 划分为多个预定义硬件实例,每个实例拥有专属计算和显存资源。
- Time-Slicing:通过时间片让多个进程或 Pod 交替使用同一 GPU,提升并发接入数量,但没有显存和故障隔离。
- MPS(Multi-Process Service):通过共享 CUDA 调度上下文减少进程切换,并允许多个 CUDA 进程的 Kernel 与拷贝操作重叠。
它们并不是三个可随意互换的”性能开关”。生产设计必须先确定隔离等级,再决定资源利用率优化方式。
核心原理:先定义隔离边界,再谈超卖
MIG:把物理 GPU 切成可调度的硬件实例
NVIDIA MIG 会把支持的 GPU 划分为多个隔离实例,每个实例具有独立的计算和显存资源,并以类似独立 GPU 的形式暴露给 CUDA 和 Kubernetes。对于需要明确显存上限、稳定延迟和租户故障边界的在线推理,MIG 通常是更合适的基础层。
MIG 的代价是资源粒度固定。可用 Profile 由具体 GPU 型号决定,不能像 CPU requests 一样随意填写任意核数和显存容量。因此,工程重点从”给 Pod 申请一张 GPU”变成”为模型选择正确的 MIG Profile”。
Time-Slicing:提高接入密度,但不创造隔离
Time-Slicing 会把一张 GPU 广告成多个可分配副本,让多个 Pod 交替运行。NVIDIA 官方文档明确指出,这些副本之间没有显存隔离,也处于同一故障域;申请多个共享副本也不代表能够获得成比例的计算能力。
因此,Time-Slicing 更适合以下场景:
- 可信的同团队工作负载;
- 低占用、短突发的开发或测试任务;
- 可以接受尾延迟互相影响的非关键推理;
- 不支持 MIG 的旧型号 GPU。
它不应被包装成”逻辑小 GPU”,也不适合直接承载互不信任的外部租户。
MPS:降低多进程切换开销,但不是完整租户隔离方案
MPS 通过控制守护进程和共享服务进程协调多个 CUDA 客户端,可减少上下文切换,让不同进程的 Kernel 和内存复制更容易重叠。它适合多个协作型 CUDA 进程共同提高 GPU 利用率。
但在 Kubernetes NVIDIA Device Plugin 中,MPS 共享仍属于实验性能力,并且当前不能与已启用 MIG 的设备同时使用。生产环境不应同时叠加所有共享机制,而应根据隔离和稳定性要求选一条主路径。
Profile 选型:不要只看模型权重文件大小
LLM 推理实例的显存需求至少包括:
required_memory = model_weights + peak_kv_cache + runtime_workspace + allocator_and_safety_headroom
其中最容易被低估的是 峰值 KV Cache。同一个模型在短问答和长上下文、高并发场景下的显存需求可能完全不同。Profile 选型应以目标流量回放为依据,而不是只读取 safetensors 文件大小。
建议为每个模型版本建立一份 Profile 画像:
| 维度 | 说明 |
|---|---|
| 模型精度与量化格式 | FP16 / INT8 / GPTQ 等 |
| 最大输入和输出 Token | 直接影响 KV Cache 上限 |
| 目标并发数 | 决定并发请求峰值显存 |
| 峰值/稳定态显存与 OOM 边界 | 压测实测数据 |
| TTFT、TPOT 和 P95/P99 延迟 | SLO 验证指标 |
| 允许的共享方式 | 独占 MIG / MIG 内 Time-Slicing / 整卡共享 |
Profile 不是静态配置项,而是模型版本、上下文策略和并发目标共同决定的部署制品。
Kubernetes 工程落地
1. 使用 GPU Operator 管理 MIG
GPU Operator 通过 MIG Manager 管理节点的 MIG 模式和几何配置。集群可选择 single 或 mixed 策略:
- single:节点上的 MIG GPU 使用统一 Profile;
- mixed:节点可暴露多种 MIG 资源类型,适合同时承载不同尺寸模型。
示例安装方式:
helm upgrade --install gpu-operator nvidia/gpu-operator \
--namespace gpu-operator \
--create-namespace \
--set mig.strategy=mixed
为节点应用平衡型 MIG 配置:
kubectl label node <node-name> \
nvidia.com/mig.config=all-balanced \
--overwrite
业务 Pod 应显式请求具体 Profile,而不是模糊申请整卡:
apiVersion: v1
kind: Pod
metadata:
name: llm-small-model
spec:
containers:
- name: server
image: example/llm-server:stable
resources:
limits:
nvidia.com/mig-2g.20gb: 1
实际资源名称取决于 GPU 型号和 mixed 策略暴露的 Profile,部署前必须通过节点资源列表确认。
2. 把共享资源名称与独占资源分开
若启用 Time-Slicing,建议设置 renameByDefault: true,把共享资源暴露为 .shared,避免应用误以为拿到的是独占 GPU。同时启用 failRequestsGreaterThanOne,阻止业务通过申请多个副本错误推断计算配额。
version: v1
sharing:
timeSlicing:
renameByDefault: true
failRequestsGreaterThanOne: true
resources:
- name: nvidia.com/gpu
replicas: 2
资源命名本身应表达隔离语义:
| 资源名 | 含义 |
|---|---|
nvidia.com/gpu | 独占整卡 |
nvidia.com/mig-2g.20gb | 独占一个 MIG 实例 |
nvidia.com/gpu.shared | 共享时间片访问 |
不要让三个等级使用同一资源名,再依赖口头约定区分。
3. 将 MIG 重配置视为有损基础设施变更
GPU Operator 文档指出,MIG Manager 在改变配置前会终止 GPU Pod;某些云环境切换 MIG 模式还可能需要节点重启。因此,MIG 重配置必须经过完整门禁:
- 冻结新调度:cordon 目标节点;
- 流量迁移:确认模型副本已在其他节点接管流量;
- 排空 GPU 工作负载:避免在活跃请求期间重构;
- 应用新 Profile:更新
nvidia.com/mig.config; - 等待状态成功:检查
nvidia.com/mig.config.state=success; - 资源验证:核对
nvidia-smi -L、节点 Capacity 和 Allocatable; - 冒烟压测:验证加载、显存、延迟和错误率;
- 恢复调度:uncordon,并分阶段回流。
重配置失败时,回滚对象不是单个 Pod,而是整台节点的 MIG 几何。必须保留前一版本配置和节点级回滚脚本。
调度分层:按业务风险选择共享方式
建议把 GPU 节点池按隔离等级拆分:
| 节点池 | 共享方式 | 适用工作负载 | 主要边界 |
|---|---|---|---|
gpu-exclusive | 整卡独占 | 超大模型、跨卡并行、关键低延迟服务 | 成本最高,隔离最清晰 |
gpu-mig | MIG Profile | 多租户在线推理、中小模型稳定服务 | Profile 固定,重配置有中断 |
gpu-mig-shared | MIG + Time-Slicing | 同信任域的低负载模型 | 实例之间硬隔离,实例内部仍会争用 |
gpu-timeslice | 整卡 Time-Slicing | 开发、测试、低优先级任务 | 无显存和故障隔离 |
这比在同一节点上临时决定”今天共享、明天独占”更容易审计和回滚。
监控:不要只看 GPU Utilization
共享推理的监控需要区分物理 GPU、MIG 实例和业务请求三个层级。
基础设施层
- MIG 配置状态与 Profile 数量;
- GPU/MIG 实例显存使用量;
- SM 利用率、功耗、温度和 XID 错误;
- 节点 Capacity、Allocatable 与实际 Pod 分配;
- MIG 重配置耗时和失败次数。
推理服务层
- 每个模型副本的队列长度;
- TTFT、TPOT、端到端 P95/P99;
- 活跃序列数、Token 吞吐和 OOM;
- 因 Profile 过小导致的加载失败;
- 同一共享实例内的邻居干扰。
需要特别注意:NVIDIA GPU Operator 文档说明,在 Device Plugin Time-Slicing 模式下,DCGM Exporter 不能把指标关联到具体容器。这意味着共享整卡模式的租户级归因能力较弱,关键业务不应只依赖该模式做精细计费或 SLO 归责。
常见误区
误区一:Kubernetes 显示 8 个 GPU 资源,就代表有 8 份算力
Time-Slicing 的副本只是共享访问凭证,不是独立算力单位。资源数量被放大,不意味着计算、显存或带宽等比例增加。
误区二:MIG 能解决所有性能抖动
MIG 提供更强的资源和故障隔离,但应用内部仍可能因为批处理、KV Cache、CPU–GPU 数据通路和模型配置出现抖动。MIG 是隔离基础,不是推理性能调优的替代品。
误区三:Profile 越小,GPU 利用率一定越高
过小 Profile 会导致模型无法加载、KV Cache 容量不足或并发下降。需要比较每张物理 GPU 的有效 Token 吞吐、SLO 达标请求数和空闲碎片,而不是只统计实例数量。
误区四:可以根据实时流量频繁切换 MIG 几何
官方管理流程会停止 GPU 工作负载,部分环境还涉及节点重启。MIG 几何适合按容量周期或维护窗口调整,不适合直接放进在线请求调度闭环。
上线检查清单
- 已确认 GPU 型号支持 MIG,并核对可用 Profile;
- 已记录模型权重、峰值 KV Cache、工作区和安全余量;
- 已通过目标上下文和并发回放验证 Profile;
- 独占、MIG 和共享资源使用不同资源名及节点池;
- Time-Slicing 已开启共享标识,并禁止申请多个副本制造配额错觉;
- 重配置流程包含 cordon、排空、验证、回滚和维护窗口;
- 已验证 MIG 状态、节点资源和
nvidia-smi -L一致; - 已建立实例级显存、延迟、OOM、XID 和配置状态告警;
- 已明确 Time-Slicing 下容器级监控和计费限制;
- 已准备从共享节点回退到独占或更大 MIG Profile 的路径。
常见问题
MPS 是否比 Time-Slicing 更适合 LLM 在线推理?
不一定。MPS 能减少上下文切换并限制客户端的部分计算和显存资源,但 Kubernetes Device Plugin 当前将 MPS 支持标记为实验性,并且不支持在启用 MIG 的设备上使用。关键在线服务应先验证驱动、故障传播、监控和恢复路径。
如何判断应该使用 MIG 还是整卡独占?
当单个模型需要跨卡并行、占用大部分显存,或对尾延迟极端敏感时,整卡独占通常更简单。多个中小模型需要明确显存和故障边界时,优先评估 MIG。只有在可信、低优先级且可接受互相影响的场景下,再使用 Time-Slicing。