Descripción general de las prácticas recomendadas de inferencia en GKE

En este documento se ofrece una descripción general de las prácticas recomendadas para ejecutar cargas de trabajo de inferencia en GKE.

Este documento está dirigido a administradores de datos, operadores y desarrolladores que quieran adoptar las prácticas recomendadas para sus cargas de trabajo de inferencia con aceleradores, como GPUs y TPUs, con Kubernetes y GKE. Para obtener más información sobre los roles habituales, consulta Roles y tareas de usuario habituales de GKE.

Preparar el servicio de inferencia en GKE

En esta sección se describen las prácticas recomendadas básicas que debes seguir al preparar la implementación de una carga de trabajo de inferencia. Entre estas prácticas se incluyen el análisis de tu caso práctico, la elección de modelos y la selección de aceleradores.

Analizar las características de tu caso práctico de inferencia

Antes de implementar una carga de trabajo de inferencia, analiza sus requisitos específicos. Este análisis te ayuda a tomar decisiones sobre la arquitectura que equilibren el rendimiento, el coste y la fiabilidad. Conocer tu caso práctico te ayudará a seleccionar los modelos, los aceleradores y las configuraciones adecuados para cumplir tus objetivos de nivel de servicio.

Para orientar tu análisis, evalúa las siguientes dimensiones clave de tu carga de trabajo:

  • Define los requisitos de rendimiento y latencia: determina los SLOs de latencia y rendimiento de tu aplicación. Entre las métricas clave que se deben definir se incluyen las solicitudes por segundo (RPS), la latencia de respuesta, la longitud de los tokens de entrada y salida, y la tasa de aciertos de la caché de prefijos. Para obtener más información, consulta Métricas de rendimiento de inferencia.
  • Evalúa los requisitos del modelo y la escala: las características del modelo que elijas influyen directamente en tus necesidades de infraestructura. Ten en cuenta la longitud máxima del contexto que admite el modelo y compárala con lo que requiere tu carga de trabajo. Si tu caso práctico no requiere el contexto máximo, reducir la longitud máxima del contexto puede liberar memoria del acelerador para una caché KV más grande, lo que podría aumentar el rendimiento.
  • Establece las restricciones de costes y de negocio: tu presupuesto y tus objetivos de negocio son factores clave a la hora de diseñar un servicio de inferencia sostenible y rentable. Define el coste por millón de tokens objetivo para la entrada y la salida, así como el presupuesto mensual total de esta carga de trabajo. Identifica tu objetivo de optimización, como la relación precio-rendimiento, la latencia más baja o el mayor rendimiento, y si tu aplicación puede tolerar una latencia variable.

Elegir los modelos adecuados para tus casos prácticos de inferencia

Seleccionar el modelo adecuado influye directamente en el rendimiento, el coste y la viabilidad de tu aplicación de inferencia. Para seleccionar el modelo óptimo, evalúa los candidatos en función de los siguientes criterios:

  • Alineación de tareas y modalidades: evalúa los modelos en función de las tareas que tengan asignadas y las modalidades que admitan. Un modelo optimizado para una tarea específica casi siempre supera a un modelo de propósito más general.
  • Características técnicas: la arquitectura y la precisión del tipo de datos de un modelo (por ejemplo, FP16, FP8 y FP4) son factores clave para determinar sus requisitos de recursos y su rendimiento. Esta evaluación te ayuda a determinar si necesitas aplicar técnicas de cuantización. Comprueba la precisión admitida de los pesos del modelo, asegúrate de que el framework sea compatible y verifica la longitud de contexto máxima admitida del modelo.
  • Rendimiento y rentabilidad: para tomar una decisión basada en datos, compara los modelos preseleccionados con las métricas disponibles públicamente y con tus propias pruebas internas. Usa clasificaciones como Chatbot Arena para comparar modelos y evaluar el coste por millón de tokens de cada modelo en el hardware de destino.

Aplicar la cuantificación al modelo

La cuantización es una técnica para optimizar las cargas de trabajo de inferencia reduciendo la huella de memoria de tu modelo. Convierte los pesos, las activaciones y la caché de clave-valor (KV) del modelo de formatos de coma flotante de alta precisión (como FP16, FP32 y FP64) a formatos de menor precisión (como FP8 y FP4). Esta reducción de la memoria puede suponer mejoras significativas tanto en el rendimiento como en la rentabilidad.

La cuantización reduce el espacio de memoria del modelo, lo que a su vez reduce la sobrecarga de la transferencia de datos y libera memoria para una caché de clave-valor más grande.

Para aplicar la cuantización a tus modelos de forma eficaz, sigue estas recomendaciones:

  • Evalúa la relación entre precisión y rendimiento: a veces, la cuantización puede provocar una pérdida de precisión del modelo. Cuando evalúes la compensación de la precisión de la cuantización, ten en cuenta que la cuantización de 8 bits a menudo puede dar lugar a una pérdida mínima de precisión. Por el contrario, la cuantización de 4 bits puede reducir hasta cuatro veces los requisitos de memoria del acelerador, pero también puede provocar una mayor pérdida de precisión en comparación con la cuantización de 8 bits. Evalúa el rendimiento del modelo cuantificado en tu caso de uso específico para asegurarte de que la precisión sigue estando dentro de un intervalo aceptable. Para evaluar la pérdida de precisión, puedes usar herramientas como OpenCompass y Language Model Evaluation Harness.
  • Evalúa la compatibilidad con la aceleración por hardware: para sacar el máximo partido a la cuantización, usa aceleradores que proporcionen aceleración por hardware para los formatos de datos que utilice el modelo cuantizado. Por ejemplo:
    • Las GPUs NVIDIA H100 proporcionan aceleración de hardware para las operaciones FP8 y FP16.
    • Las GPUs NVIDIA B200 proporcionan aceleración de hardware para las operaciones FP4, FP8 y FP16.
    • Cloud TPU v5p proporciona aceleración por hardware para operaciones FP8.
  • Buscar modelos precuantizados: antes de cuantizar un modelo, consulta repositorios de modelos públicos como Hugging Face. Lo ideal es encontrar un modelo que se haya entrenado de forma nativa con una precisión inferior, ya que esto puede proporcionar ventajas de rendimiento sin la posible pérdida de precisión de la cuantización posterior al entrenamiento.
  • Usa una biblioteca de cuantización: si no hay ningún modelo precuantizado disponible, usa una biblioteca para realizar la cuantización tú mismo. Los servidores de inferencia, como vLLM, admiten modelos que se han cuantizado con diversas técnicas. Puedes usar herramientas como llm-compressor para aplicar técnicas de cuantización a un modelo no cuantizado.
  • Considera la cuantización de la caché de KV: además de cuantizar los pesos del modelo, también puedes cuantizar la caché de KV. Esta técnica reduce aún más la memoria necesaria para la caché de KV en el tiempo de ejecución, lo que puede mejorar el rendimiento.

