Планирование GPU K8s для ИИ на практике: разбиение MIG, совместное использование GPU и оркестрация мультитенантных рабочих нагрузок

云原生

Краткое содержание

  • GPU — ключевой ресурс для ИИ-нагрузок: средняя утилизация GPU в кластерах K8s составляет лишь 30–40 %; оптимизация планирования может поднять её выше 80 %
  • Разбиение MIG NVIDIA: одна A100 делится на 7 экземпляров, поддерживает параллельное выполнение разных ИИ-задач и повышает использование ресурсов в 3 раза
  • Три режима совместного использования GPU: Time Slicing (TS), MPS и MIG — подходят соответственно для вывода, обучения и смешанных сценариев
  • Стратегии мультитенантного планирования: управление квотами GPU, вытеснение по приоритету и эластичное масштабирование для соблюдения SLA
  • В статье представлено комплексное решение планирования GPU K8s, включая настройку Device Plugin и практику расширения планировщика

Содержание


Планирование GPU: ключевая проблема ИИ-кластеров

Текущее состояние растраты ресурсов GPU

Проблема Причина Доля растрат
Низкая утилизация при выводе Один запрос вывода использует лишь 10–20 % GPU 40–60 %
Фрагментация обучения Обучение малых моделей занимает целую карту 20–30 %
Простой в ожидании Задачи стоят в очереди на освобождение GPU 15–25 %
Неверная конфигурация Запросы ресурсов не соответствуют реальному использованию 10–15 %

Эволюция планирования GPU

Этап Период Подход Характеристики
Монопольный режим До 2020 1Pod=1GPU Просто, но расточительно
Time Slicing 2021 Совместное использование GPU по временным срезам Подходит для вывода
Разбиение MIG 2022 Аппаратное разбиение A100 Сильная изоляция
Совместное использование MPS 2023 Многопроцессное совместное использование GPU Подходит для обучения
Эластичное планирование 2024–2026 Динамический MIG + приоритет Интеллектуальное

Актуальные спецификации GPU в 2026

GPU Память Экземпляры MIG Подходящие сценарии Цена ($/ч)
A100 80GB 80GB 7×10GB или 2×40GB Общее обучение и вывод 3,5
H100 80GB 80GB 7×10GB или 2×40GB Обучение крупных моделей 4,5
H200 141GB 141GB 7×20GB или 2×70GB Сверхкрупные модели 6,0
L40S 48GB 48GB MIG не поддерживается Вывод / дообучение 1,5
RTX 4090 24GB MIG не поддерживается Разработка и тестирование 0,8

Разбиение MIG NVIDIA на практике

Обзор архитектуры MIG

┌──────────────────────────────────────────────────────────────┐
│              A100 80GB MIG Partitioning Schemes                │
│                                                                │
│  Scheme 1: 7x MIG 1g.10gb (maximum parallelism)              │
│  ┌──────┐┌──────┐┌──────┐┌──────┐┌──────┐┌──────┐┌──────┐   │
│  │ GI 0 ││ GI 1 ││ GI 2 ││ GI 3 ││ GI 4 ││ GI 5 ││ GI 6 │   │
│  │10GB  ││10GB  ││10GB  ││10GB  ││10GB  ││10GB  ││10GB  │   │
│  │14SM  ││14SM  ││14SM  ││14SM  ││14SM  ││14SM  ││14SM  │   │
│  └──────┘└──────┘└──────┘└──────┘└──────┘└──────┘└──────┘   │
│  Suited for: 7 lightweight inference services in parallel     │
│                                                                │
│  Scheme 2: 2x MIG 3g.40gb (large model inference)            │
│  ┌─────────────────────────────┐┌─────────────────────────────┐│
│  │          GI 0               ││          GI 1               ││
│  │          40GB               ││          40GB               ││
│  │          42SM               ││          42SM               ││
│  └─────────────────────────────┘└─────────────────────────────┘│
│  Suited for: 2x 70B model inference (quantized)               │
│                                                                │
│  Scheme 3: 1x MIG 4g.40gb + 2x MIG 1g.10gb (mixed)          │
│  ┌─────────────────────────────┐┌──────┐┌──────┐              │
│  │          GI 0               ││ GI 1 ││ GI 2 │              │
│  │          40GB               ││10GB  ││10GB  │              │
│  │          56SM               ││14SM  ││14SM  │              │
│  └─────────────────────────────┘└──────┘└──────┘              │
│  Suited for: 1 large model inference + 2 lightweight inference │
└──────────────────────────────────────────────────────────────┘

