Usa el enrutamiento basado en la latencia prevista con GKE Inference Gateway

En este documento, se describe cómo habilitar y usar el enrutamiento basado en la latencia prevista que proporciona llm-d en la puerta de enlace de inferencia de GKE. De forma predeterminada, GKE Inference Gateway enruta las solicitudes con una combinación de indicadores de carga y heurísticas de afinidad de caché de prefijo. El enrutamiento basado en la latencia prevista reemplaza los pesos heurísticos estáticos por un modelo XGBoost entrenado de forma continua con el tráfico en tiempo real, lo que permite tomar decisiones de enrutamiento más precisas a medida que cambian los patrones de carga de trabajo.

Cuándo usar el enrutamiento basado en la latencia prevista

Esta función es más eficaz cuando se cumplen las siguientes condiciones en tu carga de trabajo:

  • Alta varianza en la longitud de la instrucción y la finalización: La profundidad de la cola por sí sola es un indicador deficiente de la carga del servidor cuando los tamaños de las solicitudes varían significativamente. El predictor de latencia tiene en cuenta el costo real de la decodificación y el prefijo por solicitud.
  • SLO de latencia por solicitud: Cuando tus aplicaciones especifican objetivos de tiempo hasta el primer token (TTFT) o tiempo por token de salida (TPOT) en solicitudes individuales, el programador aplica estos objetivos durante el enrutamiento. Para ello, calcula el margen (latencia prevista menos el objetivo del SLO) de cada Pod candidato.
  • Ajuste de ponderación estática frágil: Si reajustas con frecuencia el equilibrio entre la afinidad de caché y los indicadores de carga a medida que cambian los patrones de tráfico, el modelo entrenado en línea se adapta automáticamente.

Cómo funciona el enrutamiento basado en la latencia prevista

En esta sección, se detallan la arquitectura y la canalización de programación que utiliza el enrutamiento basado en la latencia prevista.

Arquitectura

La programación basada en la latencia prevista implementa dos contenedores sidecar adicionales dentro del Pod de EPP, junto con el propio EPP:

Componente Descripción
Servidor de entrenamiento Vuelve a entrenar continuamente los modelos de XGBoost TTFT y TPOT con las muestras de solicitudes completadas que se reciben del EPP. Utiliza la discretización estratificada en una ventana deslizante para que no se olviden los regímenes de tráfico poco frecuentes. Escribe modelos actualizados en un volumen compartido.
Servidores de predicción Publica predicciones de TTFT y TPOT en la ruta de acceso activa de la solicitud al EPP. Lee el modelo entrenado más reciente del volumen compartido. Escalable horizontalmente: Cada instancia del servidor admite aproximadamente 300 QPS de trabajo de predicción. Un proxy de coalescencia de Go en el EPP balancea la carga de varias instancias, lo que agrupa las solicitudes de predicción simultáneas en un período de 1 ms.

Canalización de programación de EPP de llm-d

Cuando se habilita la programación basada en la latencia prevista, el EPP procesa cada solicitud a través de la siguiente secuencia de complementos componibles:

  1. predicted-latency-producer: Llama al servidor de predicción para obtener estimaciones del TTFT y el TPOT para cada Pod candidato en InferencePool, según el uso actual de la caché de KV, la profundidad de la cola, la puntuación de coincidencia de la caché de prefijo y las características de la solicitud entrante de cada Pod. Después de que se devuelve la respuesta al cliente, el productor envía el TTFT observado y la latencia entre tokens al servidor de entrenamiento como una nueva muestra de entrenamiento.

    • Comportamiento de respaldo: Si no se puede acceder al servidor de predicción o este devuelve un error, el EPP recurre automáticamente a una puntuación compuesta basada en la utilización de la caché de KV, la profundidad de la cola y la coincidencia de la caché de prefijos.
  2. prefix-cache-affinity-filter: Este filtro reduce el conjunto de candidatos a Pods con caché activa cuando la puntuación de coincidencia de caché de prefijo de cualquier Pod supera el umbral de afinidad (el valor predeterminado es 0.80). Este umbral separa dos poblaciones observadas en producción: los Pods que ya tienen un historial de conversación almacenado en caché de turnos anteriores y los Pods que no lo tienen. Este filtro implementa una estrategia de exploración y explotación epsilon-greedy:

    • Aprovechamiento (ruta predeterminada): Esta ruta dirige a los Pods de caché activa para que la puntuación concentre la reutilización de la caché en ellos.

    • Explorar (probabilidad baja): Esta ruta omite el filtro por completo en una fracción configurable de solicitudes para propagar entradas de caché en Pods fríos y evitar la fragmentación de la caché.

    • Cierre de carga del TTFT: Incluso en la ruta de explotación, si el TTFT previsto de los mejores Pods con caché activa supera el TTFT del mejor Pod general en más de un umbral configurable (el valor predeterminado es de 5,000 ms), se interrumpe la afinidad y se usa el conjunto completo de candidatos.

  3. slo-headroom-tier-filter (solo solicitudes de SLO): Cuando la solicitud incluye encabezados de SLO, divide los Pods candidatos en un nivel positivo (se predice que cumplirá con el SLO) y un nivel negativo (se predice que lo incumplirá).

  4. latency-scorer: Puntúa los Pods candidatos. Sin encabezados de SLO, se selecciona el Pod con la latencia prevista más baja. Con los encabezados de SLO, la puntuación se basa en el margen (SLO menos la latencia prevista) con la siguiente fórmula: headroomSelectionStrategy:

    • least (predeterminado): Bin-pack. Se dirige al Pod con el margen positivo más pequeño, lo que maximiza la utilización y mantiene los Pods menos cargados disponibles para futuros aumentos repentinos del tráfico.
    • most: Dispersión. Enruta al Pod con la mayor capacidad positiva, lo que deja más margen para los aumentos inesperados de carga.
  5. latency-slo-admitter (solo solicitudes de SLO): Rechaza las solicitudes descartables (la prioridad es inferior a 0) cuando no se predice que ningún Pod candidato cumpla con el SLO, en lugar de consumir capacidad en una solicitud que se predice que no alcanzará su objetivo. Este filtro no tiene efecto cuando no hay encabezados de SLO o cuando existe un Pod que cumple con el SLO.

  6. weighted-random-picker: Selecciona el Pod final con una selección aleatoria ponderada sobre las puntuaciones. Esto distribuye la carga y, al mismo tiempo, favorece a los Pods con mejor puntuación.