Para obtener más información, consulta Optimizar las cargas de trabajo de inferencia de LLMs en GPUs.

Elegir los aceleradores adecuados

Seleccionar el acelerador adecuado influye directamente en el rendimiento, el coste y la experiencia de usuario de tu servicio de inferencia. La elección óptima depende de un análisis de los requisitos de memoria de tu modelo, tus objetivos de rendimiento y tu presupuesto.

Para elegir el acelerador adecuado para tu caso práctico específico, sigue estos pasos:

  1. Calcula los requisitos de memoria: primero, calcula la memoria mínima del acelerador necesaria para cargar y ejecutar tu modelo. La memoria total es la suma de la memoria necesaria para los pesos del modelo, la sobrecarga del motor de inferencia, las activaciones intermedias y la caché KV.

    Para estimar la memoria necesaria, utiliza la siguiente ecuación:

    \[ \begin{aligned} \text{Required accelerator memory} = {} & (\text{Model weights} + \text{Overhead} + \text{Activations}) \\ & + (\text{KV cache per batch} \times \text{Batch size}) \end{aligned} \]

    Los términos de la ecuación son los siguientes:

    • Ponderaciones del modelo: el tamaño de los parámetros del modelo.
    • Sobrecarga: un búfer para el servidor de inferencia y otra sobrecarga del sistema, normalmente de 1 a 2 GB.
    • Activación: la memoria necesaria para las activaciones intermedias durante la ejecución de un modelo.
    • Caché de KV por lote: la memoria necesaria para la caché de KV de una sola secuencia, que se adapta a la longitud del contexto y a la configuración del modelo.
    • Tamaño del lote: el número de secuencias (max_num_sequences) que procesará simultáneamente el motor de inferencia.

    Ejemplo: Calcula los requisitos de memoria del acelerador para Gemma 3

    Para calcular la memoria del acelerador necesaria para implementar un modelo de 27.000 millones de parámetros de Gemma 3 con una precisión de BF16 para un caso práctico de generación de texto, puedes usar los siguientes valores.

    Para ver una guía interactiva de este cálculo, consulta el artículo ¿Cuánta VRAM necesita mi modelo? Cuaderno de Colab.

    • Entradas:
      • Ponderaciones del modelo: 54 GB
      • Tamaño del lote (max_num_sequences): 1
      • Longitud media de las entradas: 1500 tokens
      • Longitud media de la salida: 200 tokens
      • Sobrecarga del motor de inferencia: 1 GB (estimación)
      • Tamaño del tipo de datos de la caché de KV: 2 (para BF16)
      • Vectores de KV: 2 (uno para la clave y otro para el valor)
    • Configuración del modelo de un modelo ajustado para instrucciones Gemma 3 27B:
      • hidden_size: 5376
      • intermediate_size: 21504
      • num_attention_heads: 32
      • num_hidden_layers: 62
      • num_key_value_heads: 16
    • Cálculo de memoria:
      • sequence_length = avg_input_length + avg_output_length = 1500 + 200 = 1700 tokens
      • pytorch_activation_peak_memory = (max_num_sequences * sequence_length * (18 * hidden_size + 4 * intermediate_size)) / (1000^3) = ~0,31 GB (estimación).
      • head_dims = hidden_size / num_attention_heads = 5376 / 32 = 168
      • kv_cache_memory_per_batch = (kv_vectors * max_num_sequences * sequence_length * num_key_value_heads * head_dims * num_hidden_layers * kv_data_type_size) / (1000^3) = (2 * 1 * 1700 * 16 * 168 * 62 * 2) / (1000^3) = ~1,13 GB
      • Memoria del acelerador necesaria = Model weights + Overhead + Activations + KV cache per batch = 54 + 1 + 0,31 + 1,13 = ~56,44 GB

    La memoria total estimada del acelerador que necesitas para implementar el modelo es de aproximadamente 57 GB.

  2. Evalúa las opciones de acelerador: una vez que hayas estimado tus requisitos de memoria, evalúa las opciones de GPU y TPU disponibles en GKE.

    Además de la cantidad de memoria del acelerador, ten en cuenta los siguientes requisitos del modelo para tu evaluación:

    • En el caso de los modelos que requieren más de un acelerador, comprueba si admiten conectividad de alta velocidad, como NVLINK y GPUDirect, para reducir la latencia de comunicación.
    • En el caso de los modelos cuantizados, usa aceleradores con aceleración de hardware nativa para tipos de datos de menor precisión, como FP8 y FP4, para obtener el máximo rendimiento.

    La elección que hagas implica un equilibrio entre estas funciones, el rendimiento, el coste y la disponibilidad.

    Nota: Para obtener las recomendaciones más recientes sobre aceleradores basadas en comparativas de rendimiento de servicio y análisis de costes, también puedes usar la herramienta de inicio rápido de inferencia de GKE. Para obtener más información, consulta la documentación de GKE Inference Quickstart.

    Para ayudarte a elegir los aceleradores adecuados para tu carga de trabajo, en la siguiente tabla se resumen las opciones más adecuadas para los casos prácticos de inferencia habituales. Estos casos prácticos se definen de la siguiente manera:

    • Inferencia de modelos pequeños: para modelos con unos pocos miles de millones de parámetros, donde la carga computacional se limita a un solo host.
    • Inferencia de modelos grandes en un solo host: para modelos con decenas o cientos de miles de millones de parámetros, donde la carga computacional se comparte entre varios aceleradores en una sola máquina host.
    • Inferencia de modelos grandes multihost: para modelos con cientos de miles de millones o billones de parámetros, donde la carga computacional se comparte entre varios aceleradores en varias máquinas host.
    Caso práctico Aceleradores recomendados Serie de máquinas Características principales
    Inferencia de modelos pequeños NVIDIA L4 G2 Opción rentable para modelos pequeños (24 GB de memoria por GPU).
    NVIDIA RTX Pro 6000 G4 Rentable para modelos de menos de 30.000 millones de parámetros y generación de imágenes (96 GB de memoria por GPU). Admite la comunicación directa entre GPUs, por lo que es adecuada para la inferencia de varias GPUs en un solo host.
    TPU v5e - Optimizada para ofrecer una buena relación calidad-precio.
    TPU v6e - Ofrece el valor más alto para los modelos Transformer y de texto a imagen.
    Inferencia de modelos grandes de un solo host NVIDIA A100 A2 Adecuado para la mayoría de los modelos que caben en un solo nodo (hasta 640 GB de memoria total).
    NVIDIA H100 A3 Ideal para cargas de trabajo de inferencia que caben en un solo nodo (hasta 640 GB de memoria total).
    NVIDIA B200 A4 Opción de futuro para modelos exigentes que caben en un solo nodo (hasta 1440 GB de memoria total).
    TPU v4 - Ofrece un buen equilibrio entre coste y rendimiento.
    TPU v5p - Una opción de alto rendimiento para cargas de trabajo exigentes.
    Inferencia de modelos grandes con varios hosts NVIDIA H200 A3 Ultra Adecuado para modelos grandes que requieren mucha memoria (hasta 1128 GB de memoria total).
    NVIDIA B200 / GB200 A4 / A4X Para las cargas de trabajo más exigentes, que requieren muchos recursos de computación y que dependen de la red. Las máquinas A4X usan CPUs basadas en Arm, lo que puede requerir la refactorización de la carga de trabajo (cambios en el código más allá de una simple recompilación de contenedores) si tu carga de trabajo usa funciones u optimizaciones específicas de x86.
    TPU v5e - Optimizado para ofrecer eficiencia y rendimiento a un coste reducido en el servicio de LLMs medianos y grandes.
    TPU v5p - Una opción de alto rendimiento para la inferencia de varios hosts que requiere una paralelización a gran escala.
    TPU v6e - Optimizado para el servicio de transformadores, de texto a imagen y de CNN.

    Ejemplo: elegir un acelerador para un modelo de 260 GB

    Supongamos que tienes que implementar un modelo que requiere 260 GB de memoria de acelerador total (200 GB para el modelo, 50 GB para la caché KV y 10 GB para la sobrecarga).

    Si solo tienes en cuenta los requisitos de memoria, puedes excluir las GPUs NVIDIA L4, ya que la máquina G2 más grande ofrece un máximo de 192 GB de memoria de acelerador. Además, como las GPUs L4 no admiten una conectividad de alta velocidad y baja latencia entre aceleradores, distribuir la carga de trabajo en varios nodos no es una opción viable para conseguir el rendimiento deseado.

    Si quieres evitar refactorizar tus cargas de trabajo x86-64 (es decir, tener que modificar tu código para que se pueda ejecutar en otro tipo de procesador), también excluirías los aceleradores NVIDIA GB200 y GB300, que usan CPUs basados en Arm.

    Por lo tanto, tienes las siguientes opciones:

    • NVIDIA A100
    • NVIDIA RTX Pro 6000
    • NVIDIA H100
    • NVIDIA H200
    • NVIDIA B200

    Todos estos aceleradores tienen suficiente memoria. El siguiente paso es evaluar su disponibilidad en las regiones de destino. Supongamos que solo hay GPUs NVIDIA A100 y NVIDIA H100 disponibles en una región concreta. Después de comparar la relación precio-rendimiento de estas dos opciones, puede que elijas la NVIDIA H100 para tu carga de trabajo.

    GPUs con varias instancias

    Para aumentar la utilización de la GPU y optimizar los costes de la GPU, puedes usar configuraciones de GPU con varias instancias. Con esta configuración, puedes particionar una GPU compatible para compartir una sola GPU entre varios contenedores en GKE. Cuando aprovisionas una GPU con varias instancias, solo adjuntas GPUs completas a tus nodos de GKE y estás sujeto a los precios de las GPUs correspondientes. Te recomendamos que uses GPUs de varias instancias solo con cargas de trabajo de confianza.

    Por ejemplo, puedes conectar una NVIDIA RTX PRO 6000 y hacer lo siguiente:

    • Particiónala en cuatro instancias (cada instancia proporciona 24 GB de memoria del acelerador) y ejecuta modelos de difusión o cargas de trabajo de inferencia de modelos pequeños, como modelos que tengan aproximadamente 8000 millones de parámetros y usen la precisión del formato de datos FP16 para los pesos del modelo. Esta partición puede tener una mejor relación precio-rendimiento en comparación con una NVIDIA L4.
    • Particiónala en dos instancias (cada instancia proporciona 48 GB de memoria del acelerador) y ejecuta cargas de trabajo de inferencia de modelos pequeños, como modelos que tengan aproximadamente 15.000 millones de parámetros y usen la precisión del formato de datos FP16 para los pesos del modelo. Esta partición puede ser una alternativa a la ejecución de cargas de trabajo de inferencia en una GPU NVIDIA A100 de 40 GB.

    Para obtener más información, consulta Ejecutar GPUs con varias instancias.

    Para obtener más información, consulta las secciones sobre tipos de máquinas con GPU y familia de máquinas optimizadas para aceleradores en la documentación de Compute Engine.

  3. Selecciona una estrategia de distribución de inferencias: si tu modelo es demasiado grande para un solo acelerador, selecciona una estrategia de distribución en función de los requisitos de tu carga de trabajo.

    Primero, elija una estrategia de distribución en función de la topología de su hardware:

    • Un solo acelerador: si tu modelo cabe en un solo acelerador, este es el enfoque más sencillo y recomendado.
    • Un solo nodo y varios aceleradores: si tu modelo cabe en un solo nodo con varios aceleradores, puedes usar el paralelismo de tensores para distribuir el modelo entre los aceleradores de ese nodo.
    • Varios nodos y varios aceleradores: si tu modelo es demasiado grande para un solo nodo, puedes usar una combinación de paralelismo de tensor y de pipeline para distribuirlo en varios nodos.

    Para implementar estas estrategias, puedes usar las siguientes técnicas de paralelismo:

    • Paralelismo de tensores: esta técnica fragmenta las capas de un modelo en varios aceleradores. Es muy eficaz en un solo nodo con interconexiones de alta velocidad, como NVLINK o PCIe directo entre iguales, pero requiere una comunicación significativa entre los aceleradores.

      Ejemplo: Paralelismo de tensores

      Por ejemplo, supongamos que tienes que desplegar un modelo con 109.000 millones de parámetros. Con la precisión BF16 (16 bits) predeterminada, se necesitan aproximadamente 113 GB para cargar los pesos del modelo en la memoria del acelerador. Una sola GPU NVIDIA H100 proporciona 80 GB de memoria. Por lo tanto, aunque no tengas en cuenta otros requisitos de memoria, como la caché KV, necesitas al menos dos GPUs NVIDIA H100 para cargar el modelo, con un tamaño de paralelismo de tensores de dos.

    • Paralelismo de la canalización: esta técnica particiona las capas de un modelo de forma secuencial en varios nodos. Es adecuada para distribuir un modelo en varios nodos de una implementación de varios hosts y requiere menos comunicación entre los rangos del modelo que el paralelismo de tensores.

      Ejemplo: paralelismo híbrido (de tensor y de flujo de trabajo)

      En el caso de un modelo muy grande con más de 600.000 millones de parámetros, el requisito de memoria puede superar los 1,1 TB. En un escenario con dos nodos a3-megagpu-8g (cada uno con ocho GPUs NVIDIA H100), el clúster tiene 1,28 TB de memoria de acelerador. Para ejecutar el modelo, implementarías una estrategia híbrida: paralelismo de tensores de 8 vías en cada nodo y paralelismo de la fase de 2 vías en los dos nodos. El modelo se dividiría en dos fases: la primera mitad de las capas en el primer nodo y la segunda mitad en el segundo nodo. Cuando llega una solicitud, el primer nodo la procesa y envía los datos intermedios a través de la red al segundo nodo, que completa el cálculo.

    Para obtener más directrices sobre cómo elegir una estrategia de inferencia distribuida para una réplica de un solo modelo, consulta Paralelismo y escalado en la documentación de vLLM.

  4. Selecciona un tipo de máquina optimizada para aceleradores: en función del acelerador que elijas y del número que necesites, selecciona un tipo de máquina que proporcione esos recursos. Cada tipo de máquina ofrece una combinación específica de vCPUs, memoria del sistema y ancho de banda de red, lo que también puede influir en el rendimiento de tu carga de trabajo. Por ejemplo, si necesitas 16 GPUs NVIDIA H100, debes seleccionar el tipo de máquina a3-megagpu-16g.

  5. Ejecuta tus propias pruebas de rendimiento: el rendimiento de tu carga de trabajo de inferencia depende en gran medida de tu caso práctico específico. Ejecuta tus propias comparativas para validar tus elecciones y optimizar tu configuración.

