HiHuo
首页
博客
手册
工具
关于
首页
博客
手册
工具
关于
  • AI 基础设施深度教程

    • AI Infra 深度教程
    • GPU容器化

      • 01-GPU 架构基础
      • NVIDIA 容器运行时
      • GPU 共享与隔离
      • GPU 监控与调试
    • Kubernetes GPU调度

      • Device Plugin 机制深度解析
      • GPU 调度器实现
      • 拓扑感知调度
      • 弹性 GPU 调度
    • AI训练平台

      • 分布式训练框架
      • 训练任务调度
      • 模型存储与管理
      • 实验管理
      • 超参数优化
    • 推理服务

      • 推理引擎原理
      • 模型服务框架
      • 动态批处理
      • 推理优化技术
      • 多模型服务
    • 异构计算

      • 05-异构计算
      • 异构计算概述
      • GPU 虚拟化技术
      • NPU 与专用 AI 芯片
      • 设备拓扑感知调度
      • 算力池化与弹性调度
    • AI工作流引擎

      • 06-AI工作流引擎
      • AI 工作流引擎概述
      • Kubeflow Pipelines 深度实践
      • 03-Argo Workflows 深度实践
      • 04-数据版本管理
      • 05-实验跟踪与模型注册
    • MLOps实践

      • 07-MLOps实践
      • 01-MLOps 成熟度模型
      • 02-数据集工程
      • 03-Feature Store 特征存储
      • 04-模型评测体系
      • 05-模型安全与治理
    • AIOps实践

      • 08-AIOps实践
      • 01-AIOps概述与架构
      • 02-异常检测算法
      • 03-根因分析与告警聚合
      • 04-智能运维决策
      • 05-AIOps平台实战
    • 面试专题

      • 09-面试专题
      • 01-AI基础设施核心面试题
      • 02-大模型面试题
      • 03-系统设计面试题
    • CUDA编程与算子开发

      • 10-CUDA 编程与算子开发
      • 01-CUDA编程模型与内存层次
      • 02-高性能 Kernel 开发实战
      • 03-Tensor Core 与矩阵运算
      • 04-算子融合与优化技术
      • 05-Triton 编程入门
    • 通信与网络底层

      • 11-通信与网络底层
      • 01-NCCL 源码深度解析
      • 02-AllReduce 算法实现
      • 03-RDMA与InfiniBand原理
      • 04-网络拓扑与通信优化
      • 05-大规模集群网络架构
    • 框架源码解析

      • 12-框架源码解析
      • 01-PyTorch分布式源码解析
      • 02-DeepSpeed源码深度解析
      • 03-Megatron-LM源码解析
      • 04-vLLM推理引擎源码解析
      • 05-HuggingFace Transformers源码解析
    • 编译优化与图优化

      • 13-编译优化与图优化
      • 01-深度学习编译器概述
      • 02-TorchDynamo与torch.compile
      • 03-XLA编译器深度解析
      • 04-算子融合与Kernel优化
      • 05-自动调度与代码生成

GPU 共享与隔离

深入理解 GPU 资源的多租户共享技术,从硬件分区到软件虚拟化

本章目标

  • 理解 GPU 共享的核心挑战
  • 掌握 MIG (Multi-Instance GPU) 原理与实践
  • 了解 vGPU 虚拟化技术
  • 学会各种 GPU 共享方案的选型

1. GPU 共享的挑战

1.1 为什么需要 GPU 共享

┌─────────────────────────────────────────────────────────────────────┐
│                    GPU 资源利用现状                                   │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  问题场景:                                                          │
│                                                                     │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │  推理服务 A                                                  │   │
│  │  ┌──────────────────────────────────────────────────────┐   │   │
│  │  │ GPU 0 (A100 80GB)                                    │   │   │
│  │  │ ████░░░░░░░░░░░░░░░░░░░░░░░░░░░░  使用率: 15%        │   │   │
│  │  │ 显存使用: 8GB / 80GB                                 │   │   │
│  │  └──────────────────────────────────────────────────────┘   │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │  推理服务 B                                                  │   │
│  │  ┌──────────────────────────────────────────────────────┐   │   │
│  │  │ GPU 1 (A100 80GB)                                    │   │   │
│  │  │ ██░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░  使用率: 8%         │   │   │
│  │  │ 显存使用: 4GB / 80GB                                 │   │   │
│  │  └──────────────────────────────────────────────────────┘   │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
│  问题:                                                              │
│  - 每个 GPU 价值数万美元,但利用率极低                                │
│  - 显存大量空闲                                                     │
│  - 计算单元未充分利用                                                │
│  - 无法将多个小任务合并到一个 GPU                                    │
│                                                                     │
│  期望:                                                              │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │ GPU 0 (A100 80GB) - 共享使用                                │   │
│  │ ████████████████████████░░░░░░░░  使用率: 80%              │   │
│  │ ┌────────────────┐ ┌────────────────┐ ┌──────────────┐    │   │
│  │ │ 服务 A (25GB)   │ │ 服务 B (20GB)  │ │ 服务 C (15GB)│    │   │
│  │ └────────────────┘ └────────────────┘ └──────────────┘    │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

1.2 GPU 共享的技术挑战

┌─────────────────────────────────────────────────────────────────────┐
│                    GPU 共享核心挑战                                   │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  1. 显存隔离                                                        │
│     ┌───────────────────────────────────────────────────────────┐  │
│     │ GPU 显存是全局共享的物理资源                                │  │
│     │ - 进程 A 可以访问进程 B 的显存吗? (安全问题)               │  │
│     │ - 进程 A 能用完所有显存吗? (公平问题)                      │  │
│     │ - 如何实现显存配额限制?                                   │  │
│     └───────────────────────────────────────────────────────────┘  │
│                                                                     │
│  2. 计算隔离                                                        │
│     ┌───────────────────────────────────────────────────────────┐  │
│     │ SM (Streaming Multiprocessor) 是计算单元                   │  │
│     │ - 如何分配 SM 给不同进程?                                  │  │
│     │ - 一个进程的密集计算会影响其他进程吗? (QoS 问题)           │  │
│     │ - 时间片轮转 vs 空间分区?                                  │  │
│     └───────────────────────────────────────────────────────────┘  │
│                                                                     │
│  3. 错误隔离                                                        │
│     ┌───────────────────────────────────────────────────────────┐  │
│     │ GPU 错误 (如 CUDA kernel 崩溃) 的影响范围                   │  │
│     │ - 一个进程崩溃会影响其他进程吗?                            │  │
│     │ - ECC 错误如何处理?                                       │  │
│     │ - 如何实现故障隔离?                                       │  │
│     └───────────────────────────────────────────────────────────┘  │
│                                                                     │
│  4. 性能干扰                                                        │
│     ┌───────────────────────────────────────────────────────────┐  │
│     │ 共享资源竞争导致的性能问题                                  │  │
│     │ - PCIe 带宽竞争                                            │  │
│     │ - 显存带宽竞争                                             │  │
│     │ - L2 Cache 竞争                                            │  │
│     │ - Tensor Core 调度冲突                                     │  │
│     └───────────────────────────────────────────────────────────┘  │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