MIG Configuration in Practice

# nvidia-mig-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: nvidia-mig-config
  namespace: gpu-operator
data:
  config.yaml: |
    version: v1
    mig-configs:
      all-1g.10gb:
        - devices: all
          mig-enabled: true
          mig-devices:
            "1g.10gb": 7
      all-2g.20gb:
        - devices: all
          mig-enabled: true
          mig-devices:
            "2g.20gb": 3
      all-3g.40gb:
        - devices: all
          mig-enabled: true
          mig-devices:
            "3g.40gb": 2
      mixed:
        - devices: [0]
          mig-enabled: true
          mig-devices:
            "3g.40gb": 2
        - devices: [1]
          mig-enabled: true
          mig-devices:
            "1g.10gb": 7
        - devices: [2, 3]
          mig-enabled: false
---
apiVersion: nvidia.com/v1alpha1
kind: MigManager
metadata:
  name: mig-manager
spec:
  config: nvidia-mig-config
  gpuClientsConfig:
    version: v1
    gpuClients:
      - namespace: "ai-inference"
        podSelector:
          matchLabels:
            workload: "llm-inference"
        migDevice: "3g.40gb"
      - namespace: "ai-inference"
        podSelector:
          matchLabels:
            workload: "light-inference"
        migDevice: "1g.10gb"

MIG Pod Scheduling

# Large model inference - using MIG 3g.40gb
apiVersion: v1
kind: Pod
metadata:
  name: llm-inference-70b
  namespace: ai-inference
  labels:
    workload: llm-inference
spec:
  containers:
    - name: inference
      image: vllm/vllm-openai:latest
      resources:
        limits:
          nvidia.com/mig-3g.40gb: 1
      env:
        - name: MODEL_NAME
          value: "Qwen/Qwen2.5-72B-Instruct-AWQ"
        - name: GPU_MEMORY_UTILIZATION
          value: "0.95"
        - name: MAX_MODEL_LEN
          value: "8192"
---
# Lightweight inference - using MIG 1g.10gb
apiVersion: v1
kind: Pod
metadata:
  name: embedding-service
  namespace: ai-inference
  labels:
    workload: light-inference
spec:
  containers:
    - name: embedding
      image: huggingface/tei:latest
      resources:
        limits:
          nvidia.com/mig-1g.10gb: 1
      env:
        - name: MODEL_NAME
          value: "BAAI/bge-large-zh-v1.5"
        - name: MAX_BATCH_SIZE
          value: "256"

Три режима совместного использования GPU

Сравнение режимов

Измерение Time Slicing (TS) MPS MIG
Уровень изоляции Программная Аппаратная (частично) Аппаратная (полностью)
Изоляция памяти Нет (общая) Нет (общая) Да (независимая)
Изоляция производительности Слабая Средняя Хорошая
Параллелизм Высокий Средний Средний
Изоляция сбоев Слабая Слабая Хорошая
Подходящие сценарии Вывод Обучение Смешанный
Требование к GPU Общее Volta+ A100+

Конфигурация Time Slicing

# gpu-time-slicing.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: gpu-time-slicing-config
  namespace: gpu-operator
data:
  config.yaml: |
    version: v1
    flags:
      migStrategy: none
    sharing:
      timeSlicing:
        renameByDefault: false
        resources:
          - name: nvidia.com/gpu
            replicas: 4
            devices: all
---
# Pod using time slicing
apiVersion: apps/v1
kind: Deployment
metadata:
  name: inference-pool
  namespace: ai-inference
spec:
  replicas: 8
  selector:
    matchLabels:
      app: inference
  template:
    metadata:
      labels:
        app: inference
    spec:
      containers:
        - name: inference
          image: vllm/vllm-openai:latest
          resources:
            limits:
              nvidia.com/gpu: 1
          env:
            - name: MODEL_NAME
              value: "Qwen/Qwen2.5-7B-Instruct"

Конфигурация MPS

# gpu-mps-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: gpu-mps-config
  namespace: gpu-operator
data:
  config.yaml: |
    version: v1
    sharing:
      mps:
        resources:
          - name: nvidia.com/gpu
            replicas: 2
            devices: all