Optimizar la configuración del servidor de inferencia

Para conseguir un rendimiento óptimo al desplegar tu carga de trabajo de inferencia, te recomendamos que sigas un ciclo de pruebas comparativas y ajustes:

  1. Empieza con la guía de inicio rápido de inferencia de GKE para obtener una configuración de Kubernetes optimizada para tu caso práctico.
  2. Ejecuta comparativas para registrar las métricas de latencia y de rendimiento de referencia.
  3. Ajusta la configuración de tu servidor de inferencia.
  4. Vuelve a ejecutar las comparativas y compara los resultados para validar los cambios.

Las siguientes recomendaciones se basan en el servidor de inferencia vLLM, pero los principios también se aplican a otros servidores. Para obtener instrucciones detalladas sobre todos los ajustes disponibles, consulta la documentación Optimización y ajuste de vLLM:

  • Configurar el paralelismo:
    • Paralelismo de tensores (tensor_parallel_size): asigna a este parámetro el número de aceleradores de un solo nodo para fragmentar la carga de trabajo. Por ejemplo, si se define tensor_parallel_size=4, la carga de trabajo se distribuirá entre cuatro aceleradores. Ten en cuenta que aumentar este valor puede provocar una sobrecarga de sincronización excesiva.
    • Paralelismo de la fase de procesamiento (pipeline_parallel_size): asigna a este valor el número de nodos en los que vas a distribuir tu modelo. Por ejemplo, si vas a implementar en dos nodos con ocho aceleradores cada uno, deberías definir tensor_parallel_size=8 y pipeline_parallel_size=2. Si aumentas este valor, se pueden producir penalizaciones por latencia.
  • Ajustar la caché de KV (gpu_memory_utilization): este parámetro controla el porcentaje de memoria de la GPU reservado para los pesos, las activaciones y la caché de KV del modelo. Un valor más alto aumenta el tamaño de la caché de clave-valor y puede mejorar el rendimiento. Te recomendamos que le asignes un valor entre 0.9 y 0.95. Si se producen errores de falta de memoria, reduce este valor.
  • Configurar la longitud máxima del contexto (max_model_len): para reducir el tamaño de la caché de pares clave-valor y los requisitos de memoria, puedes definir una longitud máxima del contexto inferior a la predeterminada del modelo. De esta forma, podrás usar GPUs más pequeñas y rentables. Por ejemplo, si tu caso práctico solo requiere un contexto de 40.000 tokens, pero el valor predeterminado de tu modelo es 256.000, al definir max_model_len en 40.000, se liberará memoria para una caché KV más grande, lo que podría aumentar el rendimiento.
  • Configura el número de solicitudes simultáneas (max_num_batched_tokens, max_num_seqs): ajusta el número máximo de solicitudes que vLLM procesa simultáneamente para evitar la apropiación cuando la caché de KV tenga poco espacio. Los valores más bajos de max_num_batched_tokens y max_num_seqs reducen los requisitos de memoria, mientras que los valores más altos pueden mejorar el rendimiento, pero con el riesgo de que se produzcan errores de falta de memoria. Para encontrar los valores óptimos, te recomendamos que ejecutes experimentos de rendimiento y observes el número de solicitudes de expropiación en las métricas de Prometheus que exporta vLLM.

