在集群环境中讨论 GPU 共享,本质上要在利用率、隔离性和调度复杂度之间找到平衡。NVIDIA 从 Ampere 架构开始引入 MIG(Multi-Instance GPU),让一块物理卡可以被拆成多个独立的计算实例,这种做法把共享从软件层推进到了硬件层。本文以 A100 和 H100 为例,说明如何选择共享策略、完成 MIG 配置,以及如何在 Kubernetes 中把切分后的实例作为可调度资源使用。

三种 GPU 共享路径的差异
单卡多任务运行的需求首先来自利用率。训练任务往往不能占满一张 80GB 的 A100,而推理服务只吃一小部分算力。如果不做共享,集群中的卡只能被一个任务独占,成本压力会非常大。常见的共享路径有三种:时间切片、MPS 进程隔离和 MIG 硬件切分。
时间切片通过 CUDA time-slicing 让多个进程轮流使用同一块 GPU,配置成本最低,但所有任务共享同一段显存,任何一个任务出现显存超限都可能影响同一张卡上的其他任务。MPS(Multi-Process Service)则是把多个 CUDA 上下文合并成一个上下文,减少上下文切换,适合小任务并发,但故障隔离能力仍然不足。MIG 直接在硬件层面划分 SM、显存和 L2 cache,每个实例拥有独立的错误隔离边界,不会因为邻居任务崩溃而导致整卡不可用。
| 共享方式 | 隔离级别 | 显存隔离 | 性能抖动 | 适合场景 |
|---|---|---|---|---|
| 时间切片 | 进程级 | 否 | 较高 | 开发调试、轻量任务 |
| MPS | 上下文级 | 共享 | 中 | 多路小推理任务 |
| MIG | 硬件级 | 独立 | 低 | 训推混合、多租户隔离 |
从调度角度看,时间切片和 MPS 虽然能提高瞬时利用率,但不能解决显存争抢,调度器也很难准确衡量剩余资源。MIG 把一块物理卡变成了多个可独立计数的设备,这与 Kubernetes 的资源模型更加匹配,也为后续的资源配额、限额和多租户管理提供了基础。
MIG 切分的命令行实战
在动手之前需要确认 GPU 是否支持 MIG。A100 40GB/80GB、A30、H100 等数据中心卡支持 MIG,GeForce 等消费级卡不支持。启用 MIG 前最好先停止该卡上的任务,然后使用 nvidia-smi 子命令完成配置。下面的示例把一块 A100 80GB 切成一个 2g.20gb 实例,实际可以根据需求用多个 profile 组合切分整卡。
sudo nvidia-smi -i 0 -mig 1 sudo nvidia-smi -i 0 --query-gpu=name,memory.total,mig.mode.current sudo nvidia-smi -i 0 -cgi 2g.20gb -C sudo nvidia-smi -i 0 -cci nvidia-smi -L
这里 -mig 1 打开 MIG 模式,-cgi 2g.20gb -C 创建 GPU 实例,-cci 为其创建计算实例。MIG 中的 GPU 实例(GI)负责分配固定的 SM 和显存切片,计算实例(CI)才是 CUDA 程序真正看到并使用的设备。常见的 A100 80GB profile 包括 1g.10gb、2g.20gb、3g.40gb 和 7g.80gb,不能像切蛋糕一样任意指定显存大小,只能选择厂商提供的组合。
配置完成后,nvidia-smi -L 会输出类似 MIG 2g.20gb Device 0 的设备块,而不再只是 GPU 0。如果需要销毁 MIG 并恢复整卡,可以先删除计算实例和 GPU 实例,再关闭 MIG 模式。示例如下:
sudo nvidia-smi -i 0 -cci 0 sudo nvidia-smi -i 0 -cgi 0 sudo nvidia-smi -i 0 -mig 0 sudo nvidia-smi -i 0 --gpu-reset
恢复整卡后,原有显存和 SM 会合并回来。需要特别注意的是,MIG 切换属于比较重的操作,生产环境应当把它放进维护窗口或节点初始化流程,避免在业务运行期间频繁创建和销毁实例。
Kubernetes 中的 MIG 资源发布与调度
在 Kubernetes 集群中,通常通过 NVIDIA GPU Operator 安装设备插件和 MIG Manager。这个组件会把每个 MIG 实例发布为独立的扩展资源,名称与 profile 对应,例如 nvidia.com/mig-1g.10gb 或 nvidia.com/mig-2g.20gb。这样 Pod 可以直接申请一个 MIG 实例,而不用关心它位于哪张物理卡上。
apiVersion: apps/v1
kind: Deployment
metadata:
name: inference-on-mig
spec:
replicas: 2
selector:
matchLabels:
app: inference
template:
metadata:
labels:
app: inference
spec:
containers:
- name: app
image: my-inference-image
resources:
limits:
nvidia.com/mig-1g.10gb: 1
requests:
nvidia.com/mig-1g.10gb: 1
这段声明会让调度器找到拥有对应 MIG 实例的节点并完成绑定。与整卡 GPU 资源不同,MIG 资源粒度更小,适合推理、小规模训练和交互式开发。如果节点本身没有提前切分出 1g.10gb 实例,Pod 会一直处于 Pending 状态,因此在发布工作负载之前,需要通过 MIG Manager 的策略或节点初始化脚本保证切分状态。
MIG Manager 通常支持 single、mixed 和 as-needed 三类策略。single 策略会在节点上统一生成一种 profile,mixed 允许按配置生成混合实例,as-needed 则根据到达的工作负载动态调整,但动态调整会涉及实例删除和重建,响应时间较长。对于运行稳定业务集群,建议先在节点池级别定义明确的 MIG 配置,再配合 nodeSelector 或污点把不同类型任务调度到对应节点。
性能隔离边界与排障要点
MIG 虽然提供硬件级隔离,但不同实例仍然共享同一块物理 HBM 的控制器和部分互连资源。因此切分后的有效带宽会按比例下降,而不是完全独立。比如一个 2g.20gb 实例的显存带宽大致相当于整卡的对应比例,如果某个任务对显存带宽极度敏感,切分后吞吐不会线性保持。评估是否采用 MIG 时,可以先在单实例内压测,再对比整卡数据,避免上线后出现不符合预期的性能曲线。
排障时最常用的是查看 MIG 状态和设备列表。以下命令可以快速确认当前卡的 MIG 模式、实例数量以及 MIG 设备 UUID:
nvidia-smi -i 0 --query-gpu=name,mig.mode.current --format=csv nvidia-smi mig -i 0 -l nvidia-smi -L
某些老版本推理框架不识别 MIG 设备,需要把 CUDA 可见设备设置成 MIG UUID 而不是物理卡索引。例如在容器启动参数中加入 CUDA_VISIBLE_DEVICES=MIG-GPU-xxxx。另外,MIG 切分是静态配置文件,无法在实例之间动态挪动显存,遇到碎片化时需要先销毁再重建。因此混部和多租户环境中,最好为 MIG 节点单独打标签,并配合监控系统采集 nvidia.com/mig 相关指标,及时调整节点池的切分配置。
总的来看,MIG 并不是解决 GPU 共享的唯一答案,它更适合对隔离性和稳定性要求较高的训推混合场景。轻量级开发测试仍可用时间切片降低成本,MPS 则可以继续承担多路小推理的并发优化。把共享路径和 MIG 切分策略分层落地,才能让集群 GPU 资源真正用得更满、更稳。