1.3 GPU 共享技术分类

┌─────────────────────────────────────────────────────────────────────┐
│                    GPU 共享技术分类                                   │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │                     硬件级别                                 │   │
│  │  ┌────────────────────────────────────────────────────────┐ │   │
│  │  │ MIG (Multi-Instance GPU)                               │ │   │
│  │  │ - NVIDIA A100/H100 专有                                │ │   │
│  │  │ - 硬件分区,完全隔离                                    │ │   │
│  │  │ - 支持 1-7 个实例                                      │ │   │
│  │  └────────────────────────────────────────────────────────┘ │   │
│  │  ┌────────────────────────────────────────────────────────┐ │   │
│  │  │ SR-IOV (vGPU)                                          │ │   │
│  │  │ - 虚拟化层面的 GPU 分割                                 │ │   │
│  │  │ - 需要特殊驱动和许可证                                  │ │   │
│  │  │ - 主要用于 VDI 场景                                    │ │   │
│  │  └────────────────────────────────────────────────────────┘ │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │                     软件级别                                 │   │
│  │  ┌────────────────────────────────────────────────────────┐ │   │
│  │  │ MPS (Multi-Process Service)                            │ │   │
│  │  │ - NVIDIA 官方支持                                       │ │   │
│  │  │ - 时分复用 + 空间复用                                   │ │   │
│  │  │ - 适合多进程共享                                        │ │   │
│  │  └────────────────────────────────────────────────────────┘ │   │
│  │  ┌────────────────────────────────────────────────────────┐ │   │
│  │  │ 时分复用 (Time Slicing)                                 │ │   │
│  │  │ - 最简单的共享方式                                      │ │   │
│  │  │ - 轮流使用 GPU                                         │ │   │
│  │  │ - 无隔离保证                                           │ │   │
│  │  └────────────────────────────────────────────────────────┘ │   │
│  │  ┌────────────────────────────────────────────────────────┐ │   │
│  │  │ 显存虚拟化 (GPU 共享框架)                               │ │   │
│  │  │ - 阿里 cGPU / 腾讯 qGPU / NVIDIA vGPU                  │ │   │
│  │  │ - 软件层面限制显存使用                                  │ │   │
│  │  │ - 配合调度器实现                                        │ │   │
│  │  └────────────────────────────────────────────────────────┘ │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

2. MIG (Multi-Instance GPU) 深入解析

2.1 MIG 架构原理

┌─────────────────────────────────────────────────────────────────────┐
│                    MIG 硬件架构 (A100 示例)                          │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  完整 A100 GPU (108 SM, 80GB HBM2e)                                 │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │                                                             │   │
│  │  ┌─────────────────────────────────────────────────────┐   │   │
│  │  │ GPC 0    │ GPC 1    │ GPC 2    │ GPC 3    │ ...     │   │   │
│  │  │ (14 SM)  │ (14 SM)  │ (14 SM)  │ (14 SM)  │         │   │   │
│  │  └─────────────────────────────────────────────────────┘   │   │
│  │                                                             │   │
│  │  ┌─────────────────────────────────────────────────────┐   │   │
│  │  │                    L2 Cache (40 MB)                  │   │   │
│  │  │  被分成 8 个独立的 Memory Slice                       │   │   │
│  │  └─────────────────────────────────────────────────────┘   │   │
│  │                                                             │   │
│  │  ┌─────────────────────────────────────────────────────┐   │   │
│  │  │                    HBM2e (80GB)                      │   │   │
│  │  │  被分成 8 个独立的 Memory Partition (每个 10GB)       │   │   │
│  │  └─────────────────────────────────────────────────────┘   │   │
│  │                                                             │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
│  MIG 分区后 (示例: 3 个实例)                                         │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │                                                             │   │
│  │  ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐   │   │
│  │  │ MIG 3g.40gb │ │ MIG 2g.20gb │ │    MIG 2g.20gb      │   │   │
│  │  │             │ │             │ │                     │   │   │
│  │  │ 42 SM       │ │ 28 SM       │ │ 28 SM               │   │   │
│  │  │ 40GB 显存   │ │ 20GB 显存   │ │ 20GB 显存           │   │   │
│  │  │ 4 Mem Slice │ │ 2 Mem Slice │ │ 2 Mem Slice         │   │   │
│  │  │             │ │             │ │                     │   │   │
│  │  │ 完全隔离    │ │ 完全隔离    │ │ 完全隔离            │   │   │
│  │  └─────────────┘ └─────────────┘ └─────────────────────┘   │   │
│  │                                                             │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
│  MIG 隔离保证:                                                      │
│  ✓ 显存隔离: 每个实例有独立的显存分区                                │
│  ✓ 计算隔离: 每个实例有独立的 SM                                    │
│  ✓ 缓存隔离: 每个实例有独立的 L2 Cache 分区                         │
│  ✓ 带宽隔离: 每个实例有独立的显存带宽                                │
│  ✓ 错误隔离: 一个实例的错误不影响其他实例                            │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

2.2 MIG 配置规格

# A100 MIG Profile 配置 (完整)

# Profile 命名规则: <compute_slices>g.<memory_slices*5>gb
# compute_slices: GPU Instance 中的计算切片数 (1-7)
# memory_slices: 每个 memory slice = 5GB (A100 40GB) 或 10GB (A100 80GB)

# A100-80GB 可用的 MIG Profile:
┌────────────────┬──────────┬─────────────┬────────────┬───────────────┐
│ Profile        │ SM 数量  │ 显存 (GB)   │ 内存带宽    │ 最大实例数    │
├────────────────┼──────────┼─────────────┼────────────┼───────────────┤
│ 7g.80gb        │ 98       │ 80          │ 100%       │ 1             │
│ 4g.40gb        │ 56       │ 40          │ 50%        │ 1             │
│ 3g.40gb        │ 42       │ 40          │ 50%        │ 2             │
│ 2g.20gb        │ 28       │ 20          │ 25%        │ 3             │
│ 1g.10gb        │ 14       │ 10          │ 12.5%      │ 7             │
│ 1g.10gb+me     │ 14       │ 10 (扩展)   │ 12.5%      │ 1             │
│ 1g.20gb        │ 14       │ 20          │ 25%        │ 4             │
└────────────────┴──────────┴─────────────┴────────────┴───────────────┘