Para obtener más información, consulta los siguientes recursos:

Optimizar la latencia y la disponibilidad

Para asegurarte de que tu servicio de inferencia sea rápido y fiable, debes optimizarlo para que tenga una latencia de inicio baja y una alta disponibilidad de recursos.

Optimizar la latencia de arranque en frío de las cargas de trabajo de inferencia

Minimizar el tiempo que tardan en iniciarse las cargas de trabajo de inferencia es fundamental tanto para la rentabilidad como para la experiencia de usuario. Una latencia de arranque en frío baja permite que tu clúster aumente la escala rápidamente para satisfacer la demanda, lo que garantiza un servicio con buena respuesta y minimiza la necesidad de un aprovisionamiento excesivo costoso.

Optimizar el tiempo de inicio de los pods

El tiempo que tarda un pod en estar listo depende en gran medida del tiempo que tarda en extraer la imagen del contenedor y descargar los pesos del modelo. Para optimizar ambos, te recomendamos las siguientes estrategias:

  • Acelera la carga de modelos con un cargador de datos optimizado: el método que uses para almacenar y cargar los pesos de tu modelo tiene un impacto significativo en el tiempo de inicio. En las versiones 0.10.2 y posteriores de vLLM, se recomienda usar Run:ai Model Streamer para cargar modelos transmitiéndolos directamente desde un segmento de Cloud Storage.

    Si el streamer no está disponible para tu caso práctico, puedes montar un segmento de Cloud Storage con Cloud Storage FUSE y optimizar su rendimiento habilitando los espacios de nombres jerárquicos y usando técnicas como las descargas paralelas y la obtención previa. Para obtener más información sobre estas técnicas, consulta Optimizar el controlador CSI de Cloud Storage FUSE para mejorar el rendimiento de GKE. En cualquier caso, te recomendamos que uses Anywhere Cache para crear cachés de lectura zonales de alto rendimiento para tus segmentos y que habilites el acceso uniforme a nivel de segmento para controlar el acceso a tus segmentos de forma uniforme.

    Si ya usas Managed Lustre para el almacenamiento de archivos de alto rendimiento de tus cargas de trabajo de entrenamiento, también puedes usarlo para cargar los pesos del modelo de inferencia. Este enfoque ofrece acceso de baja latencia cuando la localidad de los datos y la compatibilidad con POSIX son fundamentales.

  • Habilita el streaming de imágenes: para reducir el tiempo que se tarda en extraer las imágenes de contenedor, habilita Streaming de imágenes en tu clúster de GKE. El streaming de imágenes permite que los contenedores se inicien antes de que se haya descargado toda la imagen, lo que puede reducir drásticamente el tiempo de inicio de los pods.

