Ayude a mejorar esta página
Para contribuir a esta guía del usuario, elija el enlace Edit this page on GitHub que se encuentra en el panel derecho de cada página.
Escalado automático de la inferencia del modelo de IA en GPU con Amazon EKS
sugerencia
Regístrese
En esta sección, se describen los conceptos y procedimientos para escalar automáticamente las cargas de trabajo de inferencia de IA en GPU con Amazon EKS.
La réplica única del modelo vLLM que implementó en la sección anterior Modelos de carga y servicio puede ofrecer un número limitado de solicitudes simultáneas antes de que las nuevas comiencen a esperar, lo que aumenta la latencia y puede provocar que se agoten los tiempos de espera de las solicitudes. Para mantener el ritmo del tráfico, puede escalar automáticamente la implementación horizontalmente. El escalado automático agrega réplicas de las cargas de trabajo a medida que aumenta la demanda y las elimina a medida que disminuye, para evitar el sobreaprovisionamiento de la capacidad de la GPU.
El escalado automático de inferencia se efectúa en dos etapas.
-
Escalado de nodos: cuando el programador de Kubernetes no tiene espacio para colocar nuevos pods en los nodos existentes, los pods permanecen como
Pending. Para responder a los podsPending, Karpenter aprovisiona nodos de GPU para adaptarse a ellos y elimina los nodos cuando las réplicas de la carga de trabajo se reducen verticalmente. -
Escalado de pods: el Escalador automático de pods horizontales
(HPA) observa una métrica configurada. Cuando esa métrica supera un umbral configurado, el HPA aumenta el número de réplicas de la carga de trabajo y se crean nuevos pods de vLLM.
La etapa de escalado de nodos proporciona la capacidad de GPU que necesitan las réplicas de carga de trabajo para ejecutarse. La etapa de escalado de pods ajusta el número de réplicas de carga de trabajo para mantener la métrica elegida cerca del objetivo.
Aprovisionamiento de nodos de GPU con Karpenter
Karpenter administra el ciclo de vida de los nodos y los aprovisiona cuando las cargas de trabajo los necesitan y los consolida o elimina nodos cuando no los necesitan. Funciona con el programador de Kubernetes en lugar de sustituirlo. El programador coloca los pods en nodos. Karpenter aprovisiona capacidad para los pods que el programador no puede ubicar y, a continuación, permite que el programador los vincule cuando el nodo esté Ready.
Karpenter gestiona los nodos de GPU de forma diferente a una flota de nodos de CPU.
- Las GPU se solicitan como unidades completas
-
A menos que utilice una técnica de uso compartido de la GPU, como la segmentación temporal o MIG, un pod obtiene una o más GPU completas en lugar de una fracción, como lo haría con la CPU o la memoria. Cada GPU tiene su propia memoria dedicada, por lo que las réplicas del mismo nodo no comparten la memoria de la GPU. La forma en que esto se asigna a los nodos depende del tipo de instancia:
-
Instancia de una sola GPU (por ejemplo,
g6.xlarge): el nodo contiene exactamente una réplica. Las réplicas, las GPU y los nodos se escalan individualmente y cada réplica se aísla en su propia instancia. -
Instancia de varias GPU (por ejemplo,
g6.12xlarge, que tiene 4 GPU): el complemento para dispositivos anuncia el número total de GPU para que Karpenter pueda empaquetar varias réplicas en un nodo, una por GPU. -
Pod de varias GPU: un pod puede solicitar más de una GPU. Por ejemplo, si se configura
nvidia.com/gpu: 2para crear una partición de un modelo grande en dos GPU, Karpenter colocará el pod en un nodo con esa cantidad de GPU libres.
-
- Karpenter optimiza la disponibilidad y el costo de la GPU
-
Karpenter equilibra el aterrizaje con capacidad de la GPU con su ejecución rentable:
-
Selección de instancias: con un NodePool flexible, Karpenter selecciona el tipo de instancia más económico que se adapte a los pods
Pending. Cuando la capacidad de un lanzamiento sea insuficiente, vuelve a intentarlo automáticamente con otros tipos de instancias y zonas de disponibilidad, lo que aumenta las probabilidades del aterrizaje de la capacidad de GPU. -
Consolidación: cuando la demanda disminuye y las réplicas se reducen horizontalmente, Karpenter recupera los nodos liberados.
WhenEmptyOrUnderutilizedelimina los nodos vacíos y vuelve a empaquetar las réplicas en menos nodos, mientras queWhenEmptyreclama un nodo solo cuando no hay nada programado en él. -
Protección de pods en tránsito: para evitar que los pods se interrumpan durante la consolidación, agregue la anotación
karpenter.sh/do-not-disrupt, establezca un PodDisruptionBudget o utilice la configuraciónconsolidateAfterpara retrasar la consolidación.
-
Una vez que Karpenter disponga de la capacidad de GPU, pasará a la etapa de escalado de los pods: el HPA agrega y elimina réplicas en función de la métrica que configure. En el resto de esta sección, se trata cómo elegir esa métrica de escalado para las cargas de trabajo de inferencia.
Escalado automático de GPU en comparación con CPU
En Kubernetes, las cargas de trabajo tradicionales basadas en CPU se escalan automáticamente de forma inmediata, pero la inferencia basada en GPU no. Hay tres diferencias principales:
Disponibilidad de las métricas para el escalado automático
- Kubernetes proporciona métricas de CPU y memoria al HPA de forma inmediata
-
El kubelet de cada nodo informa del uso de la CPU y la memoria a la API de métricas de Kubernetes, de modo que el HPA puede leer esos valores directamente y escalar las cargas de trabajo sin componentes adicionales.
- Las cargas de trabajo aceleradas requieren configuración de métricas, exportadores y adaptadores adicionales
-
El kubelet no informa de las métricas de GPU ni de inferencia. Para escalar la inferencia basada en GPU, debe agregar exportadores que publiquen las señales pertinentes, como las métricas de las aplicaciones de vLLM y las métricas de GPU del exportador de DCGM, y adaptadores que expongan esas métricas al HPA.
Asignación de recursos y uso compartido
- Las cargas de trabajo tradicionales comparten la CPU y la memoria en fracciones
-
Los cgroups de Linux dividen la CPU y la memoria en recursos fraccionarios, lo que permite que varios pods compartan el mismo nodo. Un pod puede solicitar una parte de la capacidad de un nodo, como 100 milicores de CPU o 512 MiB de memoria.
- Las cargas de trabajo aceleradas asignan y comparten las GPU a través de un marco de asignación de GPU
-
Las GPU no se comparten a través de cgroups como la CPU y la memoria. La configuración de Kubernetes más común actualmente utiliza el complemento para dispositivos de NVIDIA, que asigna GPU completas a pods (por ejemplo,
nvidia.com/gpu: 1). La asignación dinámica de recursos(DRA) es una API de Kubernetes más reciente que asigna las GPU mediante instrucciones de recursos, lo que proporciona una programación y una administración de recursos más flexibles. Tanto el complemento para dispositivos como DRA admiten técnicas de uso compartido de GPU. La segmentación temporal permite que varios pods compartan una GPU al intercalar el acceso a lo largo del tiempo, mientras que las GPU de varias instancias (MIG) particionan las GPU compatibles, como NVIDIA A100 y H100, en instancias de GPU aisladas por hardware.
Señales de escalado
- Las cargas de trabajo tradicionales suelen escalarse en función del uso de la CPU y la memoria
-
El uso es la señal de escalado automático estándar para las cargas de trabajo de CPU y memoria. Es un indicador con retraso porque solo aumenta cuando la carga de trabajo ya está bajo carga, pero, en el caso de muchas aplicaciones tradicionales, es suficiente para impulsar las decisiones de escalado.
- Las cargas de trabajo aceleradas deberían escalarse en función de las métricas de indicadores adelantados, no del uso de la GPU
-
El uso de la GPU (
DCGM_FI_DEV_GPU_UTIL) muestra si la GPU está ocupada, no lo ocupada que está. Como un servidor de inferencia como vLLM puede permanecer cerca del 100 % en una amplia gama de solicitudes entrantes, el uso es una señal de escalado automático poco fiable. En su lugar, escale en función de los indicadores principales que aumentan a medida que la demanda se acerca a la capacidad máxima, como la profundidad de la cola de solicitudes, el tiempo hasta el primer token (TTFT) y la latencia de las solicitudes.
De estas tres diferencias descritas anteriormente, considere detenidamente las señales de escalado. Como el uso de la GPU no es una señal muy fiable de la capacidad de inferencia restante, debe identificar y recopilar las señales que hagan un seguimiento de la demanda real en el servidor de inferencia del modelo.
En la siguiente sección, se explica qué señales usar como métricas de escalado y cómo funcionan juntas.
Elección de métricas de escalado
No hay una métrica única que indique cuándo escalar las réplicas de inferencia del modelo, por lo que se escala en función de una combinación de señales del servidor de inferencia. Estas señales funcionan juntas, y cada una de ellas se basa en la anterior para captar la demanda antes y de forma más fiable que cualquier otra métrica individual:
| Señales | Métrica | Rol en el escalado |
|---|---|---|
|
Cola |
Profundidad de la cola de solicitudes (número de solicitudes en espera de procesamiento) |
Un indicador principal y el mejor activador predeterminado, ya que se forma una cola en el momento en que la demanda supera la capacidad. |
|
Latencia |
Latencia de las solicitudes (latencia p95 o TTFT) |
Activa el escalado cuando las respuestas son lentas, incluso si la cola aún no se ha acumulado, lo que mantiene la latencia orientada al usuario dentro del objetivo. |
|
Memoria de la GPU |
Uso de la caché KV (lo llena que está la memoria de solicitudes de la GPU) |
Evita que se agote la memoria de la GPU; a medida que se acerca a su límite, el servidor comienza a rechazar las solicitudes o a ponerlas en cola. |
En conjunto, forman capas de defensa: la profundidad de la cola de solicitudes es el principal activador cuando la demanda supera la capacidad, la latencia de las solicitudes permite comprobar si hay respuestas lentas antes de que se forme una cola y el uso de la caché KV es el mecanismo de seguridad que evita que se agote la memoria de la GPU.
Puesta en práctica de todo
En las siguientes subsecciones, se muestra cómo hacer que estas señales funcionen con un escalador automático específico.
-
Busque los umbrales de las métricas de escalado. Haga una prueba de carga de una sola réplica de vLLM para determinar su límite de capacidad y los umbrales de profundidad de la cola y latencia a partir de los cuales escalar. Comience aquí.
-
Escale con el HPA y KEDA. Escale automáticamente las réplicas de vLLM con KEDA y el Escalador automático de pods horizontales mediante la profundidad de la cola de solicitudes y la latencia de extremo a extremo como señales de escalado.