GPU集群调度实践:Slurm/K8s下的GPU共享技术选型与优化

GPU集群平均利用率长期低于30%,而多租户共享可将利用率提升至70%以上,但隔离性、调度粒度与故障域差异巨大。 本文从Slurm与Kubernetes两大调度体系出发,深入MIG、MPS、Time-slicing等GPU共享技术的配置细节,给出可落地的选型判据与避坑指南。

1. 背景与痛点:GPU集群利用率与多租户隔离的挑战

传统HPC场景中,Slurm以节点独占或GPU独占方式分配资源,保障了作业的强隔离与确定性性能,但导致大量GPU空闲。

云原生场景下,Kubernetes凭借声明式API与弹性扩缩受到AI平台青睐,但多租户共享GPU时面临更复杂的安全与性能隔离问题。

NVIDIA官方统计:未实施共享的集群,GPU平均利用率仅15%~30%(NVIDIA数据中心白皮书,2023)。

核心痛点可归纳为三点:

  • 资源碎片:单卡强算力与多用户小模型需求不匹配,造成“够用但独占”浪费。
  • 隔离缺失:简单时分复用缺乏显存与故障隔离,导致“邻座噪声”甚至OOM扩散。
  • 调度异构:Slurm与K8s调度模型、设备插件机制、拓扑感知策略差异大,难以统一纳管。

为此,NVIDIA推出了MIG(多实例GPU)、MPS(多进程服务)以及K8s端的Time-slicing等共享方案,配合GPU Operator简化部署,形成两种典型技术路线。

2. Slurm环境下的GPU共享技术实践

Slurm原生支持GRES(通用资源)插件管理GPU,通过配置gres.confcgroup可实现GPU设备分配。但实现细粒度共享需借助NVIDIA MPS或MIG。

MPS(多进程服务) 允许不同进程的CUDA上下文共享GPU执行资源,适合小模型并发推理。

配置步骤示例(Slurm 23.02 + NVIDIA Driver 535 + CUDA 12.2):

# 在计算节点启用MPS控制守护进程
nvidia-cuda-mps-control -d
# 在slurm.conf中配置MPS为每个作业创建独立上下文
export CUDA_MPS_PIPE_DIRECTORY=/tmp/nvidia-mps

Slurm通过Prolog/Epilog脚本控制MPS生命周期,确保作业间上下文隔离。

MIG(多实例GPU) 在A100/A30等架构上提供硬件级隔离,将单卡划分为最多7个独立实例,各自拥有独立显存、缓存和计算单元。

在Slurm中,需将MIG实例作为独立GRES设备暴露:

# 在gres.conf中定义MIG实例
Name=gpu Type=a100 File=/dev/nvidia-caps/nvidia-cap1
# 在slurm.conf中配置节点GRES
NodeName=node[01-10] Gres=gpu:a100:4

作业提交时指定特定MIG实例大小:

# 请求1g.5gb的MIG实例
srun --gres=gpu:1g.5gb:1 --cpus-per-task=4 python train.py

下表对比MPS与MIG在Slurm下的关键特性:

特性MPSMIG
隔离级别进程级(软件)硬件级
显存隔离无,共享显存严格显存分区
性能干扰低负载时较小,高并发下可能竞争无干扰,QoS保证
支持GPU从Volta架构开始仅A100/A30/H100等
Slurm配置复杂度中等,需脚本控制较高,需GRES映射

实践表明,MPS适合推理服务(<4GB显存/任务),MIG适合训练与推理混合且要求故障隔离的场景。

3. Kubernetes环境下的GPU共享技术实践

Kubernetes通过Device Plugin框架暴露GPU资源,NVIDIA GPU Operator(v23.9+)简化了驱动、插件、MIG管理器的部署。

安装GPU Operator后,默认提供nvidia.com/gpu资源,使用整卡分配。若要启用共享,需配置Time-slicing或MIG策略。

Time-slicing(时分复用) 通过GPU Operator中的time-slicing-config ConfigMap设置,将单卡分为多个“副本”,供多个Pod分时使用。