Habilitar nodos de inicio rápido

En el caso de las cargas de trabajo que requieren un escalado rápido, puedes aprovechar los nodos de inicio rápido de GKE. Los nodos de inicio rápido son recursos de hardware preinicializados que tienen un tiempo de inicio significativamente menor que los nodos estándar. Si tu clúster cumple los requisitos, GKE habilita automáticamente los nodos de inicio rápido.

Planificar la capacidad y maximizar la disponibilidad de aceleradores

Los aceleradores de alta demanda, como las GPUs y las TPUs, pueden tener una disponibilidad limitada, por lo que es fundamental contar con una estrategia de planificación de la capacidad proactiva.

Planificar y reservar capacidad

Los aceleradores de alta demanda pueden tener una disponibilidad limitada, por lo que es esencial contar con una estrategia de planificación de la capacidad proactiva. Para garantizar el acceso a los recursos que necesitas, sigue estas recomendaciones:

  • Determina la capacidad de base y la gestión de picos: planifica la capacidad de acelerador de base que necesitas reservar. El importe que debes reservar depende de tu caso práctico. Por ejemplo, puedes reservar el 100% de la capacidad necesaria para cargas de trabajo críticas que no toleren retrasos o reservar un percentil determinado (como el 90.º o el 95.º) y adquirir el resto bajo demanda para gestionar los picos.

  • Reservar capacidad de base: para obtener recursos con un alto nivel de certeza, crea reservas. Puedes elegir un tipo de reserva en función de tus necesidades. Por ejemplo, para reservar recursos de alta demanda, como aceleradores, para un periodo concreto en el futuro, puedes crear reservas futuras en el modo Calendario.

  • Orquestar la capacidad para los picos: si la demanda supera tus reservas de referencia, puedes implementar una estrategia de respaldo con otros tipos de capacidad, como la capacidad bajo demanda, las máquinas virtuales de acceso puntual o Dynamic Workload Scheduler (DWS). Puedes automatizar esta estrategia de respaldo usando clases de computación personalizadas para definir un orden de prioridad para aprovisionar diferentes tipos de capacidad.

  • Acceder a precios con descuento: para tu capacidad de referencia, compra descuentos por compromiso de uso (CUDs) para obtener precios con grandes descuentos a cambio de un compromiso de uno o tres años.

Usa Dynamic Workload Scheduler con el modo de aprovisionamiento de inicio flexible si tus cargas de trabajo toleran retrasos en la adquisición de capacidad

En el caso de las cargas de trabajo que pueden tolerar cierto retraso en la adquisición de capacidad, Dynamic Workload Scheduler (DWS) con el modo de aprovisionamiento de inicio flexible es una opción para obtener aceleradores a un precio rebajado. DWS te permite poner en cola solicitudes de capacidad durante un máximo de siete días.

Si usas DWS con el modo de aprovisionamiento flex-start, te recomendamos lo siguiente:

  • Incorporarlo a una clase de computación personalizada: usa una clase de computación personalizada para definir DWS como parte de una estrategia de reserva priorizada para adquirir capacidad.
  • Define una duración máxima del tiempo de ejecución: el parámetro maxRunDurationSeconds define el tiempo de ejecución máximo de los nodos solicitados a través de DWS. Si asignas un valor inferior al predeterminado de siete días, aumentarán las probabilidades de obtener los nodos solicitados.
  • Habilita el reciclaje de nodos: para evitar el tiempo de inactividad de tus cargas de trabajo, habilita el reciclaje de nodos. Esta función empieza a aprovisionar un nuevo nodo antes de que caduque el antiguo, lo que asegura una transición más fluida.
  • Minimizar las interrupciones: para minimizar las interrupciones causadas por el desalojo y las actualizaciones de nodos, configura ventanas y exclusiones de mantenimiento, inhabilita la reparación automática de nodos y aprovecha la estrategia de actualizaciones de corta duración.

Usar clases de computación personalizadas