# H100 MIG Profile (H100-80GB):
┌────────────────┬──────────┬─────────────┬───────────────┐
│ Profile        │ SM 数量  │ 显存 (GB)   │ 最大实例数    │
├────────────────┼──────────┼─────────────┼───────────────┤
│ 7g.80gb        │ 132      │ 80          │ 1             │
│ 4g.40gb        │ 66       │ 40          │ 1             │
│ 3g.40gb        │ 60       │ 40          │ 2             │
│ 2g.20gb        │ 42       │ 20          │ 3             │
│ 1g.10gb        │ 22       │ 10          │ 7             │
└────────────────┴──────────┴─────────────┴───────────────┘

2.3 MIG 操作实战

# 1. 检查 GPU 是否支持 MIG
nvidia-smi -q | grep "MIG Mode"
# Current                           : Disabled
# Pending                           : Disabled

# 查看支持 MIG 的 GPU
nvidia-smi --query-gpu=name,mig.mode.current --format=csv
# name, mig.mode.current
# NVIDIA A100-SXM4-80GB, Disabled

# 2. 启用 MIG 模式
sudo nvidia-smi -i 0 -mig 1
# Warning: MIG mode change requires a GPU reset.

# 重置 GPU (需要停止所有使用 GPU 的进程)
sudo nvidia-smi -i 0 -r

# 验证 MIG 已启用
nvidia-smi -i 0 --query-gpu=mig.mode.current --format=csv
# mig.mode.current
# Enabled

# 3. 查看可用的 GPU Instance Profile
nvidia-smi mig -lgip
# +-----------------------------------------------------------------------------+
# | GPU instance profiles:                                                      |
# | GPU   Name             ID    Instances   Memory     P2P    SM    DEC   ENC  |
# |                              Free/Total   GiB              CE    JPEG  OFA  |
# |=============================================================================|
# |   0  MIG 1g.10gb        19     7/7        9.50       No     14     0     0  |
# |                                                             1     0     0  |
# |   0  MIG 1g.10gb+me     20     1/1        9.50       No     14     1     0  |
# |                                                             1     1     1  |
# |   0  MIG 2g.20gb        14     3/3        19.50      No     28     1     0  |
# |                                                             2     0     0  |
# |   0  MIG 3g.40gb         9     2/2        39.25      No     42     2     0  |
# |                                                             3     0     0  |
# |   0  MIG 4g.40gb         5     1/1        39.25      No     56     2     0  |
# |                                                             4     0     0  |
# |   0  MIG 7g.80gb         0     1/1        79.00      No     98     5     0  |
# |                                                             7     1     1  |
# +-----------------------------------------------------------------------------+

# 4. 创建 GPU Instance (GI)
# 创建 2 个 3g.40gb 实例
sudo nvidia-smi mig -cgi 9,9 -C

# 或者指定不同大小
# 创建 1 个 3g.40gb + 2 个 2g.20gb
sudo nvidia-smi mig -cgi 9 -C
sudo nvidia-smi mig -cgi 14,14 -C

# 5. 查看创建的实例
nvidia-smi mig -lgi
# +-------------------------------------------------------+
# | GPU instances:                                        |
# | GPU   Name             Profile  Instance   Placement  |
# |                          ID       ID       Start:Size |
# |=======================================================|
# |   0  MIG 3g.40gb          9        1          0:4     |
# |   0  MIG 2g.20gb         14        2          4:2     |
# |   0  MIG 2g.20gb         14        3          6:2     |
# +-------------------------------------------------------+

# 6. 在每个 GI 中创建 Compute Instance (CI)
nvidia-smi mig -lci
# 查看可用的 CI profile

# 创建 CI (一般使用默认配置)
sudo nvidia-smi mig -cci

# 7. 查看完整的 MIG 配置
nvidia-smi
# 会显示 MIG 设备,每个设备有独立的 UUID

# 8. 使用 MIG 实例 (通过 UUID)
# 获取 MIG UUID
nvidia-smi -L
# GPU 0: NVIDIA A100-SXM4-80GB (UUID: GPU-xxxxxx)
#   MIG 3g.40gb Device 0: (UUID: MIG-xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
#   MIG 2g.20gb Device 1: (UUID: MIG-xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
#   MIG 2g.20gb Device 2: (UUID: MIG-xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)

# 在容器中使用特定 MIG 实例
docker run --gpus '"device=MIG-xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"' \
    nvidia/cuda:12.0-base nvidia-smi

# 或使用索引 (MIG 设备按顺序编号)
docker run --gpus '"device=0:0"' nvidia/cuda:12.0-base nvidia-smi  # 第一个 MIG 设备
docker run --gpus '"device=0:1"' nvidia/cuda:12.0-base nvidia-smi  # 第二个 MIG 设备

# 9. 销毁 MIG 实例
# 先销毁 CI
sudo nvidia-smi mig -dci

# 再销毁 GI
sudo nvidia-smi mig -dgi

# 10. 禁用 MIG 模式
sudo nvidia-smi -i 0 -mig 0
sudo nvidia-smi -i 0 -r  # 重置 GPU

2.4 MIG 与 Kubernetes 集成

# NVIDIA Device Plugin 配置 MIG 策略
# /etc/nvidia-device-plugin/config.yaml

version: v1
sharing:
  mig:
    strategy: single  # single, mixed, none
    # single: 假设所有 GPU 都启用 MIG,暴露 MIG 设备
    # mixed: 支持 MIG 和非 MIG GPU 混合
    # none: 忽略 MIG 设备

---
# Pod 使用 MIG 设备
apiVersion: v1
kind: Pod
metadata:
  name: mig-pod
spec:
  containers:
  - name: cuda-container
    image: nvidia/cuda:12.0-base
    command: ["nvidia-smi"]
    resources:
      limits:
        # 请求特定的 MIG Profile
        nvidia.com/mig-3g.40gb: 1
        # 或
        # nvidia.com/mig-2g.20gb: 1
        # nvidia.com/mig-1g.10gb: 1
