Programación GPU de K8s para IA en la práctica: partición MIG, uso compartido de GPU y orquestación de cargas de trabajo multiinquilino

云原生

Resumen

  • Las GPU son el recurso central de las cargas de IA: la utilización media de GPU en clústeres K8s es solo del 30-40 %; la optimización de la programación puede elevarla por encima del 80 %
  • Partición MIG de NVIDIA: una sola A100 se divide en 7 instancias, admite la ejecución paralela de diferentes tareas de IA y multiplica por 3 el aprovechamiento de recursos
  • Tres modos de uso compartido de GPU: Time Slicing (TS), MPS y MIG, adecuados respectivamente para inferencia, entrenamiento y escenarios mixtos
  • Estrategias de programación multiinquilino: gestión de cuotas GPU, preempción basada en prioridad y escalado elástico para garantizar el cumplimiento de SLA
  • Este artículo ofrece una solución integral de programación GPU K8s, incluyendo la configuración del Device Plugin y prácticas de extensión del programador

Tabla de contenido


Programación GPU: el desafío central de los clústeres de IA

Estado actual del desperdicio de recursos GPU

Problema Causa Porcentaje de desperdicio
Baja utilización en inferencia Una sola solicitud de inferencia usa solo 10-20 % de la GPU 40-60 %
Fragmentación de entrenamiento El entrenamiento de modelos pequeños ocupa una tarjeta completa 20-30 %
Espera inactiva Tareas en cola a la espera de liberación de GPU 15-25 %
Configuración incorrecta Las solicitudes de recursos no coinciden con el uso real 10-15 %

Evolución de la programación GPU

Fase Período Enfoque Características
Modo exclusivo Antes de 2020 1Pod=1GPU Simple pero desperdiciador
Time Slicing 2021 Uso compartido por franjas de tiempo GPU Adecuado para inferencia
Partición MIG 2022 Partición a nivel de hardware de A100 Aislamiento fuerte
Uso compartido MPS 2023 Uso compartido GPU multiproceso Adecuado para entrenamiento
Programación elástica 2024-2026 MIG dinámico + prioridad Inteligente

Especificaciones GPU comunes en 2026

GPU Memoria Instancias MIG Escenarios adecuados Precio ($/h)
A100 80GB 80GB 7x10GB o 2x40GB Entrenamiento e inferencia generales 3,5
H100 80GB 80GB 7x10GB o 2x40GB Entrenamiento de modelos grandes 4,5
H200 141GB 141GB 7x20GB o 2x70GB Modelos ultra grandes 6,0
L40S 48GB 48GB MIG no compatible Inferencia / ajuste fino 1,5
RTX 4090 24GB MIG no compatible Desarrollo y pruebas 0,8

Partición MIG de NVIDIA en la práctica

Descripción general de la arquitectura 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"

Tres modos de uso compartido de GPU

Comparación de modos

Dimensión Time Slicing (TS) MPS MIG
Nivel de aislamiento Software Hardware (parcial) Hardware (completo)
Aislamiento de memoria No (compartida) No (compartida) Sí (independiente)
Aislamiento de rendimiento Pobre Medio Bueno
Paralelismo Alto Medio Medio
Aislamiento de fallos Pobre Pobre Bueno
Escenarios adecuados Inferencia Entrenamiento Mixto
Requisito de GPU General Volta+ A100+

Configuración 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"

Configuración 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

Árbol de decisión para selección de modo

¿Tiene A100/H100?
├── No → Time Slicing (inferencia) / MPS (entrenamiento)
└── Sí → ¿Se requiere aislamiento completo?
    ├── Sí → Partición MIG
    └── No → ¿Se requiere entrenamiento?
        ├── Sí → MPS
        └── No → Time Slicing

Configuración del Device Plugin GPU de K8s

Despliegue del 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

Monitoreo 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

Estrategias de programación GPU multiinquilino

Gestión de cuotas 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"

Programación con preempción basada en prioridad

# 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

Escalado 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

Gestión de clústeres GPU en producción

Etiquetado y programación de nodos 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

Autorreparación de fallos 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 optimización de utilización GPU

Medida de optimización Aumento de utilización Ahorro de costos
Partición MIG +35 % 30 %
Time Slicing +25 % 20 %
Programación por prioridad +15 % 15 %
Escalado elástico +10 % 10 %
Optimización combinada +50 % 50 %

Resumen y recursos

Puntos clave

  1. Partición MIG: la función estrella de A100/H100 — convierte 1 tarjeta en 7, la primera opción para inferencia
  2. Uso compartido GPU: Time Slicing para inferencia, MPS para entrenamiento, MIG para cargas mixtas
  3. Programación multiinquilino: el trío de cuotas + prioridades + escalado elástico garantiza el cumplimiento de SLA
  4. Optimización combinada: MIG + programación + escalado juntos logran 50 % de ahorro

Recomendaciones de solución de programación GPU

Tamaño del clúster Solución recomendada Utilización esperada
<8 tarjetas Time Slicing 60 %
8-32 tarjetas MIG + Time Slicing 75 %
32-128 tarjetas MIG + programación por prioridad 80 %
>128 tarjetas Conjunto de solución completa 85 %+

¿Necesita generar rápidamente comandos cURL para probar APIs de inferencia GPU? Pruebe nuestra herramienta cURL a Código y el JSON Formatter.

Lecturas adicionales

Prueba estas herramientas que se ejecutan en tu navegador — no requieren registro →

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