Las clases de computación personalizadas (CCCs) son una función de GKE que te permite definir una lista priorizada de configuraciones de infraestructura para tus cargas de trabajo. Los CCCs proporcionan funciones clave diseñadas para mejorar la obtención de aceleradores:

  • Prioridades de cálculo alternativas: puedes definir una lista priorizada de configuraciones. Si la opción que prefieres no está disponible durante un evento de escalado vertical, la herramienta de adaptación automática recurrirá automáticamente a la siguiente de la lista, lo que aumentará significativamente la probabilidad de adquirir capacidad correctamente.
  • Migración activa a nodos de mayor prioridad: cuando configuras esta función, GKE sustituye automáticamente los nodos que se ejecutan en configuraciones de menor prioridad por nodos de configuraciones de mayor prioridad a medida que están disponibles. De esta forma, te aseguras de que tus pods se ejecuten en los nodos que prefieras (que suelen ser los más rentables).

Con las clases de computación personalizadas (CCCs), puedes crear una estrategia alternativa para adquirir nodos. Esta estrategia usa una lista priorizada de diferentes tipos de capacidad, como máquinas virtuales bajo demanda, máquinas virtuales de Spot o reservas. Cada uno de estos tipos de capacidad tiene un nivel de disponibilidad diferente:

  • Reservas: ofrecen el máximo nivel de garantía para obtener capacidad. Cuando consumas reservas con CCCs, ten en cuenta sus restricciones. Por ejemplo, algunos tipos de reserva limitan los tipos de máquina que puedes reservar o el número máximo de máquinas que puedes solicitar.
  • Bajo demanda: es el modelo de aprovisionamiento estándar, que ofrece flexibilidad, pero puede estar sujeto a restricciones de capacidad regionales en el caso de los recursos con mucha demanda.
  • Máquinas virtuales de acceso puntual: usa la capacidad de reserva a un precio más bajo, pero se pueden interrumpir. Cuando se produce un evento de desalojo, GKE proporciona un periodo de finalización gradual de hasta 30 segundos a los pods afectados en la medida de lo posible. Para aprovechar esta función, haz que tus cargas de trabajo toleren los eventos de expropiación implementando puntos de control y mecanismos de reintento.
  • Dynamic Workload Scheduler (DWS): te permite poner en cola solicitudes de recursos escasos a precios con descuento. Esta función es ideal para cargas de trabajo que pueden tolerar retrasos en la adquisición de capacidad.

El orden de tu lista de prioridades debe cambiar en función de si tu objetivo principal es minimizar la latencia u optimizar los costes. Por ejemplo, puedes configurar las siguientes listas de prioridades para diferentes requisitos de carga de trabajo:

Prioridad Cargas de trabajo de baja latencia Cargas de trabajo con optimización de costes (tolerantes a la latencia)
1 Reservas (específicas y, después, cualquiera) Reservas (específicas y, después, cualquiera)
2 bajo demanda Spot VMs
3 Spot VMs Dynamic Workload Scheduler
4 Dynamic Workload Scheduler bajo demanda

En los casos prácticos de baja latencia, la capacidad bajo demanda tiene prioridad después de las reservas, ya que informa rápidamente de las deficiencias de capacidad, lo que permite que el CCC vuelva rápidamente a la siguiente opción.

En los casos prácticos optimizados para reducir costes, se priorizan las máquinas virtuales de acceso puntual y DWS con inicio flexible después de las reservas para aprovechar los costes más bajos. La capacidad bajo demanda se usa como último recurso.

Configurar la política de ubicación de los clústeres y grupos de nodos de GKE

La política de ubicación de la herramienta de adaptación dinámica de clústeres controla cómo distribuye GKE los nodos en las zonas durante un evento de escalado vertical. Este ajuste es especialmente importante cuando se usan clases de computación personalizadas, ya que determina qué zonas tendrá en cuenta la herramienta de escalado automático de clústeres antes de aplicar la lista de prioridades de la CCC.

Para aumentar las probabilidades de obtener aceleradores, configura la política de ubicación en función de los requisitos de tu carga de trabajo:

  • location-policy=ANY: prioriza la obtención de capacidad en lugar de equilibrar los nodos de forma uniforme entre las zonas. Este ajuste es especialmente útil cuando tu CCC incluye máquinas virtuales de Spot o tipos de máquinas con disponibilidad variable, ya que ANY permite que el escalador automático de clústeres elija la zona con más probabilidades de cumplir los tipos de nodos priorizados del CCC. Utilice este ajuste también para priorizar el uso de las reservas sin usar. Cuando uses esta política, te recomendamos que empieces con num-nodes=0 para que el escalador automático de clústeres tenga la máxima flexibilidad a la hora de encontrar capacidad.

  • location-policy=BALANCED: intenta distribuir los nodos de forma uniforme entre todas las zonas disponibles. Usa esta política cuando tus cargas de trabajo utilicen recursos fáciles de obtener y quieras mantener la redundancia de zona para lograr una alta disponibilidad.

Puedes configurar este ajuste al crear o actualizar un grupo de nodos.

Optimizar la eficiencia y los costes

Si monitorizas tus aceleradores con atención y ajustas la escala de tus cargas de trabajo de forma inteligente, puedes reducir significativamente los residuos y los costes operativos.

Monitorizar los aceleradores y los servidores de inferencia

Una estrategia de observabilidad completa es esencial para comprender el rendimiento y la utilización de tus cargas de trabajo de inferencia. GKE proporciona un conjunto de herramientas para ayudarte a monitorizar tus aceleradores y servidores de inferencia:

  • Monitorizar métricas de DCGM para GPUs NVIDIA: para monitorizar el estado y el rendimiento de tus GPUs NVIDIA, configura GKE para que envíe métricas de NVIDIA Data Center GPU Manager (DCGM) a Cloud Monitoring.
  • Habilita la monitorización automática de aplicaciones: para simplificar el proceso de monitorización de tus servidores de inferencia, habilita la monitorización automática de aplicaciones en GKE.
  • Instrumenta tus cargas de trabajo con OpenTelemetry: en el caso de las cargas de trabajo que no sean compatibles con la monitorización automática de aplicaciones, usa OpenTelemetry para recoger métricas y trazas personalizadas.

Escalar automáticamente tus pods