# MIG 配置管理器 (自动配置 MIG)
# nvidia-mig-manager

apiVersion: v1
kind: ConfigMap
metadata:
  name: mig-parted-config
  namespace: nvidia-device-plugin
data:
  config.yaml: |
    version: v1
    mig-configs:
      # 默认配置: 7 个 1g.10gb
      all-1g.10gb:
        - devices: all
          mig-enabled: true
          mig-devices:
            "1g.10gb": 7

      # 混合配置: 1 个 3g.40gb + 2 个 2g.20gb
      mixed:
        - devices: [0]
          mig-enabled: true
          mig-devices:
            "3g.40gb": 1
            "2g.20gb": 2

      # 大实例配置
      big-instance:
        - devices: all
          mig-enabled: true
          mig-devices:
            "7g.80gb": 1

2.5 MIG 性能特征

┌─────────────────────────────────────────────────────────────────────┐
│                    MIG 性能分析                                      │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  A100-80GB 不同 Profile 的性能对比 (以 1g.10gb 为基准)               │
│                                                                     │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │ Profile      │ SM   │ 显存带宽 │ FP16 算力   │ 相对性能      │  │
│  ├──────────────┼──────┼──────────┼─────────────┼───────────────┤  │
│  │ 7g.80gb      │ 98   │ 2039GB/s │ 312 TFLOPS  │ 7x            │  │
│  │ 4g.40gb      │ 56   │ 1020GB/s │ 179 TFLOPS  │ 4x            │  │
│  │ 3g.40gb      │ 42   │ 1020GB/s │ 134 TFLOPS  │ 3x            │  │
│  │ 2g.20gb      │ 28   │  510GB/s │  90 TFLOPS  │ 2x            │  │
│  │ 1g.10gb      │ 14   │  255GB/s │  45 TFLOPS  │ 1x (基准)     │  │
│  └──────────────┴──────┴──────────┴─────────────┴───────────────┘  │
│                                                                     │
│  性能隔离测试:                                                      │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │                                                              │  │
│  │  场景: 3 个 MIG 2g.20gb 实例同时运行 ResNet-50 推理          │  │
│  │                                                              │  │
│  │  实例 1    ████████████████████  1200 img/s                 │  │
│  │  实例 2    ████████████████████  1180 img/s                 │  │
│  │  实例 3    ████████████████████  1190 img/s                 │  │
│  │                                                              │  │
│  │  每个实例性能稳定,互不影响                                   │  │
│  │                                                              │  │
│  └──────────────────────────────────────────────────────────────┘  │
│                                                                     │
│  MIG vs 时分复用 对比:                                              │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │                                                              │  │
│  │  时分复用 (3 个进程共享一个 GPU):                             │  │
│  │  进程 1    ████░░░░████░░░░████░░░░  平均: 400 img/s        │  │
│  │  进程 2    ░░░░████░░░░████░░░░████  平均: 400 img/s        │  │
│  │  进程 3    ░░░░░░░░████░░░░████░░░░  平均: 400 img/s        │  │
│  │  (有明显的延迟抖动)                                          │  │
│  │                                                              │  │
│  │  MIG (3 个 2g.20gb 实例):                                    │  │
│  │  MIG 1     ████████████████████████  稳定: 1200 img/s       │  │
│  │  MIG 2     ████████████████████████  稳定: 1180 img/s       │  │
│  │  MIG 3     ████████████████████████  稳定: 1190 img/s       │  │
│  │  (无延迟抖动,性能隔离)                                       │  │
│  │                                                              │  │
│  └──────────────────────────────────────────────────────────────┘  │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

3. MPS (Multi-Process Service)

3.1 MPS 原理

┌─────────────────────────────────────────────────────────────────────┐
│                    MPS 架构原理                                      │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  没有 MPS 的情况 (默认):                                             │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │                                                              │  │
│  │  进程 A          进程 B          进程 C                      │  │
│  │    │               │               │                        │  │
│  │    ▼               ▼               ▼                        │  │
│  │  ┌─────┐         ┌─────┐         ┌─────┐                    │  │
│  │  │CUDA │         │CUDA │         │CUDA │    每个进程独立    │  │
│  │  │Context│       │Context│       │Context│   的 CUDA 上下文  │  │
│  │  └─────┘         └─────┘         └─────┘                    │  │
│  │    │               │               │                        │  │
│  │    └───────────────┼───────────────┘                        │  │
│  │                    ▼                                        │  │
│  │              ┌──────────┐                                   │  │
│  │              │   GPU    │  时分复用: A→B→C→A→B→C...         │  │
│  │              │          │  上下文切换开销大                  │  │
│  │              └──────────┘                                   │  │
│  │                                                              │  │
│  └──────────────────────────────────────────────────────────────┘  │
│                                                                     │
│  使用 MPS 的情况:                                                   │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │                                                              │  │
│  │  进程 A          进程 B          进程 C                      │  │
│  │    │               │               │                        │  │
│  │    └───────────────┼───────────────┘                        │  │
│  │                    ▼                                        │  │
│  │              ┌──────────────┐                               │  │
│  │              │ MPS Server   │                               │  │
│  │              │              │  共享 CUDA Context            │  │
│  │              │ ┌──────────┐ │  合并 kernel 调度              │  │
│  │              │ │  CUDA    │ │                               │  │
│  │              │ │ Context  │ │                               │  │
│  │              │ └──────────┘ │                               │  │
│  │              └──────┬───────┘                               │  │
│  │                     ▼                                        │  │
│  │              ┌──────────┐                                   │  │
│  │              │   GPU    │  空间复用: A+B+C 并行执行          │  │
│  │              │          │  无上下文切换开销                  │  │
│  │              └──────────┘                                   │  │
│  │                                                              │  │
│  └──────────────────────────────────────────────────────────────┘  │
│                                                                     │
│  MPS 优势:                                                          │
│  ✓ 减少上下文切换开销                                               │
│  ✓ 更好的 SM 利用率 (空间复用)                                      │
│  ✓ 支持 Hyper-Q (多硬件队列)                                        │
│                                                                     │
│  MPS 限制:                                                          │
│  ✗ 无显存隔离 (共享地址空间)                                        │
│  ✗ 无错误隔离 (一个进程崩溃影响所有)                                 │
│  ✗ 需要特殊配置                                                     │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

3.2 MPS 配置与使用

# 1. 启动 MPS Server
export CUDA_VISIBLE_DEVICES=0
export CUDA_MPS_PIPE_DIRECTORY=/tmp/nvidia-mps
export CUDA_MPS_LOG_DIRECTORY=/tmp/nvidia-mps-log

