05 MIG 与 GPU 虚拟化共享
05 MIG 与 GPU 虚拟化共享
一张 A100 80GB 很贵,但很多小任务用不满整张卡 → 浪费。这一章学怎么把一张卡「切小」、让多个任务/团队共享,把利用率从 30% 拉到 70%。这正是 AI Infra 工程师「省钱」的核心技能。
💡 给你的话:这章的 K8s 类比是「把节点 CPU 切给多个 Pod」——只不过 GPU 切分远比 CPU 复杂:有硬件级(MIG)、驱动级(vGPU)、内核级(qGPU)、用户态库级(vCUDA/HAMi)、进程级(MPS)多种实现,隔离强度完全不同。学的时候始终抓三个问题:在哪一层切?切的是算力还是显存?隔离有多强?
📖 本章导读与前置依赖
- 前置(你已在
01/04学过):GPU 架构(SM/HBM/算力,01)、Device Plugin 资源注册(04:整卡nvidia.com/gpu)。本章解决「整卡分配太浪费」的问题。 - 本章解决什么:怎么把一张卡切小、隔离地共享给多任务——MIG(硬件级)/ vGPU(驱动级)/ qGPU(内核级)/ MPS(无隔离),把利用率从 30% 拉到 70%。
- 学习目标:先建立「空间切分 vs 时间复用」总框架,再逐一吃透四个方案的原理与实现,最后能按场景选型;牢记「利用率 30%→70% 靠 MIG+qGPU+调度三件套」;分清「算力利用率 vs 显存利用率」。
- 怎么读:5.2 是全章钥匙、务必先看;5.3(MIG)和 5.6(qGPU)是面试高频;5.10 是动手实战。
5.1 为什么要切分 GPU
- 整卡给小任务 → 显存/算力大量闲置(利用率 20%–30%)。推理场景尤其典型:一个小模型权重才 8GB,却独占一张 80GB 的卡。
- 多个小任务抢一张卡 → 需要隔离(不能互相干扰:一个任务 OOM 不能拖垮另一个,一个任务吃满带宽不能把别人的延迟拉高)。
- 目标:单卡多实例、硬隔离、可计费、可调度。
五种做法(按实现层次从深到浅):
| # | 方案 | 实现层次 | 一句话 |
|---|---|---|---|
| 1 | MIG | 硬件 | 物理切卡,切完就是多张小卡 |
| 2 | vGPU | 驱动(Hypervisor 侧) | 给虚拟机用的中介直通 |
| 3 | qGPU | 内核 | 容器级算力%+显存GB 细粒度强隔离 |
| 4 | vCUDA / HAMi | 用户态库 | 拦截 CUDA 调用做软限制 |
| 5 | MPS / 时间片超卖 | 进程 | 无强隔离,纯提利用率 |
名词解释:隔离(Isolation) 指多个任务共用硬件时互不干扰。评价隔离强弱要看三个层面:
- 故障隔离:一个实例崩了(OOM、ECC 错误、驱动挂死),别的实例会不会被拖死;
- 性能隔离:邻居把算力/带宽/缓存吃满时,我的吞吐和延迟会不会被拖慢;
- 地址隔离:别的实例能不能摸到我的显存数据。
硬隔离通常是物理切分(MIG),软隔离靠软件调度/配额(时间片、限额)。
5.2 先建立总框架:空间切分 vs 时间复用
所有 GPU 共享方案,本质上只有两种基本操作:
空间切分(Spatial Partitioning)—— 一张卡切成几块,各用各的
┌────────┬────────┬────────┐
│ 实例 A │ 实例 B │ 实例 C │ 切的是「物理资源」:SM、缓存、显存
└────────┴────────┴────────┘
时间复用(Time-Slicing)—— 整卡轮流给不同进程用
┌────────────────────────────┐
│ A │ B │ A │ C │ A │ B │ ... │ 切的是「时间」:调度器决定谁何时上卡
└────────────────────────────┘
| 方案 | 算力怎么分 | 显存怎么分 |
|---|---|---|
| MIG | 空间切分(专属 SM) | 空间切分(专属显存+控制器) |
| vGPU | 时间复用(调度器轮转) | 空间划分(静态 framebuffer) |
| qGPU | 时间复用(时间片+优先级) | 空间划分(内核硬隔离) |
| MPS | 并发混跑(kernel 级) | 不切(只有软配额) |
⭐ 重点:现实方案几乎都是「显存按空间切(配额制,防 OOM 互杀)+ 算力按时间复用(调度制,保灵活性)」的组合拳。纯空间切分(MIG)隔离最强但粒度粗;纯时间复用(MPS)最灵活但没隔离。面试先把这张框架图讲出来,再展开任何一个方案,立刻显得有体系。
5.3 MIG 原理详解(硬件隔离,最稳)
MIG 到底切了什么
MIG = Multi-Instance GPU(多实例 GPU),Ampere(A100/A30)/Hopper(H100/H200)架构特性。它在硬件层面把一张物理 GPU 真正切成多个独立的小 GPU——切完之后,对操作系统和上层软件来说就是「好几张卡」,各自有独立的设备号和 UUID,nvidia-smi -L 里每个实例显示为独立的 MIG-<uuid> 设备。
切分发生在两个维度:
计算侧:按 GPC 切(7 个计算切片)
名词解释:
- GPC(Graphics Processing Cluster,图形处理簇):GPU 内部模块化的计算单元,一个 GPC 包含一组 SM(Streaming Multiprocessor,流多处理器,GPU 的执行单元) 及配套缓存。可以粗略理解为「GPU 这栋大楼里的一个楼层」。
- 切片(Slice):MIG 的最小切分单位。计算切片 ≈ 一个 GPC;显存切片见下。
A100 的计算资源被划成 7 个计算切片(对应 7 个可用的 GPC,die 上有冗余屏蔽)→ 这就是「A100 最多切 7 个实例」的由来。
显存侧:按显存切片切(8 个显存切片)
A100-40G 的 40GB 被划成 8 片 × 5GB;A100-80G 被划成 8 片 × 10GB。
因此每个 MIG 实例独享:
| 独享资源 | 带来的隔离 |
|---|---|
| 一组 SM(计算切片) | 算力隔离:邻居再忙也抢不走你的计算单元 |
| 专属 L2 缓存切片 | 缓存隔离:不会互相把对方的 cache 挤掉(避免「缓存抖动」) |
| 专属显存控制器/通道 | 带宽隔离:各有各的内存通路,性能可预测 |
| 独立 MMU(内存管理单元)+ 专属显存地址空间 | 地址隔离:实例之间互相看不到对方的数据 |
一张 A100-80G 物理卡(俯视示意)
计算侧:7 个计算切片(GPC) 显存侧:8 个显存切片
┌─────┐ ┌─────┐ ┌─────┐ ┌────┐ ┌────┐ ┌────┐
│GPC-0│ │GPC-1│ │GPC-2│ ⋯⋯ GPC-6 │10GB│ │10GB│ ⋯⋯ │10GB│
│ SMs │ │ SMs │ │ SMs │ │切片 │ │切片 │ │切片 │
└─────┘ └─────┘ └─────┘ └────┘ └────┘ └────┘
每个切片还配套:专属 L2 缓存切片 + 专属显存控制器 + 独立 MMU
切成 MIG 实例后(例:1×3g.40gb + 4×1g.10gb)
┌──────────────────────┬───────┬───────┬───────┬───────┐
│ 实例 1:3g.40gb │ 实例 2 │ 实例 3 │ 实例 4 │ 实例 5 │
│ 3 个计算切片 │ 1 切片 │ 1 切片 │ 1 切片 │ 1 切片 │
│ 4×10GB 显存 │ +10GB │ +10GB │ +10GB │ +10GB │
└──────────────────────┴───────┴───────┴───────┴───────┘
计算切片用满 3+1+1+1+1 = 7 个;显存切片用满 4+1+1+1+1 = 8 个
对 OS / 容器 / CUDA 应用来说 = 5 张互相独立的「小 GPU」
💡 类比:MIG 像「把一栋楼物理隔成几套独立公寓,各有独门独户的水电表」;vGPU/qGPU 像「一套公寓里合租,按配额分房间」;MPS 像「睡上下铺,全屋共用水电」。
⭐ 纠错回顾(来自转岗指南,这里把事实彻底理清):元宝曾说「A100 有 8 层显存 7 层计算单元每层 5GB」被批「错」。准确的说法是:A100 有 7 个计算切片(GPC) 和 8 个显存切片(40G 卡每片 5GB、80G 卡每片 10GB)。实例数受计算切片限制,所以最多 7 个实例;显存切片比计算切片多 1 个,所以整卡 profile(
7g.40gb/7g.79gb)能拿满全部 8 片显存。「每层 5GB」只对 A100-40G 成立。把 7/8、5GB/10GB、切片与实例的对应关系讲清,比背「最多切 7 个」高一个层次。
故障隔离:为什么说 MIG「最稳」
硬件切分带来的招牌能力是故障隔离:
- 某个实例内发生 ECC 显存错误、SM 故障、非法访存,错误被封锁在该实例内——其他实例继续跑;恢复时也只需处理故障实例,整卡其他实例不用动。
- 显存绝对隔离:实例 A 的任务疯狂申请显存直到 OOM,实例 B 毫发无损(地址空间不相交)。
- 算力、缓存、带宽全专属 → 性能可预测(QoS 有硬保障)。「我在实例里跑 benchmark,隔壁实例跑什么都改变不了我的数字」——这是 MIG 区别于一切软件方案的核心卖点。
GI 与 CI:MIG 的两级结构
MIG 内部是两级对象:
物理 GPU
└── GI(GPU Instance,GPU 实例) ← 物理隔离 / 故障隔离的边界
├── 专属计算切片 + 专属显存切片
└── CI(Compute Instance,计算实例)×N ← GI 内再分算力,共享 GI 显存
└── 进程
- GI = 「算力 + 显存」的物理划分,上面说的所有隔离都发生在 GI 级别。
- CI = 把一个 GI 的计算切片再分给多个进程,共享该 GI 的显存。典型用法:同一个团队内部几个进程各分一点算力、共用一份显存(一个训练 + 一个数据预处理)。
⭐ 重点:CI 之间共享显存,隔离弱于 GI——跨租户用 GI,同租户内多进程用 CI。
MIG 的限制(面试高频)
- 只支持计算负载:MIG 实例上不能跑图形 API(OpenGL/显示输出),纯 compute。
- 实例间不能通信:不支持实例间 CUDA IPC、统一内存(Unified Memory)、NVLink P2P——对依赖卡间高速互联的分布式训练是减分项。
- 一个驱动:所有实例由同一驱动管理,驱动升级/故障影响全部实例。
- 共享 PCIe:各实例共享该卡的 PCIe 带宽,数据搬运仍可能互相影响。
- 粒度固定:算力只能按 1/7 的倍数切,显存只能按切片切,不能任意比例——这是硬件切分的代价,也正是 qGPU 存在的理由。
- 切分变更有代价:修改切分方案需要清空该卡任务并重置,生产上必须用声明式工具管理(见 5.10 的 MIG Manager)。
- 硬件门槛:消费级 RTX 卡不支持 MIG,只有企业级 A100/A30/H100/H200 等才有——这是训练卡和游戏卡在「共享」上的本质区别。
5.4 MIG Profiles 与管理实操
profile(切分方案)命名形如 Ng.Mgb:N = 计算切片数(1–7),Mgb = 显存大小。
A100-80G 常用 profile(完整列表以 nvidia-smi mig -lgip 输出为准):
| Profile | 计算切片 | 显存 | 一张卡能同时放几个 |
|---|---|---|---|
1g.10gb |
1/7 | 10 GB | 最多 7 个 |
1g.20gb |
1/7 | 20 GB | 最多 4 个(受显存切片数限制) |
2g.20gb |
2/7 | 20 GB | 最多 3 个 |
3g.40gb |
3/7 | 40 GB | 最多 2 个 |
4g.40gb |
4/7 | 40 GB | 最多 1 个 |
7g.79gb |
7/7(整卡) | 79 GB | 1 个(约 1GB 用于实例管理开销) |
常用组合(满足「计算切片 ≤7、显存切片 ≤8」即可):7×1g.10gb、2×3g.40gb + 1×1g.10gb、1×3g.40gb + 4×1g.10gb、2×2g.20gb + 3×1g.10gb。
其他卡型:
- A100-40G:
1g.5gb / 1g.10gb / 2g.10gb / 3g.20gb / 4g.20gb / 7g.40gb(显存切片 5GB)。 - A30:最多 4 实例(
1g.6gb / 2g.12gb / 4g.24gb)。 - H100/H200:同样最多 7 实例,命名规则一致。
管理命令(节点级操作):
# 1) 开启 MIG 模式(需 root,卡上需无任务)
sudo nvidia-smi -mig 1
# 2) 查看本卡支持哪些 profile(输出里含 profile ID)
nvidia-smi mig -lgip
# 3) 创建实例:-cgi 指定 profile ID,-C 同时创建默认 Compute Instance
sudo nvidia-smi mig -cgi 19,19 -C # 建两个 1g.10gb(19 是该卡 1g.10gb 的 ID,以 -lgip 输出为准)
# 4) 查看
nvidia-smi mig -lgi # 已创建的 GI
nvidia-smi mig -lci # 已创建的 CI
nvidia-smi -L # 所有设备,MIG 实例形如 MIG-e4a2c6b3-...
# 5) 删除(先删 CI 再删 GI)
sudo nvidia-smi mig -dci
sudo nvidia-smi mig -dgi
CUDA 应用选择实例:环境变量 CUDA_VISIBLE_DEVICES=<MIG 实例 UUID 或序号>。监控按实例独立采集(DCGM 支持按 MIG 实例出指标,见 11)。
在 K8s 中,GPU Operator 的 MIG Manager 会自动把这些实例注册为资源,如 nvidia.com/mig-1g.10gb: 2,Pod 直接申请即可(见 5.10 实战)。
5.5 vGPU 详解(驱动级虚拟化,面向虚拟机)
vGPU 是什么:NVIDIA 的商业 GPU 虚拟化软件(前身叫 GRID),让一台虚拟机通过「中介直通」共享一张物理 GPU。它解决的是虚拟化场景(云桌面、云工作站、GPU 池化售卖)的 GPU 共享问题——面向 VM,不是面向容器,这是它和 qGPU 在定位上的根本区别。
名词解释:Mediated Passthrough(中介直通):介于「软件模拟显卡」(慢)和「完整直通」(一卡只能给一个 VM)之间的路线——hypervisor 拦截 VM 对 GPU 关键资源的访问,由中间层仲裁后再转发给物理卡。既能让多个 VM 分一张卡,性能又接近原生。
架构与实现原理
物理服务器(宿主机)
┌──────────────────────────────────────────────────┐
│ Hypervisor(VMware vSphere / RHEL KVM / Citrix…) │
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ 物理 GPU(如 A100-80GB) │ │
│ │ ▲ 所有访问被「中介」 │ │
│ │ │ │ │
│ │ vGPU Manager(宿主机驱动里的内核模块: │ │
│ │ 显存划分 + 时间片调度 + 访问仲裁) │ │
│ └────┼──────────────────────┬────────────────┘ │
│ │ 显存静态划分 │ 算力时间片轮转 │
│ ┌────▼─────┐ ┌─────▼────┐ │
│ │ VM 1 │ │ VM 2 │ │
│ │ ┌──────┐ │ │ ┌──────┐ │ │
│ │ │vGPU │ │ │ │vGPU │ │ │
│ │ │40GB │ │ │ │40GB │ │ │
│ │ │Guest │ │ │ │Guest │ │ │
│ │ │驱动 │ │ │ │驱动 │ │ │
│ │ └──────┘ │ │ └──────┘ │ │
│ │ CUDA/CAD │ │ 云桌面 │ │
│ └──────────┘ └──────────┘ │
│ 每个 VM 内看到的 = 一张 40GB 显存的「完整显卡」 │
└──────────────────────────────────────────────────┘
工作方式拆开看:
- 显存:静态划分(空间切分)。创建 vGPU 时按 profile 把物理显存划出一块专属 framebuffer 给它——分了不用也占着。
- 算力:时间片轮转(时间复用)。多个 vGPU 排队轮流使用物理卡的执行引擎,由宿主机侧的 vGPU 调度器决定。
- Guest 驱动:VM 里装的 NVIDIA 驱动把 vGPU 当一张真卡用,应用零改造。
Profile 体系与调度策略
- Profile 命名:
<GPU 型号>-<显存><类型字母>,如T4-8B= T4 切出的、每个 8GB 显存的 B 系列 vGPU。类型字母:- A = vApps(应用虚拟化/流送)
- B = vPC(办公云桌面)
- Q = vWS(专业工作站,CAD 认证)
- C = vCS/AI(计算与 AI 负载)
- A100/H100 的 vGPU profile 自带算力档位(如
A100-7-40C= 7/7 计算切片 + 40GB)——因为它们就是 MIG-backed vGPU:用 MIG 实例做 vGPU 的后端,组合出「虚拟机 + 硬隔离」。 - 调度策略(宿主机上配置,又见「时间复用」思路):
- Best Effort(默认):先到先得,空闲算力谁抢到算谁的,可能「饿死」低优先级 VM;
- Equal Share:各 vGPU 均分时间片;
- Fixed Share:给每个 vGPU 固定配额。
- License:vGPU 是订阅制商业软件,按「启用了 vGPU 的物理 GPU 数量」计费,需部署 License Server(DLS/CLS);没有 license,vGPU 无法正常工作。这是 vGPU 最大的落地门槛。
优缺点与适用场景
| 优点 | 缺点 |
|---|---|
| 显存专属(静态划分),不担心互抢 | License 贵、按卡订阅 |
| VM 内是「完整显卡」,应用零改造 | 显存静态分配,分了不用也浪费 |
| 生态成熟(vSphere/KVM/Citrix/AHV) | 时间片轮转有性能损耗,性能隔离弱于 MIG |
| 可与 MIG 组合(MIG-backed vGPU)获得硬隔离 | 面向 VM,容器场景不顺手 |
典型场景:VDI 云桌面、云工作站(CAD/设计)、云游戏、GPU 池化售卖。AI Infra 视角下,vGPU 更多出现在「云厂商把 GPU 切给虚机客户」的售卖模型里,而不是 K8s 训练集群内部。
💡 和 K8s 的关系:常见形态是「VM 里跑 K8s,vGPU 给 Pod」(两层虚拟化),或用 GPU Operator 在启用了 vGPU 的 VM 内管理 GPU。你做平台时更可能拿它评估「GPU 池化/售卖」,而不是做训练集群的共享。
5.6 qGPU 详解(内核级虚拟化,面向容器)
MIG 粒度粗(最小 1/7 卡)且只支持企业卡;而推理场景大量用 T4/A10 这类卡,小模型往往只要「10% 算力 + 4GB 显存」。腾讯 qGPU 就是为这种场景设计的:把卡按「算力百分比 + 显存 GB」细粒度切给多个容器,内核级强隔离。
定位与底层原理
qGPU 是腾讯云 TKE 针对原生节点的 GPU 容器虚拟化产品,依托腾讯开源的 Elastic GPU 框架(github.com/elastic-ai/elastic-gpu):
- 显存:内核态硬隔离(空间切分)。每个容器只能看到并使用配额内的显存——一个容器把配额用爆 OOM,别的容器无感。这是 qGPU 相对用户态方案(vCUDA/HAMi 的库拦截)的核心优势:在内核层做地址隔离,难绕过、开销低。
- 算力:时间片 + 优先级(时间复用)。内核层控制每个容器获得的 SM 执行时间比例,实现算力配额。
- 业务无感:不重编译、不替换 CUDA 库、不换镜像,标准 NVIDIA Docker 直接用。
- 硬件覆盖广:支持 Volta/Turing/Ampere(V100、T4、A100、A10 等),不挑企业卡。
- 在离线混部:在精细切分的基础上支持在线推理 + 离线任务共享 GPU(呼应
08的混部话题)。
TKE 节点(数据平面)
┌─────────────────────────────────────────────────────┐
│ Pod A Pod B Pod C │
│ core=30% core=50% core=20% │
│ mem=8GB mem=12GB mem=8GB │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ 容器内:标准 /dev/nvidia* 设备 + 被 qGPU 内核模块约束的配额 │
│ ┌───────────────────────────────────────────────────┐│
│ │ qGPU 内核模块(由 qgpu-manager DaemonSet 负责安装) ││
│ │ ├─ 显存硬隔离(地址空间隔离,防 OOM 互杀) ││
│ │ └─ 算力隔离(时间片 + 优先级调度) ││
│ └─────────────────────┬─────────────────────────────┘│
│ ▼ │
│ 物理 GPU(T4 / A10 / V100 / A100…) │
└─────────────────────────────────────────────────────┘
控制平面(Master)
kube-scheduler ──(Scheduler Extender / Framework 插件两种接口)──▶ qGPU Scheduler
├─ 节点层调度:选节点(binpack / spread)
└─ 卡层调度:选卡(binpack / spread)
device plugin:启动时自动发现并上报每张卡的 qgpu-core / qgpu-memory 资源
资源模型与两层调度(实现的关键)
- 资源模型:每张卡算力切成 100 份(
qgpu-core单位 = 整卡算力的 1%),显存按 GB(整数) 分配(qgpu-memory)。 - qGPU Scheduler 同时实现了 Scheduler Extender 和 Scheduler Framework 两种接口接入 kube-scheduler(见
06/08):- 预选(Filter):遍历节点,找到有剩余配额的卡;
- 优选(Score):按「显存分配率 × 0.8 + 算力分配率 × 0.2」加权打分——显存是绝对隔离、切了就占住,所以权重高;算力可共享、弹性大,权重低。
- 两层调度:节点层 + GPU 卡层,各自可配 binpack(装箱优先,碎片少)或 spread(打散优先,故障域隔离),组合出四种策略应对不同业务。
- Pod 示例(真实资源名):
apiVersion: v1
kind: Pod
metadata:
name: qgpu-demo
spec:
containers:
- name: test
image: nvidia/cuda:11.0-base
resources:
limits:
tke.cloud.tencent.com/qgpu-core: 30 # 30% 算力
tke.cloud.tencent.com/qgpu-memory: "8" # 8GB 显存
- 整卡与多卡:
qgpu-core填 100 的倍数且不填 memory = 整卡独占(显存自动拿满);填超过 100(如 160)自动触发多卡互联——均分到多张物理卡上(160 → 2 张卡各 80%)。
⭐ 重点(面试高频):一句话讲清 qGPU——「显存内核态硬隔离(空间切分,防 OOM 互杀)+ 算力时间片/优先级隔离(时间复用,保灵活)+ 算力/显存双维度扩展资源 + 节点/卡两层调度(各自 binpack/spread)」。再补一句「调度打分显存权重 0.8 > 算力 0.2,因为显存切了就占住」就是加分项。
💡 技术演进:腾讯早期开源的 GPU Manager(vCUDA,资源名
tencent.com/vcuda-core / vcuda-memory)是用户态方案——拦截 CUDA 库调用做限制,易被绕过、隔离不精确;qGPU 把这套逻辑下沉到内核态,隔离强度和可靠性都是量级提升。社区同类方案 HAMi(原 k8s-vgpu-scheduler)走库注入路线,国内用得很多。国产卡如昇腾也提供芯片级 vNPU 切分——思路殊途同归:显存配额 + 算力调度。
5.7 MPS 与时间片超卖(最轻量的共享)
MPS 原理
MPS(Multi-Process Service) 是 NVIDIA 自带的进程级共享服务。没有 MPS 时,多个进程共用一张卡,GPU 只能整体做上下文切换(一个进程的 context 换下来、另一个换上去),切换开销大,且任意时刻只有一个进程的 kernel 在跑。MPS 在中间加了一层「代理」:
进程 A 进程 B 进程 C
│ CUDA 调用 │ │
▼ ▼ ▼
MPS Client MPS Client MPS Client ← 各自独立地址空间(Volta+)
└────────────────┴───────┬────────┘
▼
MPS Server(root 权限后台进程,
汇聚所有 client 的 kernel 提交,
合并到共享的 GPU 上下文)
│
▼
物理 GPU
多个进程的 kernel 并发执行,省去上下文切换开销
- 收益:并发执行 + 低切换开销,小 kernel 密集的推理/开发场景利用率明显提升。
- Volta 之后的 MPS:每个 client 有独立地址空间(可靠性比老架构好);支持按 client 限制算力(
CUDA_MPS_ACTIVE_THREAD_PERCENTAGE)和显存上限(CUDA_MPS_PINNED_DEVICE_MEM_LIMIT)。 - 但本质仍是软隔离:没有带宽/缓存隔离(性能会被邻居拖慢),一个 client 严重崩溃可能要重启 MPS 服务。不适合多租户生产。
时间片超卖(device-plugin replicas)
NVIDIA k8s-device-plugin 还有个更朴素的玩法:把 nvidia.com/gpu 资源复制 N 份(replicas: N)超卖给 N 个 Pod——内核对多个进程做时间片轮转。完全无隔离(显存不隔离,先到先得),只适合开发测试。
⭐ 重点:MPS 和时间片超卖解决「利用率」,不解决「隔离」。多租户生产用 MIG/qGPU/vGPU;同团队内部提利用率用 MPS。
5.8 四种方案对比总结
| 维度 | MIG | vGPU | qGPU | MPS |
|---|---|---|---|---|
| 实现层级 | 硬件 | 驱动(Hypervisor 侧) | 内核 | 用户态进程 |
| 算力分配 | 空间切分(专属 SM) | 时间片轮转 | 时间片+优先级 | kernel 并发混跑 |
| 显存分配 | 专属(物理隔离) | 静态划分(framebuffer) | 内核硬隔离 | 不隔离(软配额) |
| 故障隔离 | ✅ 最强(错误封锁在实例内) | ⭕ 驱动级,一般 | ✅ 显存强 / 算力中 | ❌ 弱(可能连带重启) |
| 性能隔离 | ✅ 缓存/带宽专属,QoS 可预测 | ⭕ 时间片,受邻居影响 | ⭕ 算力软隔离 | ❌ 无 |
| 最小粒度 | 1/7 卡 + 1 个显存切片 | profile 档位 | 1% 算力 + 1GB 显存 | 无限制 |
| 硬件要求 | A100/A30/H100/H200 | NVIDIA 卡(企业为主) | V100/T4/A100/A10 等 | 通用 N 卡 |
| 成本 | 随卡(无额外软件费) | License 订阅(贵) | TKE 组件 / 开源框架 | 免费 |
| 面向对象 | 容器 / 裸机 | 虚拟机 | 容器 | 进程 |
| 典型场景 | 稳定隔离的训练/推理 | VDI / 云工作站 / GPU 售卖 | 高密度推理共享、混部 | 同团队开发/批处理 |
选型原则:要最强隔离、跑训练 → MIG;要高密度、跑推理、提利用率 → qGPU/细粒度虚拟化;虚拟机/云桌面场景 → vGPU;开发测试容忍共享 → MPS。
国产卡虚拟化(异构集群必懂)
- 华为昇腾:vNPU 芯片级切分,思路类似 MIG——把一颗 Ascend 切成若干虚拟实例,CANN 软件栈层面支持。
- 其他国产卡:各家自研方案,原理大同小异(硬件/驱动级切分),但成熟度和易用性参差不齐——这是国产卡在「共享/虚拟化」维度落后 NVIDIA 的点之一。
- AI Infra 现实:异构集群里,N 卡用 MIG、昇腾用 vNPU,调度器要能识别不同切分粒度的资源名(
nvidia.com/mig-1g.10gbvshuawei.com/ascend-vnpu-...),复杂度比纯 N 卡集群高一截。
5.9 多团队共享提利用率(AI Infra 价值落点)
场景:100 个团队共用一个 GPU 集群。
- 不加切分:整卡分配 → 小任务占整卡 → 利用率 30%。
- 加 MIG/qGPU:一张卡切多份分给多团队 → 利用率 70%+。
- 配合调度器(Volcano/qGPU 调度):按配额、优先级、亲和性分配。
⭐ 重点:你作为 AI Infra 工程师,「把卡的利用率从 30% 提到 70%」 这句话背后的技术,就是 MIG + qGPU + 调度器三件套。这也是面试最能讲出业务价值的点。
⚠️ 内幕:「利用率」要分清是计算利用率(GPU 在算)还是显存利用率。一张卡显存占满但算力空闲(跑很多小推理),算力利用率低但显存利用率高。qGPU 这种细粒度切分提的是「单卡塞更多任务」的密度,不一定提单个任务的算力利用率——面试讲清楚这点显得很专业。
利用率提升全景(从 30% 到 80%+ 的完整路径)
| 阶段 | 做法 | 利用率 |
|---|---|---|
| 整卡分配 | 一个任务占一整张卡 | ~30% |
| +MIG 切分 | 一张卡切 7 份,7 个小任务各用一份 | ~45% |
| +qGPU 细分 | 算力/显存任意比例分配,更高密度 | ~55% |
| +智能调度 | Volcano 配额+优先级+拓扑感知 | ~70% |
| +混部 | 在线/离线分时复用(见 08) |
~80% |
⭐ 完整闭环:利用率提升不是单点优化,是 MIG(硬件切分)+ qGPU(软件细分)+ 调度器(智能分配)+ 混部(分时复用) 的体系工程。面试讲「降本」时,这条链比单说「我用 MIG」值钱得多。
5.10 实战:在 K8s 用 MIG 实例
GPU Operator(ClusterPolicy: mig.strategy = mixed)
│ 部署并管理以下组件
▼
MIG Manager(DaemonSet)
│ 监听节点标签 nvidia.com/mig.config(如 all-1g.10gb、3g.40gb,4g.10gb)
▼ 声明式地在节点上执行 nvidia-smi mig 命令,把实际切分对齐到标签
device-plugin
│ 把每个 MIG 实例注册为扩展资源 nvidia.com/mig-1g.10gb: N
▼
kube-scheduler 按 Pod 请求调度 → 容器内 nvidia-smi 只看到分到的那张「小卡」
# 1) GPU Operator 开启 MIG(mixed 模式:同一节点允许不同 profile 共存)
kubectl edit clusterpolicy gpu-cluster-policy
# spec:
# mig:
# strategy: mixed
# 2) 给节点打「期望切分」标签,MIG Manager 自动执行(推荐,声明式)
kubectl label node gpu-node-1 nvidia.com/mig.config=all-1g.10gb
# 手动方式(应急/裸机):在节点上执行
# sudo nvidia-smi -mig 1 && sudo nvidia-smi mig -cgi 19 -C
# 3) 验证:节点资源里出现 MIG 小卡
kubectl describe node gpu-node-1 | grep nvidia.com/mig
# nvidia.com/mig-1g.10gb: 7
# 4) Pod 申请一个 MIG 小卡
apiVersion: v1
kind: Pod
metadata:
name: mig-test
spec:
containers:
- name: cuda
image: nvidia/cuda:12.4.0-base
command: ["nvidia-smi"] # 进容器看:只有一张 ~10GB 的小卡
resources:
limits:
nvidia.com/mig-1g.10gb: 1
名词解释:
mig.strategy: mixed指「节点上可同时存在不同 profile 的 MIG 实例」(mixed 混合模式);另一种single指所有实例同 profile。混合模式灵活但管理复杂,single 模式运维简单(节点标签一键全切)。nvidia.com/mig.config节点标签是 GPU Operator 的声明式玩法——把「切卡」这个危险操作变成 GitOps 可管理的配置,避免有人直接上节点手敲nvidia-smi mig把生产任务切没了。
5.11 自测题
- 为什么要切分 GPU?不切会有什么浪费?
- GPU 共享的两条基本技术路线是什么?MIG/vGPU/qGPU/MPS 分别怎么组合这两条路线?
- MIG 在硬件层面到底切了哪些东西?为什么 A100 最多切 7 个实例?
- A100-80G 有几个计算切片、几个显存切片、各多大?
7g.79gb为什么是 79GB 不是 80GB? - GI 和 CI 的区别是什么?跨租户用哪一级、同租户内多进程用哪一级?
- MIG 的故障隔离体现在哪?列出至少 3 条 MIG 的限制。
- vGPU 的 mediated passthrough 是什么?它的显存和算力分别怎么分配?三种调度策略是什么?
- qGPU 的显存和算力分别怎么隔离?资源模型是什么(两个扩展资源)?调度打分为什么显存权重 0.8、算力 0.2?
- qGPU 的两层调度分别是什么?各自支持什么策略?
- MPS 为什么能提利用率?为什么不适合多租户生产?
- 消费卡支持 MIG 吗?为什么?
- 「利用率从 30% 到 70%」靠哪三件套实现?
- ⭐ 「算力利用率」和「显存利用率」有何区别?qGPU 主要提升哪个?
- ⭐ 利用率从 30% 提到 80%+ 的完整路径是什么?(MIG→qGPU→调度→混部)
- 国产卡(昇腾)的虚拟化方案叫什么?异构集群的调度复杂在哪?
mig.strategy: mixed和single的区别是什么?
答上即可进入调度层
06——学「资源注册好了,怎么聪明地分配」。