Optimiza el rendimiento de GPU en entornos Kubernetes consolidando cargas de trabajo subutilizadas

La infraestructura de inteligencia artificial (IA) puede optimizarse al consolidar las cargas de trabajo de GPU infrautilizadas. En entornos de Kubernetes, la diferencia entre los requisitos del modelo y el tamaño de la GPU provoca ineficiencias.

Por ejemplo, los modelos de reconocimiento automático de voz (ASR) o de texto a voz (TTS) pueden requerir solo 10 GB de VRAM, pero ocupan una GPU completa en implementaciones estándar de Kubernetes. Esto se debe a que el programador asigna un modelo a una o más GPUs y no puede compartir fácilmente los recursos entre modelos, lo que lleva a que recursos computacionales costosos permanezcan infrautilizados.

Optimización de recursos de GPU

Abordar este problema no solo implica reducir costos, sino también optimizar la densidad del clúster para atender a más usuarios concurrentes en el mismo hardware. Este artículo describe cómo implementar y evaluar estrategias de particionamiento de GPU, centrándose en NVIDIA Multi-Instance GPU (MIG) y el time-slicing para maximizar el uso de recursos computacionales.

Utilizando un pipeline de voz AI de grado de producción como campo de prueba, demostramos cómo combinar modelos para maximizar el retorno de inversión (ROI) de la infraestructura manteniendo una fiabilidad superior al 99% y garantizando latencias estrictas.

Fragmentación de recursos de GPU

Por defecto, el plugin de NVIDIA Device para Kubernetes muestra las GPUs como recursos enteros. Un pod solicita nvidia.com/gpu: 1 y el programador lo vincula a un dispositivo físico.

Modelos de lenguaje grande (LLMs) como NVIDIA Nemotron, Llama 3 o Qwen 7B/8B requieren computación dedicada para mantener un bajo tiempo hasta el primer token (TTFT) y un alto rendimiento por lotes. Sin embargo, los modelos de soporte en un pipeline de IA generativa, como los modelos de incrustación, ASR, TTS o guardrails, a menudo utilizan solo una fracción de una GPU. Ejecutar estos modelos ligeros en GPUs dedicadas resulta en:

  • Baja utilización: La utilización de computación de GPU a menudo se mantiene entre el 0-10%.
  • Expansión del clúster: Se necesitan provisionar más nodos para ejecutar la misma cantidad de pods.
  • Fricción en la escalabilidad: Añadir una nueva capacidad requiere una nueva GPU física.

Para solucionar esto, es necesario romper la relación 1:1 entre pods y GPUs.

Estrategias de particionamiento

Evaluamos dos estrategias principales para el particionamiento de GPU soportadas por el NVIDIA GPU Operator.

Particionamiento basado en software

El time-slicing permite que múltiples procesos de NVIDIA CUDA compartan una GPU al intercalar la ejecución. Funciona de manera similar a un programador de CPU: el contexto A se ejecuta, se pausa y luego se ejecuta el contexto B.

  • Mecanismo: Programación a nivel de software a través del controlador CUDA.
  • Ventajas: Maximiza la utilización. Permite “explosiones”: si el Pod A está inactivo, el Pod B puede utilizar el 100% de los núcleos de computación de la GPU.
  • Desventajas: Sin aislamiento de hardware. Un desbordamiento de memoria (OOM) en un pod puede afectar el contexto de ejecución compartido, y un cómputo pesado en un pod puede limitar a los vecinos (el efecto del “vecino ruidoso”).

Además del time-slicing, el Servicio de Múltiples Procesos (MPS) de NVIDIA ofrece un enfoque alternativo basado en software. MPS permite que múltiples procesos compartan recursos de GPU de manera concurrente utilizando una arquitectura de servidor-cliente. Esto proporciona más flexibilidad que MIG y es más resistente a ciertos problemas como filtraciones de memoria en comparación con el time-slicing estándar.

MIG: Enfoque de hardware para particionamiento

MIG particiona físicamente la GPU en instancias separadas, cada una con su propia memoria, caché y multiprocesadores de streaming (SMs). Para el sistema operativo y Kubernetes, estas se ven como dispositivos PCI separados.

  • Mecanismo: Aislamiento a nivel de hardware.
  • Ventajas: Calidad de servicio (QoS) estricta. Una carga de trabajo no puede afectar el rendimiento o la estabilidad de memoria de otra.
  • Desventajas: Tamaño rígido. Si una partición está inactiva, sus recursos de computación no pueden ser “tomados prestados” por un vecino.

Mientras que el time-slicing ofrece flexibilidad, MIG es preferido para entornos de producción donde se requiere un estricto aislamiento de fallos a nivel de hardware para cumplir con los SLA empresariales.

Resultados experimentales

Para evaluar la fragmentación de recursos, probamos el sistema con dos patrones de tráfico distintos:

  • Carga ligera: 5 usuarios concurrentes simulando ~135 segundos de interacción sostenida.
  • Carga pesada: 50 usuarios concurrentes simulando ~375 segundos de interacción sostenida.
A bar chart comparing GenAI inference throughput in requests per second per GPU across light and heavy loads. Under heavy load, Experiment 3 (MIG) achieves the highest efficiency at 1.00 Req/Sec, compared to 0.74 for the Baseline and 0.76 for Time-Slicing.

Los datos muestran cómo el particionamiento afecta las solicitudes de proceso a medida que aumenta la concurrencia, comparando el baseline (GPUs dedicadas), el time-slicing (compartición de software) y MIG (particionamiento de hardware) bajo cargas ligeras y pesadas. Todos los experimentos tienen una tasa de éxito del 100%, sin fallos.

Recomendaciones para el particionamiento

Basado en los datos de referencia, recomendamos la siguiente matriz de decisión:

  1. Default a MIG para escala de producción y estabilidad.
  2. Usar time-slicing para desarrollo o aplicaciones de baja concurrencia.

Comienza a experimentar

  1. Experimenta más: Prueba el repositorio.
  2. Implementa particionamiento: Sigue nuestra Guía de Implementación para configurar perfiles MIG.
  3. Escala con NIM: Despliega pipelines NVIDIA NIM para maximizar tus cargas de trabajo ASR, TTS y LLM.
Ilustración de un hombre mayor con auriculares y chaqueta