# 创建目录
mkdir -p $CUDA_MPS_PIPE_DIRECTORY
mkdir -p $CUDA_MPS_LOG_DIRECTORY

# 启动控制守护进程
nvidia-cuda-mps-control -d

# 验证 MPS 运行
echo "get_server_list" | nvidia-cuda-mps-control
# 输出: Server process ID: XXXXX

# 2. 在容器中使用 MPS
docker run --gpus all \
    -v /tmp/nvidia-mps:/tmp/nvidia-mps \
    -e CUDA_MPS_PIPE_DIRECTORY=/tmp/nvidia-mps \
    nvidia/cuda:12.0-base \
    python my_app.py

# 3. 设置每个客户端的资源限制
# 限制每个 MPS 客户端使用的 SM 百分比
echo "set_default_active_thread_percentage 50" | nvidia-cuda-mps-control
# 或者针对特定客户端
echo "set_active_thread_percentage <server_pid> 50" | nvidia-cuda-mps-control

# 限制每个 MPS 客户端的显存
# (需要 CUDA 11.4+)
echo "set_default_device_pinned_mem_limit 0 4G" | nvidia-cuda-mps-control
# 设置 GPU 0 每个客户端最多使用 4GB 显存

# 4. 查看 MPS 状态
nvidia-smi
# 会显示 MPS 相关进程

echo "get_server_list" | nvidia-cuda-mps-control
echo "ps -ef" | nvidia-cuda-mps-control

# 5. 关闭 MPS
echo "quit" | nvidia-cuda-mps-control

3.3 MPS 在 Kubernetes 中使用

# 部署 MPS Server 作为 DaemonSet
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nvidia-mps-server
  namespace: kube-system
spec:
  selector:
    matchLabels:
      name: nvidia-mps-server
  template:
    metadata:
      labels:
        name: nvidia-mps-server
    spec:
      nodeSelector:
        nvidia.com/gpu: "true"
      containers:
      - name: mps-server
        image: nvidia/cuda:12.0-base
        command:
        - nvidia-cuda-mps-control
        - "-d"
        securityContext:
          privileged: true
        env:
        - name: CUDA_MPS_PIPE_DIRECTORY
          value: /tmp/nvidia-mps
        - name: CUDA_MPS_LOG_DIRECTORY
          value: /tmp/nvidia-mps-log
        volumeMounts:
        - name: mps-pipe
          mountPath: /tmp/nvidia-mps
        - name: mps-log
          mountPath: /tmp/nvidia-mps-log
      volumes:
      - name: mps-pipe
        hostPath:
          path: /tmp/nvidia-mps
      - name: mps-log
        hostPath:
          path: /tmp/nvidia-mps-log

---
# 使用 MPS 的 Pod
apiVersion: v1
kind: Pod
metadata:
  name: mps-client
spec:
  containers:
  - name: cuda-app
    image: my-cuda-app
    env:
    - name: CUDA_MPS_PIPE_DIRECTORY
      value: /tmp/nvidia-mps
    volumeMounts:
    - name: mps-pipe
      mountPath: /tmp/nvidia-mps
    resources:
      limits:
        nvidia.com/gpu: 1  # 仍然需要声明 GPU
  volumes:
  - name: mps-pipe
    hostPath:
      path: /tmp/nvidia-mps

4. 时分复用 (Time Slicing)

4.1 时分复用原理

┌─────────────────────────────────────────────────────────────────────┐
│                    时分复用工作原理                                   │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  时间轴                                                             │
│  ─────────────────────────────────────────────────────────────►    │
│                                                                     │
│  ┌───────┬───────┬───────┬───────┬───────┬───────┬───────┐        │
│  │ Pod A │ Pod B │ Pod C │ Pod A │ Pod B │ Pod C │ Pod A │ ...    │
│  └───────┴───────┴───────┴───────┴───────┴───────┴───────┘        │
│  │<- 时间片 ->│                                                     │
│                                                                     │
│  特点:                                                              │
│  - 多个 Pod 轮流使用同一个 GPU                                       │
│  - 每个 Pod 在其时间片内独占 GPU                                     │
│  - 上下文切换开销较大                                                │
│  - 延迟不可预测 (需等待其他 Pod 完成时间片)                          │
│                                                                     │
│  适用场景:                                                          │
│  ✓ 开发测试环境                                                     │
│  ✓ 批处理任务 (不关心延迟)                                          │
│  ✓ 低 GPU 利用率的工作负载                                          │
│  ✗ 实时推理服务 (延迟敏感)                                          │
│  ✗ 需要 QoS 保证的场景                                              │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

4.2 Kubernetes 时分复用配置

# nvidia-device-plugin 配置时分复用
# /etc/nvidia-device-plugin/config.yaml

version: v1
sharing:
  timeSlicing:
    renameByDefault: false  # 是否重命名资源为 nvidia.com/gpu.shared
    failRequestsGreaterThanOne: false  # 是否允许请求多个共享 GPU
    resources:
    - name: nvidia.com/gpu
      replicas: 4  # 每个 GPU 可以被 4 个 Pod 共享

---
# 重新部署 device plugin
kubectl delete -f nvidia-device-plugin.yaml
kubectl apply -f nvidia-device-plugin.yaml

# 验证可用 GPU 数量增加
kubectl describe node | grep nvidia.com/gpu
# nvidia.com/gpu: 8  # 原来 2 个 GPU,现在变成 8 个 (2*4)
# Pod 使用共享 GPU
apiVersion: v1
kind: Pod
metadata:
  name: gpu-pod-1
spec:
  containers:
  - name: cuda-container
    image: nvidia/cuda:12.0-base
    command: ["nvidia-smi", "-l", "10"]
    resources:
      limits:
        nvidia.com/gpu: 1  # 请求 1 个共享 GPU 份额

---
# 同一节点上可以调度多个 Pod 使用同一 GPU
apiVersion: v1
kind: Pod
metadata:
  name: gpu-pod-2
spec:
  containers:
  - name: cuda-container
    image: nvidia/cuda:12.0-base
    resources:
      limits:
        nvidia.com/gpu: 1  # 与 gpu-pod-1 共享同一 GPU

5. vGPU 虚拟化

5.1 vGPU 架构