# ConfigMap: time-slicing-config
apiVersion: v1
kind: ConfigMap
metadata:
  name: time-slicing-config
data:
  any: |-
    version: v1
    sharing:
      timeSlicing:
        resources:
          - name: nvidia.com/gpu
            replicas: 4

更新ClusterPolicy使配置生效,节点将报告nvidia.com/gpu资源数量为4倍,但每个Pod实际获得1/4时间片。

此方案无显存隔离,多Pod共享同一显存空间,需配合应用层限制(如CUDA_VISIBLE_DEVICES和PyTorch显存预分配)。

MIG模式 在K8s中更为优雅。GPU Operator可自动发现MIG布局并作为独立资源暴露,例如:

# 配置ClusterPolicy启用MIG
spec:
  migManager:
    enabled: true
  mig:
    strategy: mixed

之后,节点会报出nvidia.com/mig-1g.5gbnvidia.com/mig-2g.10gb等资源,Pod可显式请求:

resources:
  limits:
    nvidia.com/mig-1g.5gb: 1

两种方案在K8s下的对比:

维度Time-slicingMIG
资源粒度单卡虚拟为多个硬件实例
显存隔离
故障隔离
额外配置仅需ConfigMap需MIG开启和分区
适用场景弹性推理、批处理多租户训练、高隔离需求

K8s环境下,结合HPA与Cluster Autoscaler,Time-slicing可快速响应推理负载,而MIG适合固定多租户训练集群。

4. 对比分析与选型建议:Slurm vs K8s GPU共享

选择调度器与共享技术需综合考虑团队技能栈、工作负载类型与隔离要求。

下表从调度能力、生态集成、运维成本等维度进行对比:

维度SlurmKubernetes
调度粒度作业级,支持GPU细粒度分配Pod级,扩展性强
GPU共享支持MPS/MIG通过脚本和GRES集成GPU Operator原生支持Time-slicing/MIG
拓扑感知通过topology.conf配置NVLink亲和需要GPU Topology Scheduler插件
故障域作业失败影响范围小,但无自动重启Pod重启策略灵活,可集成监控
生态集成传统HPC、MPI应用云原生AI框架、Kubeflow、MLflow
运维成本较低,静态配置为主较高,需维护Operator、监控、CRD

选型建议

  • 纯HPC或大规模MPI训练,选择Slurm + MIG,利用硬件隔离保证性能可预测。
  • 云原生AI平台,推理与训练混合,且需要弹性扩缩,选择K8s + GPU Operator。初期可用Time-slicing快速提升利用率,逐步为关键训练任务引入MIG。
  • 混合集群可考虑Slurm + K8s分层调度,Slurm管理裸金属GPU训练,K8s管理推理与弹性负载。

避坑实践

  • MPS与MIG不能同时启用,需在启动前确认nvidia-smi中MIG模式状态。
  • K8s Time-slicing下,显存超分易导致Pod被OOMKilled,务必设置uidmemory限制,并监控DCGM指标。
  • Slurm使用MIG时,GRES配置需与MIG实例名称严格匹配,否则作业卡在PENDING状态。
  • 无论哪种方案,应用层都应结合CUDA_VISIBLE_DEVICES和框架显存分配策略,避免硬编码设备ID。

配置示例:限制PyTorch进程显存使用(配合MIG/Time-slicing):

import torch
torch.cuda.set_per_process_memory_fraction(0.5)  # 仅使用50%可见显存

通过组合这些技术,某AI平台将GPU利用率从25%提升至78%,且训练作业P99延迟无明显增加。


GPU共享并非简单的“一分为多”,需要根据隔离强度、调度灵活性及运维成本谨慎选择。Slurm与Kubernetes各有擅长,MIG与Time-slicing形成互补。
随着NVIDIA H100引入更细粒度的MIG实例和动态分区,以及K8s支持GPU弹性切片,未来GPU资源的池化与弹性分配将更加成熟。
本文技术细节基于NVIDIA官方文档、Slurm 23.02及Kubernetes 1.28社区实践,供读者参考。

更多推荐