Para asegurarte de que tus cargas de trabajo de inferencia se adapten dinámicamente a los cambios en la demanda, usa un Horizontal Pod Autoscaler (HPA) para escalar automáticamente el número de pods. En el caso de las cargas de trabajo de inferencia, es fundamental basar las decisiones de escalado en métricas que reflejen directamente la carga del servidor de inferencia, en lugar de en métricas estándar de CPU o memoria.

Para configurar el autoescalado de tus cargas de trabajo de inferencia, te recomendamos que hagas lo siguiente:

  • Configura HPA en función de métricas basadas en la inferencia: para obtener un rendimiento óptimo, configura HPA para que escale en función de las métricas de tu servidor de inferencia. La mejor métrica depende de si quieres optimizar la latencia o el rendimiento.

    • En el caso de las cargas de trabajo sensibles a la latencia, tiene dos opciones principales:

      • Utilización de la caché de KV (por ejemplo, vllm:gpu_cache_usage_perc): esta métrica suele ser el mejor indicador de picos de latencia inminentes. Un uso elevado de la caché de KV indica que el motor de inferencia está cerca de alcanzar su capacidad máxima. El HPA puede usar esta señal para añadir réplicas de forma preventiva y mantener una experiencia de usuario estable.
      • Número de solicitudes en curso (tamaño del lote) (por ejemplo,vllm:num_requests_running): esta métrica está directamente relacionada con la latencia, ya que los tamaños de lote más pequeños suelen dar lugar a una latencia menor. Sin embargo, usarlo para el escalado automático puede ser complicado, ya que maximizar el rendimiento depende del tamaño de las solicitudes entrantes. Es posible que tengas que elegir un valor inferior al tamaño de lote máximo posible para asegurarte de que el HPA se amplíe correctamente.
    • En el caso de las cargas de trabajo sensibles al rendimiento, escala en función del tamaño de la cola (por ejemplo, vllm:num_requests_waiting). Esta métrica mide directamente el trabajo pendiente y es una forma sencilla de adaptar la capacidad de procesamiento a la demanda entrante. Como esta métrica solo tiene en cuenta las solicitudes que están en espera y no las que se están procesando, es posible que no alcance la latencia más baja posible en comparación con el escalado en función del tamaño del lote.

  • Define un número mínimo de réplicas: para asegurar una disponibilidad constante y una experiencia de usuario básica, define siempre un número mínimo de réplicas para tu implementación de inferencia.

  • Habilita el perfil de HPA de rendimiento: en las versiones 1.33 o posteriores de GKE, el perfil de HPA de rendimiento está habilitado de forma predeterminada en los clústeres aptos para mejorar el tiempo de reacción de HPA.

Para obtener más información, consulta Configurar HPA para cargas de trabajo de LLM en GPUs y Escalar automáticamente cargas de trabajo de inferencia de LLM en TPUs.

Mueve los datos a una ubicación más cercana a tus cargas de trabajo

El tiempo que tardan tus cargas de trabajo en cargar datos, como los pesos del modelo, puede ser una fuente importante de latencia. Si traslada sus datos a una ubicación más cercana a sus recursos de computación, puede reducir los tiempos de transferencia de datos y mejorar el rendimiento general.

  • Crea cachés de lectura zonales con Anywhere Cache: si usas Cloud Storage para almacenar datos de tus cargas de trabajo de IA o aprendizaje automático, habilita Anywhere Cache. Anywhere Cache crea cachés de lectura zonales de alto rendimiento para tus segmentos de Cloud Storage.
  • Almacena en caché los datos a los que se accede con frecuencia en SSD locales: en cargas de trabajo que requieren un acceso de latencia extremadamente baja a datos temporales, usa SSD locales como caché de alto rendimiento. Usar SSDs locales como almacenamiento temporal de baja latencia para almacenar datos que se usan con frecuencia te ayuda a reducir el tiempo de inactividad de recursos caros, como los aceleradores, ya que se reduce drásticamente el tiempo que los aceleradores esperan a que se completen las operaciones de E/S. Ten en cuenta que no todas las series de máquinas admiten SSDs locales, lo que puede influir en tu elección de aceleradores.
  • Gestionar cachés con GKE Data Cache: en cargas de trabajo que leen datos de discos persistentes con frecuencia, habilita GKE Data Cache. GKE Data Cache usa SSDs locales para crear una caché gestionada de alto rendimiento para tus discos persistentes. En la mayoría de las cargas de trabajo de producción, recomendamos usar el modo Writethrough para evitar la pérdida de datos escribiendo datos de forma síncrona tanto en la caché como en el disco persistente subyacente.

Optimizar para arquitecturas de escalado avanzadas

Para satisfacer las demandas de las aplicaciones a gran escala o distribuidas a nivel mundial, puedes adoptar arquitecturas de escalado avanzadas para mejorar el rendimiento, la fiabilidad y la gestión del tráfico.

Balancear la carga del tráfico con GKE Inference Gateway

Para las cargas de trabajo de inferencia en un solo clúster, te recomendamos que uses GKE Inference Gateway. Inference Gateway es un balanceador de carga con reconocimiento de IA que monitoriza las métricas de inferencia para enrutar las solicitudes al endpoint más óptimo. Esta función mejora el rendimiento y el uso de los aceleradores.

Cuando uses GKE Inference Gateway, te recomendamos que sigas estas prácticas recomendadas:

  • Agrupa los pods de servicio en un InferencePool: define un InferencePool para cada grupo de pods que sirvan tus cargas de trabajo de inferencia. Para obtener más información, consulta Personalizar la configuración de GKE Inference Gateway.
  • Multiplexar cargas de trabajo críticas para la latencia: define InferenceObjectives para especificar las propiedades de servicio de tu modelo, como su nombre y prioridad. GKE Inference Gateway da prioridad a las cargas de trabajo con una prioridad más alta, lo que te permite multiplexar cargas de trabajo sensibles a la latencia y tolerantes a la latencia, así como implementar políticas de reducción de carga durante periodos de tráfico intenso.
  • Usar el enrutamiento en función del modelo: para enrutar las solicitudes en función del nombre del modelo en el cuerpo de la solicitud, usa el enrutamiento basado en el cuerpo. Cuando uses el enrutamiento basado en el cuerpo, asegúrate de que tus backends tengan una alta disponibilidad. La pasarela devolverá un error si la extensión no está disponible, lo que evitará que las solicitudes se enruten incorrectamente.
  • Permitir que la pasarela distribuya el tráfico automáticamente: GKE Inference Gateway enruta el tráfico de forma inteligente monitorizando métricas clave de los servidores de inferencia del InferencePool, como la utilización de la caché de valores clave, la longitud de la cola y los índices de la caché de prefijos. Este balanceo de carga en tiempo real optimiza el uso del acelerador, reduce la latencia de cola y aumenta el rendimiento general en comparación con los métodos tradicionales.
  • Integración con Apigee y Model Armor: para mejorar la seguridad y la gestión, integra Apigee para gestionar las APIs y Model Armor para realizar comprobaciones de seguridad.