┌─────────────────────────────────────────────────────────────────────┐
│                    NVIDIA vGPU 架构                                  │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  虚拟机层                                                           │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │                                                             │   │
│  │  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐   │   │
│  │  │   VM 1   │  │   VM 2   │  │   VM 3   │  │   VM 4   │   │   │
│  │  │          │  │          │  │          │  │          │   │   │
│  │  │ vGPU 驱动 │  │ vGPU 驱动 │  │ vGPU 驱动 │  │ vGPU 驱动 │   │   │
│  │  └────┬─────┘  └────┬─────┘  └────┬─────┘  └────┬─────┘   │   │
│  │       └─────────────┼─────────────┼─────────────┘         │   │
│  │                     ▼                                     │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                        │                                            │
│  Hypervisor 层         │                                            │
│  ┌─────────────────────┼───────────────────────────────────────┐   │
│  │                     ▼                                       │   │
│  │  ┌─────────────────────────────────────────────────────┐   │   │
│  │  │              vGPU Manager                            │   │   │
│  │  │                                                      │   │   │
│  │  │  - 管理 vGPU 实例的创建和销毁                         │   │   │
│  │  │  - 调度 GPU 资源给各 VM                               │   │   │
│  │  │  - 强制执行 vGPU Profile 限制                         │   │   │
│  │  └─────────────────────────────────────────────────────┘   │   │
│  │                     │                                       │   │
│  │  ESXi / KVM / Xen  │                                       │   │
│  └─────────────────────┼───────────────────────────────────────┘   │
│                        ▼                                            │
│  物理层                                                            │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │                                                             │   │
│  │  ┌─────────────────────────────────────────────────────┐   │   │
│  │  │              NVIDIA GPU (支持 vGPU)                  │   │   │
│  │  │                                                      │   │   │
│  │  │  支持的 GPU:                                         │   │   │
│  │  │  - NVIDIA A100, A30, A16, A10, A2                   │   │   │
│  │  │  - NVIDIA RTX 6000, RTX 4000                        │   │   │
│  │  │  - Tesla V100, T4                                   │   │   │
│  │  └─────────────────────────────────────────────────────┘   │   │
│  │                                                             │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
│  vGPU 类型:                                                        │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │ vPC    : 虚拟 PC,用于 VDI                                  │   │
│  │ vCS    : 虚拟计算服务器,用于 AI/ML                          │   │
│  │ vWS    : 虚拟工作站,用于专业图形                            │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

5.2 vGPU Profile 示例

# A100-40GB vGPU Profile 示例
┌────────────────────┬───────────────┬───────────────┬───────────────┐
│ vGPU Profile       │ 显存 (GB)     │ 最大 vGPU 数  │ 使用场景      │
├────────────────────┼───────────────┼───────────────┼───────────────┤
│ A100-4C            │ 4             │ 10            │ 推理          │
│ A100-5C            │ 5             │ 8             │ 推理          │
│ A100-8C            │ 8             │ 5             │ 推理/小训练   │
│ A100-10C           │ 10            │ 4             │ 训练          │
│ A100-20C           │ 20            │ 2             │ 大模型训练    │
│ A100-40C           │ 40            │ 1             │ 完整 GPU      │
└────────────────────┴───────────────┴───────────────┴───────────────┘

# 查看可用 vGPU 类型 (在 ESXi 或 KVM 主机上)
# ESXi:
esxcli graphics vgpu list