Modo de transmisión

El complemento predicted-latency-producer admite dos modos de entrenamiento, que se configuran con el parámetro streamingMode:

  • streamingMode: false (predeterminado): Se entrena en la latencia de solicitud de extremo a extremo (E2E). Usa este modo si tu carga de trabajo combina respuestas de transmisión y no transmisión, o si solo necesitas un enrutamiento que tenga en cuenta la latencia sin la aplicación del SLO por solicitud.
  • streamingMode: true: Entrena modelos TTFT y TPOT separados. El TTFT se registra en el primer fragmento transmitido, mientras que el TPOT se muestrea en los tokens posteriores. Usa este modo si tu carga de trabajo es completamente de transmisión y necesitas una aplicación de x-slo-ttft-ms / x-slo-tpot-ms significativa.

Antes de comenzar

Antes de comenzar, asegúrate de haber realizado las siguientes tareas:

  • Habilita la API de Google Kubernetes Engine.
  • Habilitar la API de Google Kubernetes Engine
  • Si deseas usar Google Cloud CLI para esta tarea, instala y, luego, inicializa gcloud CLI. Si ya instalaste la gcloud CLI, ejecuta el comando gcloud components update para obtener la versión más reciente. Es posible que las versiones anteriores de gcloud CLI no admitan la ejecución de los comandos que se indican en este documento.
  • Habilita la API de Compute Engine, la API de Network Services y la API de Model Armor si es necesario.

    Ve a Habilita el acceso a las APIs y sigue las instrucciones.

  • Asegúrate de tener una implementación de GKE Inference Gateway que funcione. Consulta Implementa GKE Inference Gateway.

  • Asegúrate de que tu InferencePool use un conjunto homogéneo de Pods, con el mismo tipo de GPU, pesos del modelo y configuración de servicio.

  • Asegúrate de que tu clúster de GKE sea la versión 1.32.3 o posterior.

  • Instala Helm. Consulta la guía de instalación de Helm.

Habilita la programación basada en la latencia prevista

En los siguientes pasos, se explica cómo habilitar la programación basada en la latencia prevista para tu implementación de GKE Inference Gateway.

Paso 1: Instala o actualiza InferencePool con la latencia predicha habilitada

La marca latencyPredictor.enabled=true implementa los sidecars del servidor de entrenamiento y del servidor de predicción dentro del Pod de EPP y conecta la canalización completa del complemento de programación:

helm upgrade --install INFERENCE_POOL_NAME \
  --set inferencePool.modelServers.matchLabels.app=MODEL_SERVER_LABEL \
  --set provider.name=gke \
  --set inferenceExtension.monitoring.gke.enabled=true \
  --set inferenceExtension.latencyPredictor.enabled=true \
  --version LLM_D_VERSION \
  oci://LLM_D_REGISTRY_PATH

Reemplaza lo siguiente:

  • INFERENCE_POOL_NAME: Es el nombre de tu InferencePool, por ejemplo, vllm-llama3-8b-instruct.
  • MODEL_SERVER_LABEL: Es la clave de etiqueta que se usa para seleccionar los Pods del servidor del modelo.
  • LLM_D_VERSION: Es la versión del gráfico de Helm de llm-d que se usará.
  • LLM_D_REGISTRY_PATH: Es la ruta de acceso al registro de OCI de llm-d.

Paso 2: Verifica la implementación

Confirma que el Pod de EPP se esté ejecutando con todos los contenedores secundarios listos:

kubectl get pods -l app=INFERENCE_POOL_NAME-epp

El Pod de EPP debe mostrar todos los contenedores en estado Running o Ready: el EPP en sí, el servidor de entrenamiento y uno o más servidores de predicción.

Paso 3: Envía una solicitud de referencia

Envía una solicitud de inferencia estándar para confirmar que el enrutamiento funciona antes de habilitar los encabezados de SLO:

curl -i -X POST GATEWAY_IP:PORT/v1/completions \
 -H 'Content-Type: application/json' \
 -H 'Authorization: Bearer $(gcloud auth print-access-token)' \
 -H 'x-prediction-based-scheduling: true' \
 -d '{
    "model": "MODEL_NAME",
    "prompt": "PROMPT_TEXT",
    "max_tokens": MAX_TOKENS,
    "temperature": "0"
 }'

Reemplaza lo siguiente:

  • GATEWAY_IP: Es la dirección IP de tu servicio de puerta de enlace.
  • PORT: Es el número de puerto de tu servicio de puerta de enlace.
  • MODEL_NAME: Es el nombre del modelo que se usará para la inferencia.
  • PROMPT_TEXT: Es la instrucción de entrada.
  • MAX_TOKENS: Es la cantidad máxima de tokens que se pueden generar.

El encabezado x-prediction-based-scheduling: true habilita esta solicitud en la canalización de programación de latencia prevista. Durante el período de calentamiento del predictor, el EPP recurre al enrutamiento heurístico.

Paso 4: Envía solicitudes que tengan en cuenta el SLO (opcional)

Para habilitar la aplicación del SLO por solicitud, agrega los encabezados de objetivo de latencia TTFT y TPOT:

curl -i -X POST GATEWAY_IP:PORT/v1/completions \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer $(gcloud auth print-access-token)' \
  -H 'x-prediction-based-scheduling: true' \
  -H 'x-slo-ttft-ms: 500' \
  -H 'x-slo-tpot-ms: 50' \
  -d '{
    "model": "MODEL_NAME",
    "prompt": "PROMPT_TEXT",
    "max_tokens": MAX_TOKENS,
    "temperature": "0",
    "stream": true
  }'

Reemplaza lo siguiente:

  • GATEWAY_IP: Es la dirección IP de tu servicio de puerta de enlace.
  • PORT: Es el número de puerto de tu servicio de puerta de enlace.
  • MODEL_NAME: Es el nombre del modelo que se usará para la inferencia.
  • PROMPT_TEXT: Es la instrucción de entrada.
  • MAX_TOKENS: Es la cantidad máxima de tokens que se pueden generar.

Encabezados de la solicitud:

  • x-prediction-based-scheduling: true: Habilita la solicitud para la canalización de programación de latencia prevista.
  • x-slo-ttft-ms: Es el tiempo hasta el primer token máximo aceptable en milisegundos.
  • x-slo-tpot-ms: Es el tiempo por token de salida máximo aceptable en milisegundos.

Supervisa la programación de la latencia prevista

Cuando el predictor de latencia está habilitado, el EPP expone métricas adicionales a través de Cloud Monitoring.

Métrica Descripción
inference_objective_request_ttft_seconds Es la distribución real del TTFT (o la latencia de E2E si streamingMode=false).
inference_objective_request_predicted_ttft_seconds Es la distribución del TTFT previsto (o la latencia de extremo a extremo si streamingMode=false).
inference_objective_request_tpot_seconds Es la distribución real del TPOT.
inference_objective_request_predicted_tpot_seconds Es la distribución de TPOT predicha.
inference_objective_request_ttft_slo_violation_total Es el contador de incumplimientos del SLO de TTFT.

Cómo escalar el servidor de predicción

El EPP realiza una llamada de predicción por Pod candidato y por solicitud entrante. Cada instancia del servidor de predicción admite aproximadamente 300 QPS de trabajo de predicción.

Orientación aproximada para el recuento de instancias del servidor de predicción:

QPS del clúster (100 Pods) Se requieren servidores de predicción
Hasta 1,000 QPS 1 servidor
Hasta 5,000 QPS 2 servidores
Hasta 10,000 QPS 4 servidores

Actualiza el valor de Helm latencyPredictor.predictionServerCount para agregar instancias del servidor de predicción.

Limitaciones

  • Se requiere InferencePool homogéneo: No se admiten tipos de GPU, variantes de modelos ni configuraciones de entrega mixtos dentro de un solo grupo.
  • Período de calentamiento: El modelo XGBoost requiere suficientes muestras de tráfico en vivo antes de que las predicciones se vuelvan precisas.
  • Aplicación del SLO: La aplicación solo se realiza en la capa de enrutamiento. El servidor del modelo no finaliza las solicitudes que superan el objetivo del SLO después de la selección.
  • Estado: Esta función está en versión preliminar. No se recomienda para cargas de trabajo de producción con requisitos estrictos de ANS sin pruebas exhaustivas.

¿Qué sigue?