---
apiVersion: v1
kind: Pod
metadata:
  name: training-job-mps
  namespace: ai-training
spec:
  containers:
    - name: training
      image: pytorch/pytorch:2.4-cuda12.4
      resources:
        limits:
          nvidia.com/gpu: 1
      command:
        - python
        - -m
        - torch.distributed.launch
        - --nproc_per_node=2
        - train.py

Дерево принятия решений о выборе режима

Есть A100/H100?
├── Нет → Time Slicing (вывод) / MPS (обучение)
└── Да → Требуется полная изоляция?
    ├── Да → Разбиение MIG
    └── Нет → Требуется обучение?
        ├── Да → MPS
        └── Нет → Time Slicing

Конфигурация GPU Device Plugin K8s

Развёртывание Device Plugin NVIDIA

# nvidia-device-plugin.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nvidia-device-plugin-daemonset
  namespace: kube-system
spec:
  selector:
    matchLabels:
      name: nvidia-device-plugin-ds
  template:
    metadata:
      labels:
        name: nvidia-device-plugin-ds
    spec:
      tolerations:
        - key: nvidia.com/gpu
          operator: Exists
          effect: NoSchedule
      priorityClassName: system-node-critical
      containers:
        - name: nvidia-device-plugin
          image: nvcr.io/nvidia/k8s-device-plugin:v0.16.0
          args:
            - --config=default
            - --mig-strategy=mixed
            - --pass-device-specs=true
            - --device-list-strategy=configmap
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop: ["ALL"]
          volumeMounts:
            - name: device-plugin
              mountPath: /var/lib/kubelet/device-plugins
      volumes:
        - name: device-plugin
          hostPath:
            path: /var/lib/kubelet/device-plugins

Мониторинг ресурсов GPU

# gpu-monitor.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: gpu-monitor-config
  namespace: monitoring
data:
  gpu-metrics.json: |
    {
      "metrics": [
        "gpu_utilization",
        "gpu_memory_utilization",
        "gpu_memory_used_bytes",
        "gpu_memory_total_bytes",
        "gpu_power_usage_watts",
        "gpu_temperature_celsius",
        "gpu_sm_clock_mhz",
        "gpu_mem_clock_mhz"
      ],
      "scrape_interval": "15s",
      "labels": {
        "cluster": "production",
        "region": "cn-east"
      }
    }
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: dcgm-exporter
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app: dcgm-exporter
  template:
    metadata:
      labels:
        app: dcgm-exporter
    spec:
      containers:
        - name: dcgm-exporter
          image: nvcr.io/nvidia/k8s/dcgm-exporter:3.3.7
          ports:
            - containerPort: 9400
              name: metrics
          env:
            - name: DCGM_EXPORTER_COLLECTORS
              value: "/etc/dcgm-exporter/dcp-metrics-inventory.csv"
          resources:
            limits:
              nvidia.com/gpu: 1

Стратегии мультитенантного планирования GPU

Управление квотами GPU

# gpu-resource-quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: gpu-quota-team-a
  namespace: team-a
spec:
  hard:
    requests.nvidia.com/gpu: "8"
    limits.nvidia.com/gpu: "8"
    requests.nvidia.com/mig-3g.40gb: "4"
    limits.nvidia.com/mig-3g.40gb: "4"
    requests.nvidia.com/mig-1g.10gb: "14"
    limits.nvidia.com/mig-1g.10gb: "14"
---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: gpu-quota-team-b
  namespace: team-b
spec:
  hard:
    requests.nvidia.com/gpu: "4"
    limits.nvidia.com/gpu: "4"
    requests.nvidia.com/mig-3g.40gb: "2"
    limits.nvidia.com/mig-3g.40gb: "2"

Планирование с вытеснением по приоритету

# gpu-priority-class.yaml
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: gpu-critical
value: 1000000
globalDefault: false
description: "Critical GPU workloads - can preempt others"
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: gpu-high
value: 900000
globalDefault: false
description: "High priority GPU workloads"
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: gpu-low
value: 100000
globalDefault: false
description: "Low priority GPU workloads - preemptible"
---
# Online inference - high priority
apiVersion: apps/v1
kind: Deployment
metadata:
  name: online-inference