Desplegar cargas de trabajo de inferencia en varios nodos

En el caso de los modelos muy grandes que no caben en un solo nodo, debes distribuir la carga de trabajo de inferencia en varios nodos. Para ello, se necesita una arquitectura que minimice la latencia de comunicación entre nodos y asegure que todos los componentes de la carga de trabajo distribuida se gestionen como una sola unidad.

Te recomendamos que sigas estas prácticas recomendadas:

  • Maximizar el ancho de banda y el rendimiento de la red de aceleradores: cuando una carga de trabajo se distribuye en varios nodos, la red se convierte en un factor de rendimiento crucial. Para minimizar la latencia de comunicación entre nodos, usa tecnologías de redes de alto rendimiento, como NVIDIA GPUDirect. En función de la escala de tu clúster y de la intensidad de la comunicación que requiera tu carga de trabajo, puedes elegir entre estas opciones:

    • GPUDirect-TCPX: eficaz para una serie de cargas de trabajo de inferencia multinodo que se ejecutan en A3 High.
    • GPUDirect-TCPXO: ofrece un rendimiento mejorado con una mayor descarga y un mayor ancho de banda, lo que resulta útil para clústeres más grandes en comparación con TCPX estándar. Se ejecuta en máquinas A3 Mega.
    • GPUDirect RDMA: proporciona el mayor ancho de banda entre nodos y la latencia más baja, ya que permite el acceso directo a la memoria entre GPUs de diferentes nodos, sin pasar por la CPU. Es la opción más adecuada para los escenarios de inferencia a gran escala más exigentes en máquinas A3 Ultra y A4.

    Para obtener más información, consulta estos artículos:

    Para validar que la configuración de tu red multinodo funciona como se espera, te recomendamos que realices pruebas con herramientas como la biblioteca de comunicaciones colectivas de NVIDIA (NCCL).

  • Usa LeaderWorkerSet para gestionar cargas de trabajo distribuidas: cuando implementas una carga de trabajo distribuida con estado, como un servicio de inferencia de varios nodos, es fundamental gestionar todos sus componentes como una sola unidad. Para ello, usa LeaderWorkerSet, una API nativa de Kubernetes que te permite gestionar un grupo de pods relacionados como una sola entidad. Un LeaderWorkerSet asegura que todos los pods del conjunto se creen y se eliminen juntos, lo cual es fundamental para mantener la integridad de una carga de trabajo distribuida.

  • Coloca los nodos cerca unos de otros mediante la colocación compacta: la distancia física entre los nodos de tu carga de trabajo distribuida puede influir significativamente en la latencia de la red entre nodos. Para minimizar esta latencia, usa una política de emplazamiento compacta para tus grupos de nodos de GKE. Una política de colocación compacta indica a GKE que coloque los nodos de un grupo de nodos lo más cerca posible entre sí dentro de una zona.

Desplegar cargas de trabajo de inferencia en varias regiones

En el caso de las aplicaciones distribuidas a nivel mundial que requieren alta disponibilidad y baja latencia, es fundamental desplegar las cargas de trabajo de inferencia en varias regiones. Una arquitectura multirregión puede ayudarte a aumentar la fiabilidad, mejorar la disponibilidad de los aceleradores, reducir la latencia percibida por los usuarios y cumplir los requisitos normativos específicos de cada ubicación.

Para desplegar y gestionar de forma eficaz un servicio de inferencia multirregional, siga estas recomendaciones:

  • Aprovisiona clústeres de GKE en varias regiones en las que tengas capacidad reservada o preveas que vas a necesitar capacidad para gestionar las cargas máximas.
  • Elige la estrategia de almacenamiento adecuada para los pesos de tu modelo. Para optimizar la eficiencia operativa, crea un segmento de Cloud Storage multirregional. Para optimizar los costes, crea un segmento regional en cada región y replica los pesos de tu modelo.
  • Usa Anywhere Cache para crear cachés de lectura zonales en tus segmentos de Cloud Storage y reducir tanto la latencia de red como los costes de salida de datos.

Resumen de las prácticas recomendadas

En la siguiente tabla se resumen las prácticas recomendadas que se indican en este documento:

Tema Tarea
Implementación y configuración
  • Analizar las características de tu caso práctico de inferencia
  • Elegir los modelos adecuados para tus casos prácticos de inferencia
  • Aplicar cuantización al modelo
  • Elige los aceleradores adecuados
  • Elige tu estrategia de distribución de inferencias
  • Optimizar la configuración del servidor de inferencia
Latencia de arranque en frío
  • Optimizar el tiempo de inicio de Pod
  • Habilitar nodos de inicio rápido
Planificación de la capacidad y disponibilidad de aceleradores
  • Planificar y reservar capacidad
  • Usar Dynamic Workload Scheduler
  • Usar clases de computación personalizadas
  • Configurar la política de ubicación de los clústeres y grupos de nodos de GKE
Eficiencia de recursos y aceleradores
  • Monitorizar los aceleradores y los servidores de inferencia
  • Escalar automáticamente tus pods
  • Acerca los datos a tus cargas de trabajo
Balanceo de carga
  • Usar GKE Inference Gateway para implementaciones de un solo clúster
Despliegues de varios nodos
  • Maximizar el ancho de banda y el rendimiento de la red de aceleradores
  • Usar LeaderWorkerSet para agrupar pods
  • Colocar nodos en proximidad física mediante la colocación compacta
Despliegues multirregionales
  • Aprovisionar clústeres de GKE en varias regiones
  • Equilibrar la carga del tráfico entre regiones
  • Almacenar los pesos del modelo en segmentos de Cloud Storage
  • Almacenar datos en caché con Anywhere Cache

Siguientes pasos