# KVM (使用 mdev):
ls /sys/class/mdev_bus/*/mdev_supported_types/

5.3 vGPU vs MIG 对比

┌─────────────────────────────────────────────────────────────────────┐
│                    vGPU vs MIG 对比                                  │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ┌───────────────────┬────────────────────┬────────────────────┐   │
│  │ 特性              │ vGPU               │ MIG                │   │
│  ├───────────────────┼────────────────────┼────────────────────┤   │
│  │ 虚拟化层级        │ Hypervisor 层      │ 硬件层             │   │
│  ├───────────────────┼────────────────────┼────────────────────┤   │
│  │ 隔离级别          │ 时分复用           │ 硬件分区           │   │
│  │                   │ (软件隔离)         │ (完全隔离)         │   │
│  ├───────────────────┼────────────────────┼────────────────────┤   │
│  │ 性能隔离          │ 有干扰             │ 完全隔离           │   │
│  ├───────────────────┼────────────────────┼────────────────────┤   │
│  │ 错误隔离          │ 部分隔离           │ 完全隔离           │   │
│  ├───────────────────┼────────────────────┼────────────────────┤   │
│  │ 显存分配          │ 灵活配置           │ 固定 Profile       │   │
│  ├───────────────────┼────────────────────┼────────────────────┤   │
│  │ 许可证            │ 需要 (付费)        │ 不需要             │   │
│  ├───────────────────┼────────────────────┼────────────────────┤   │
│  │ 支持 GPU          │ 多种 GPU           │ A100/H100 等       │   │
│  ├───────────────────┼────────────────────┼────────────────────┤   │
│  │ 实例数上限        │ 最多 32 个         │ 最多 7 个          │   │
│  ├───────────────────┼────────────────────┼────────────────────┤   │
│  │ 使用场景          │ VDI、虚拟化环境    │ 容器、Kubernetes   │   │
│  └───────────────────┴────────────────────┴────────────────────┘   │
│                                                                     │
│  选型建议:                                                          │
│  - 需要完全隔离 + Kubernetes → MIG                                  │
│  - 已有虚拟化基础设施 → vGPU                                        │
│  - 需要更多实例数 → vGPU                                            │
│  - 成本敏感 → MIG (无许可证费用)                                    │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

6. GPU 共享框架

6.1 阿里云 cGPU

┌─────────────────────────────────────────────────────────────────────┐
│                    阿里云 cGPU 架构                                   │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  容器层                                                             │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │  ┌───────────────┐  ┌───────────────┐  ┌───────────────┐   │   │
│  │  │ Container A   │  │ Container B   │  │ Container C   │   │   │
│  │  │ 显存: 4GB     │  │ 显存: 8GB     │  │ 显存: 4GB     │   │   │
│  │  │ 算力: 25%     │  │ 算力: 50%     │  │ 算力: 25%     │   │   │
│  │  └───────┬───────┘  └───────┬───────┘  └───────┬───────┘   │   │
│  │          └──────────────────┼──────────────────┘           │   │
│  └─────────────────────────────┼───────────────────────────────┘   │
│                                ▼                                    │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │                    cGPU Runtime                             │   │
│  │                                                             │   │
│  │  ┌─────────────────────────────────────────────────────┐   │   │
│  │  │ 拦截层 (LD_PRELOAD / GPU API Hook)                  │   │   │
│  │  │                                                      │   │   │
│  │  │ - 拦截 CUDA Driver API 调用                          │   │   │
│  │  │ - 显存分配限制 (cuMemAlloc 等)                       │   │   │
│  │  │ - 算力配额管理                                       │   │   │
│  │  └─────────────────────────────────────────────────────┘   │   │
│  │                                                             │   │
│  │  ┌─────────────────────────────────────────────────────┐   │   │
│  │  │ 调度器                                               │   │   │
│  │  │                                                      │   │   │
│  │  │ - 跨容器调度 GPU 时间片                               │   │   │
│  │  │ - 算力 QoS 保证                                      │   │   │
│  │  │ - 显存超卖管理                                       │   │   │
│  │  └─────────────────────────────────────────────────────┘   │   │
│  │                                                             │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                │                                    │
│                                ▼                                    │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │                    NVIDIA GPU                               │   │
│  │                    (物理共享)                                │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
│  cGPU 特点:                                                        │
│  ✓ 支持显存隔离 (软件层面)                                          │
│  ✓ 支持算力隔离 (时分复用)                                          │
│  ✓ 兼容所有 NVIDIA GPU                                             │
│  ✓ 与 Kubernetes 深度集成                                          │
│  ✗ 非硬件隔离,有一定性能开销                                       │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

6.2 开源 GPU 共享方案

# HAMi (Heterogeneous AI Computing Virtualization Middleware)
# https://github.com/Project-HAMi/HAMi

# 部署 HAMi
kubectl apply -f https://raw.githubusercontent.com/Project-HAMi/HAMi/master/deployments/hami.yaml

# Pod 使用共享 GPU
apiVersion: v1
kind: Pod
metadata:
  name: hami-pod
spec:
  containers:
  - name: cuda-container
    image: nvidia/cuda:12.0-base
    resources:
      limits:
        nvidia.com/gpu: 1
        nvidia.com/gpumem: 4096  # 限制显存 4GB
        nvidia.com/gpucores: 50  # 限制算力 50%

---
# GPU Share Scheduler Extender (阿里开源)
# https://github.com/AliyunContainerService/gpushare-scheduler-extender

# 安装
kubectl apply -f https://raw.githubusercontent.com/AliyunContainerService/gpushare-scheduler-extender/master/deploy/gpushare-schd-extender.yaml

# Pod 使用
apiVersion: v1
kind: Pod
metadata:
  name: gpushare-pod
spec:
  schedulerName: gpushare-scheduler
  containers:
  - name: cuda-container
    image: nvidia/cuda:12.0-base
    resources:
      limits:
        aliyun.com/gpu-mem: 4  # 请求 4GB 显存

7. GPU 共享方案选型

7.1 方案对比

┌─────────────────────────────────────────────────────────────────────────────────┐
│                         GPU 共享方案对比                                         │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  ┌────────────┬──────────────┬──────────────┬──────────────┬──────────────┐    │
│  │            │ MIG          │ MPS          │ 时分复用     │ cGPU/HAMi    │    │
│  ├────────────┼──────────────┼──────────────┼──────────────┼──────────────┤    │
│  │ 隔离级别   │ 硬件完全隔离 │ 共享上下文   │ 时间片隔离   │ 软件隔离     │    │
│  ├────────────┼──────────────┼──────────────┼──────────────┼──────────────┤    │
│  │ 显存隔离   │ ✓ 完全隔离   │ ✗ 无隔离     │ ✗ 无隔离     │ ✓ 软件限制   │    │
│  ├────────────┼──────────────┼──────────────┼──────────────┼──────────────┤    │
│  │ 算力隔离   │ ✓ 固定分配   │ △ 有限       │ ✗ 轮流使用   │ △ 软件调度   │    │
│  ├────────────┼──────────────┼──────────────┼──────────────┼──────────────┤    │
│  │ 性能损耗   │ 几乎无       │ 低           │ 中等         │ 低-中        │    │
│  ├────────────┼──────────────┼──────────────┼──────────────┼──────────────┤    │
│  │ 延迟稳定性 │ ✓ 稳定       │ △ 一般       │ ✗ 抖动大     │ △ 一般       │    │
│  ├────────────┼──────────────┼──────────────┼──────────────┼──────────────┤    │
│  │ GPU 兼容性 │ A100/H100    │ 大多数 GPU   │ 所有 GPU     │ 所有 GPU     │    │
│  ├────────────┼──────────────┼──────────────┼──────────────┼──────────────┤    │
│  │ 复杂度     │ 中           │ 低           │ 低           │ 中-高        │    │
│  ├────────────┼──────────────┼──────────────┼──────────────┼──────────────┤    │
│  │ 成本       │ 无额外成本   │ 无额外成本   │ 无额外成本   │ 取决于实现   │    │
│  └────────────┴──────────────┴──────────────┴──────────────┴──────────────┘    │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

7.2 场景选型指南

┌─────────────────────────────────────────────────────────────────────┐
│                    GPU 共享场景选型                                   │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  1. 在线推理服务 (低延迟、高 QoS)                                    │
│     ┌─────────────────────────────────────────────────────────────┐│
│     │ 推荐: MIG                                                   ││
│     │ 原因:                                                       ││
│     │ - 硬件隔离保证延迟稳定性                                     ││
│     │ - 一个实例故障不影响其他服务                                  ││
│     │ - 显存和算力完全隔离                                         ││
│     │                                                             ││
│     │ 配置示例:                                                    ││
│     │ A100-80GB → 7 个 1g.10gb 实例,每个服务一个实例              ││
│     └─────────────────────────────────────────────────────────────┘│
│                                                                     │
│  2. 开发测试环境 (成本优先)                                          │
│     ┌─────────────────────────────────────────────────────────────┐│
│     │ 推荐: 时分复用 + HAMi                                        ││
│     │ 原因:                                                       ││
│     │ - 最大化 GPU 利用率                                          ││
│     │ - 开发测试对延迟不敏感                                        ││
│     │ - 配置简单                                                   ││
│     │                                                             ││
│     │ 配置示例:                                                    ││
│     │ 1 个 GPU 共享给 4-8 个开发者                                 ││
│     └─────────────────────────────────────────────────────────────┘│
│                                                                     │
│  3. 批处理训练任务                                                  │
│     ┌─────────────────────────────────────────────────────────────┐│
│     │ 推荐: 独占 GPU + 弹性调度                                    ││
│     │ 原因:                                                       ││
│     │ - 训练任务通常需要较多显存                                    ││
│     │ - 可以通过任务调度提高利用率                                  ││
│     │ - 显存共享可能导致 OOM                                       ││
│     │                                                             ││
│     │ 配置示例:                                                    ││
│     │ 使用 Kubernetes Job + 优先级调度                             ││
│     └─────────────────────────────────────────────────────────────┘│
│                                                                     │
│  4. 多模型推理 (显存密集)                                            │
│     ┌─────────────────────────────────────────────────────────────┐│
│     │ 推荐: MIG (大实例) 或 cGPU                                   ││
│     │ 原因:                                                       ││
│     │ - 多个模型需要可预测的显存                                    ││
│     │ - 需要显存配额管理                                           ││
│     │                                                             ││
│     │ 配置示例:                                                    ││
│     │ A100-80GB → 2 个 3g.40gb 实例                               ││
│     │ 或 cGPU 分配: 模型 A 20GB + 模型 B 20GB + 模型 C 20GB       ││
│     └─────────────────────────────────────────────────────────────┘│
│                                                                     │
│  5. VDI 虚拟桌面                                                    │
│     ┌─────────────────────────────────────────────────────────────┐│
│     │ 推荐: vGPU                                                   ││
│     │ 原因:                                                       ││
│     │ - 与虚拟化平台深度集成                                        ││
│     │ - 支持更多实例数                                             ││
│     │ - 成熟的图形工作站支持                                        ││
│     └─────────────────────────────────────────────────────────────┘│
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

7.3 生产环境最佳实践

# 综合使用多种共享策略
# 根据工作负载类型自动选择

# 1. Node 标签标识 GPU 类型和共享模式
kubectl label node node1 nvidia.com/gpu.sharing=mig
kubectl label node node2 nvidia.com/gpu.sharing=timeslice
kubectl label node node3 nvidia.com/gpu.sharing=none  # 独占

# 2. 使用 Node Affinity 调度
apiVersion: v1
kind: Pod
metadata:
  name: inference-pod
  labels:
    workload-type: inference
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: nvidia.com/gpu.sharing
            operator: In
            values:
            - mig  # 推理服务使用 MIG 节点
  containers:
  - name: inference
    image: my-inference-service
    resources:
      limits:
        nvidia.com/mig-2g.20gb: 1

---
apiVersion: v1
kind: Pod
metadata:
  name: dev-pod
  labels:
    workload-type: development
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: nvidia.com/gpu.sharing
            operator: In
            values:
            - timeslice  # 开发环境使用时分复用节点
  containers:
  - name: dev
    image: nvidia/cuda:12.0-devel
    resources:
      limits:
        nvidia.com/gpu: 1

---
# 3. 训练任务独占 GPU
apiVersion: batch/v1
kind: Job
metadata:
  name: training-job
spec:
  template:
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: nvidia.com/gpu.sharing
                operator: In
                values:
                - none  # 训练使用独占节点
      containers:
      - name: training
        image: my-training-job
        resources:
          limits:
            nvidia.com/gpu: 4  # 使用 4 个完整 GPU
      restartPolicy: Never

8. 本章总结

8.1 核心知识点

┌─────────────────────────────────────────────────────────────────────┐
│                    GPU 共享与隔离知识图谱                             │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  核心挑战                                                           │
│  ├── 显存隔离: 软件限制 vs 硬件分区                                  │
│  ├── 计算隔离: 时分复用 vs 空间分区                                  │
│  ├── 错误隔离: 共享上下文 vs 独立实例                                │
│  └── 性能干扰: 资源竞争、带宽争用                                    │
│                                                                     │
│  MIG (硬件级别)                                                     │
│  ├── 支持 GPU: A100, H100, A30                                     │
│  ├── Profile: 1g.10gb ~ 7g.80gb                                    │
│  ├── 隔离级别: 显存 + 计算 + 缓存 + 带宽                             │
│  ├── 操作命令: nvidia-smi mig -cgi/-dgi/-lgi                       │
│  └── K8s 集成: nvidia.com/mig-Xg.Xgb                               │
│                                                                     │
│  MPS (软件级别)                                                     │
│  ├── 原理: 共享 CUDA Context,合并 kernel 调度                      │
│  ├── 优势: 减少上下文切换,支持空间复用                               │
│  ├── 限制: 无显存隔离,无错误隔离                                    │
│  └── 使用: nvidia-cuda-mps-control                                 │
│                                                                     │
│  时分复用                                                           │
│  ├── 原理: 多进程轮流使用 GPU                                       │
│  ├── K8s: nvidia-device-plugin timeSlicing 配置                    │
│  ├── 适用: 开发测试、批处理                                         │
│  └── 限制: 延迟抖动、无隔离保证                                      │
│                                                                     │
│  选型原则                                                           │
│  ├── 推理服务 → MIG (延迟稳定)                                      │
│  ├── 开发测试 → 时分复用 (成本低)                                    │
│  ├── 批处理 → 独占 + 弹性调度                                       │
│  └── VDI → vGPU (虚拟化集成)                                        │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

8.2 面试要点

  1. MIG 和时分复用的区别是什么?

    • MIG: 硬件分区,完全隔离 (显存/计算/缓存/带宽)
    • 时分复用: 软件调度,轮流使用,无隔离保证
    • MIG 适合需要 QoS 保证的场景,时分复用适合开发测试
  2. 什么场景应该使用 MIG?

    • 在线推理服务 (需要低延迟、稳定性)
    • 多租户共享 (需要隔离)
    • 故障隔离要求高的场景
  3. MPS 的优缺点是什么?

    • 优点: 减少上下文切换开销,支持空间复用
    • 缺点: 无显存隔离,一个进程崩溃影响所有进程
  4. 如何在 Kubernetes 中实现 GPU 共享?

    • MIG: 配置 nvidia-device-plugin 的 mig strategy
    • 时分复用: 配置 timeSlicing replicas
    • 软件方案: HAMi、gpushare-scheduler-extender

8.3 下一章预告

下一章我们将深入探讨 GPU 监控与调试技术:

  • nvidia-smi 深入解析
  • DCGM (Data Center GPU Manager)
  • GPU 性能分析工具
  • 常见 GPU 问题排查

参考资料

  • NVIDIA MIG 用户指南
  • NVIDIA MPS 文档
  • NVIDIA vGPU 软件文档
  • Kubernetes GPU 共享调度
  • HAMi 项目
Prev
NVIDIA 容器运行时
Next
GPU 监控与调试