spec:
  template:
    spec:
      priorityClassName: gpu-critical
      containers:
        - name: inference
          resources:
            limits:
              nvidia.com/mig-3g.40gb: 1
---
# Offline training - low priority
apiVersion: batch/v1
kind: Job
metadata:
  name: offline-training
spec:
  template:
    spec:
      priorityClassName: gpu-low
      containers:
        - name: training
          resources:
            limits:
              nvidia.com/gpu: 4

Эластичное масштабирование GPU

# gpu-hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: inference-hpa
  namespace: ai-inference
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: inference-pool
  minReplicas: 2
  maxReplicas: 20
  metrics:
    - type: Pods
      pods:
        metric:
          name: gpu_utilization
        target:
          type: AverageValue
          averageValue: "70"
    - type: Pods
      pods:
        metric:
          name: request_latency_ms
        target:
          type: AverageValue
          averageValue: "200"
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 60
      policies:
        - type: Percent
          value: 50
          periodSeconds: 120
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
        - type: Percent
          value: 25
          periodSeconds: 300

Управление GPU-кластерами в продакшене

Маркировка и планирование GPU-узлов

# gpu-node-labels.yaml
# Label GPU types
kubectl label nodes gpu-node-1 nvidia.com/gpu.product=A100-SXM4-80GB
kubectl label nodes gpu-node-2 nvidia.com/gpu.product=H100-SXM5-80GB
kubectl label nodes gpu-node-3 nvidia.com/gpu.product=L40S-48GB

# Label MIG configurations
kubectl label nodes gpu-node-1 nvidia.com/mig.config=mixed
kubectl label nodes gpu-node-2 nvidia.com/mig.config=all-3g.40gb

# Schedule to specific GPU
apiVersion: v1
kind: Pod
metadata:
  name: h100-training
spec:
  nodeSelector:
    nvidia.com/gpu.product: H100-SXM5-80GB
  containers:
    - name: training
      resources:
        limits:
          nvidia.com/gpu: 8

Самовосстановление при сбоях GPU

# gpu-health-check.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: gpu-health-monitor
  namespace: kube-system
spec:
  selector:
    matchLabels:
      app: gpu-health-monitor
  template:
    metadata:
      labels:
        app: gpu-health-monitor
    spec:
      serviceAccountName: gpu-health-sa
      containers:
        - name: monitor
          image: custom/gpu-health-monitor:latest
          env:
            - name: CHECK_INTERVAL
              value: "60"
            - name: MEMORY_ERROR_THRESHOLD
              value: "10"
            - name: TEMPERATURE_THRESHOLD
              value: "90"
            - name: AUTO_CORDON
              value: "true"
          volumeMounts:
            - name: nvidia
              mountPath: /usr/local/nvidia
      volumes:
        - name: nvidia
          hostPath:
            path: /usr/local/nvidia

Результаты оптимизации утилизации GPU

Мера оптимизации Рост утилизации Экономия затрат
Разбиение MIG +35 % 30 %
Time Slicing +25 % 20 %
Планирование по приоритету +15 % 15 %
Эластичное масштабирование +10 % 10 %
Комплексная оптимизация +50 % 50 %

Итоги и ресурсы

Главные выводы

  1. Разбиение MIG: ключевая возможность A100/H100 — превращает 1 карту в 7, первый выбор для сценариев вывода
  2. Совместное использование GPU: Time Slicing для вывода, MPS для обучения, MIG для смешанных нагрузок
  3. Мультитенантное планирование: trio из квот + приоритетов + эластичного масштабирования обеспечивает соблюдение SLA
  4. Комплексная оптимизация: MIG + планирование + масштабирование вместе дают 50 % экономии

Рекомендации по решению планирования GPU

Размер кластера Рекомендуемое решение Ожидаемая утилизация
<8 карт Time Slicing 60 %
8–32 карты MIG + Time Slicing 75 %
32–128 карт MIG + планирование по приоритету 80 %
>128 карт Полный набор решений 85 %+

Нужно быстро сгенерировать cURL-команды для тестирования API вывода GPU? Попробуйте наш инструмент cURL в код и JSON Formatter.

Дополнительные материалы

Попробуйте эти локальные браузерные инструменты — регистрация не требуется →

#K8s GPU scheduling#AI inference scheduling#GPU sharing#MIG partitioning#K8s AI workloads#2026