Agendamento GPU de K8s para IA na prática: particionamento MIG, compartilhamento de GPU e orquestração de cargas de trabalho multi-inquilino

云原生

Resumo

  • As GPUs são o recurso central das cargas de IA: a utilização média de GPU em clusters K8s é de apenas 30-40 %; a otimização do agendamento pode elevá-la acima de 80 %
  • Particionamento MIG da NVIDIA: uma única A100 pode ser dividida em 7 instâncias, suporta a execução paralela de diferentes tarefas de IA e triplica o aproveitamento de recursos
  • Três modos de compartilhamento de GPU: Time Slicing (TS), MPS e MIG, adequados respectivamente para inferência, treinamento e cenários mistos
  • Estratégias de agendamento multi-inquilino: gerenciamento de cotas GPU, preempção baseada em prioridade e escalonamento elástico para garantir o cumprimento de SLA
  • Este artigo apresenta uma solução completa de agendamento GPU K8s, incluindo a configuração do Device Plugin e práticas de extensão do agendador

Sumário


Agendamento GPU: o desafio central dos clusters de IA

Estado atual do desperdício de recursos GPU

Problema Causa Percentual de desperdício
Baixa utilização em inferência Uma única requisição de inferência usa apenas 10-20 % da GPU 40-60 %
Fragmentação de treinamento O treinamento de modelos pequenos ocupa uma placa inteira 20-30 %
Espera ociosa Tarefas na fila aguardando liberação da GPU 15-25 %
Configuração incorreta As solicitações de recursos não correspondem ao uso real 10-15 %

Evolução do agendamento GPU

Fase Período Abordagem Características
Modo exclusivo Antes de 2020 1Pod=1GPU Simples, mas desperdiçador
Time Slicing 2021 Compartilhamento por fatias de tempo GPU Adequado para inferência
Particionamento MIG 2022 Particionamento em nível de hardware da A100 Isolamento forte
Compartilhamento MPS 2023 Compartilhamento GPU multiprocesso Adequado para treinamento
Agendamento elástico 2024-2026 MIG dinâmico + prioridade Inteligente

Especificações GPU comuns em 2026

GPU Memória Instâncias MIG Cenários adequados Preço ($/h)
A100 80GB 80GB 7x10GB ou 2x40GB Treinamento e inferência gerais 3,5
H100 80GB 80GB 7x10GB ou 2x40GB Treinamento de grandes modelos 4,5
H200 141GB 141GB 7x20GB ou 2x70GB Modelos ultragrandes 6,0
L40S 48GB 48GB MIG não suportado Inferência / ajuste fino 1,5
RTX 4090 24GB MIG não suportado Desenvolvimento e testes 0,8

Particionamento MIG da NVIDIA na prática

Visão geral da arquitetura 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"

Três modos de compartilhamento de GPU

Comparação de modos

Dimensão Time Slicing (TS) MPS MIG
Nível de isolamento Software Hardware (parcial) Hardware (completo)
Isolamento de memória Não (compartilhada) Não (compartilhada) Sim (independente)
Isolamento de desempenho Ruim Médio Bom
Paralelismo Alto Médio Médio
Isolamento de falhas Ruim Ruim Bom
Cenários adequados Inferência Treinamento Misto
Requisito de GPU Geral Volta+ A100+

Configuração de 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"

Configuração de 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

Árvore de decisão para seleção de modo

Você tem A100/H100?
├── Não → Time Slicing (inferência) / MPS (treinamento)
└── Sim → Requer isolamento completo?
    ├── Sim → Particionamento MIG
    └── Não → Requer treinamento?
        ├── Sim → MPS
        └── Não → Time Slicing

Configuração do Device Plugin GPU do K8s

Implantação do 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

Monitoramento de recursos 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

Estratégias de agendamento GPU multi-inquilino

Gerenciamento de cotas 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"

Agendamento com preempção baseada em prioridade

# 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

Escalonamento elástico de 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

Gerenciamento de clusters GPU em produção

Rotulagem e agendamento de nós 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

Autocura de falhas 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

Resultados de otimização de utilização GPU

Medida de otimização Aumento de utilização Economia de custos
Particionamento MIG +35 % 30 %
Time Slicing +25 % 20 %
Agendamento por prioridade +15 % 15 %
Escalonamento elástico +10 % 10 %
Otimização combinada +50 % 50 %

Resumo e recursos

Principais conclusões

  1. Particionamento MIG: o recurso matador da A100/H100 — transforma 1 placa em 7, a primeira escolha para inferência
  2. Compartilhamento de GPU: Time Slicing para inferência, MPS para treinamento, MIG para cargas mistas
  3. Agendamento multi-inquilino: o trio de cotas + prioridades + escalonamento elástico garante o cumprimento de SLA
  4. Otimização combinada: MIG + agendamento + escalonamento juntos alcançam 50 % de economia

Recomendações de solução de agendamento GPU

Tamanho do cluster Solução recomendada Utilização esperada
<8 placas Time Slicing 60 %
8-32 placas MIG + Time Slicing 75 %
32-128 placas MIG + agendamento por prioridade 80 %
>128 placas Conjunto completo de soluções 85 %+

Precisa gerar rapidamente comandos cURL para testar APIs de inferência GPU? Experimente nossa ferramenta cURL para Código e o JSON Formatter.

Leitura adicional

Experimente estas ferramentas executadas localmente no navegador — nenhum cadastro necessário →

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