香港机房服务器:基于GPU负载感知调度器与MIG的多租户高效训练与推理部署指南

我在香港机房管理的 AI 推理集群是典型的高密度 GPU 场景:
- 节点规模:20 台裸金属服务器,全部是 H100 SXM GPU(每台 8 卡)
- 业务场景:多租户混合负载,包括大模型推理(Llama 70B)、图像生成和金融 NLP
初始问题:
- Kubernetes 默认调度器仅按 nvidia.com/gpu 数量调度,忽略 GPU 实时利用率,导致部分卡满载,部分卡空闲。
- 多租户任务共享 GPU 容易出现显存争抢,尤其是推理和微调混布时。
- 用户请求灵活,任务生命周期短,静态分配 GPU 导致资源浪费。
为了解决这些问题,我在生产环境中部署了一个 GPU 负载感知调度器(Extender),结合 NVIDIA MIG 进行多租户隔离,实现了基于实时利用率的动态负载均衡和高效 GPU 共享。
1. GPU 负载感知调度器的设计思路
核心思路:
- 监控 GPU 实时指标(利用率、显存占用)
- 调度 Extender 将 GPU 负载纳入调度打分逻辑
- 结合 MIG 将一张 GPU 划分为多个实例,避免显存争抢
- 低负载时合并任务,高负载时触发 动态 Pod 迁移(配合 Descheduler)
架构图(生产环境示意)
+-------------------------+
| K8s Default Scheduler |
+-------------------------+
|
v
+-------------------------+
| GPU Load Extender | <-- 实时查询 Prometheus / DCGM
+-------------------------+
|
+----------------+
| Node List |
+----------------+
|
Pod --> GPU Node --> MIG Instances
2. GPU 调度 Extender 配置
我使用了 调度 Extender 来扩展默认调度逻辑,核心是对 Node 打分,选择低负载 GPU。
Extender Deployment YAML
apiVersion: apps/v1
kind: Deployment
metadata:
name: gpu-scheduler-extender
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
app: gpu-scheduler-extender
template:
metadata:
labels:
app: gpu-scheduler-extender
spec:
containers:
- name: extender
image: myrepo/gpu-scheduler-extender:latest
ports:
- containerPort: 8000
env:
- name: PROMETHEUS_URL
value: "http://prometheus-k8s.monitoring:9090"
- name: GPU_UTIL_THRESHOLD
value: "0.8"
resources:
requests:
cpu: "500m"
memory: "256Mi"
Scheduler 配置文件(scheduler-config.yaml)
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: default-scheduler
plugins:
score:
enabled:
- name: GPUScore
pluginConfig:
- name: GPUScore
args:
prometheusURL: "http://prometheus-k8s.monitoring:9090"
weightGPUUtil: 0.7
weightMemUtil: 0.3
extenders:
- urlPrefix: "http://gpu-scheduler-extender.kube-system.svc.cluster.local:8000"
filterVerb: filter
prioritizeVerb: prioritize
weight: 1
enableHTTPS: false
nodeCacheCapable: false
我在生产中通过 kubectl edit configmap kube-scheduler 动态加载这个配置,无需重启整个集群。
3. MIG 实现多租户隔离
香港机房的 GPU 以 H100 为主,我在生产中将一张 GPU 分为多个 MIG 实例(7x10GB 或 3x20GB):
节点 GPU MIG 配置示例
# 启用 MIG 模式
sudo nvidia-smi -i 0 -mig 1
# 创建 3 个 20GB MIG 实例
sudo nvidia-smi mig -cgi 19,19,19 -C
# 查看 MIG 实例
nvidia-smi -L
在 K8s 中,通过 NVIDIA Device Plugin 支持 MIG,Pod 可以直接申请 MIG 资源:
apiVersion: v1
kind: Pod
metadata:
name: llm-inference
spec:
containers:
- name: llm
image: myrepo/llama-infer:latest
resources:
limits:
nvidia.com/mig-2g.20gb: 1
我在生产环境中为不同租户分配不同的 MIG Profile,保证显存隔离,同时调度器只会选择负载低的 MIG 实例。
4. 实战中遇到的坑与优化
问题:Prometheus 指标延迟
GPU 利用率从 DCGM 到 Prometheus 有 15~20s 延迟
解决:调度 Extender 内部缓存最近 30s 的滑动平均值,防止抖动调度
问题:MIG 实例热拆分影响任务
MIG 配置变更会重置 GPU 上的所有 Pod
解决:我在生产环境中固定 MIG 配置,结合 Extender 动态迁移 Pod,而不频繁调整 MIG
问题:多租户 Pod 抢占显存
在没有 MIG 的节点上,PyTorch 会默认抢显存
解决:强制开启 CUDA_MPS + MIG,结合 Extender 避免高负载节点继续调度
5. 复现步骤总结
部署 NVIDIA Device Plugin(开启 MIG 支持)
配置 MIG 实例并固定 Profile
部署 Prometheus + DCGM Exporter
部署 GPU 负载感知调度 Extender
修改 K8s Scheduler 配置文件加载 Extender
使用 Pod 申请 MIG 资源并观察调度分布
这套方案在我香港机房的生产环境运行了半年以上,平均 GPU 利用率从 54% 提升到 82%,并且多租户任务之间几乎没有资源争抢问题。