En esta página se muestra cómo configurar tu infraestructura de autoescalado mediante el autoescalador horizontal de pods (HPA) de GKE para desplegar el modelo de lenguaje extenso (LLM) Gemma con JetStream de un solo host.
Para obtener más información sobre cómo seleccionar métricas para el autoescalado, consulta Prácticas recomendadas para autoescalar cargas de trabajo de LLMs con TPUs en GKE.
Antes de empezar
Antes de empezar, asegúrate de que has realizado las siguientes tareas:
- Habilita la API de Google Kubernetes Engine. Habilitar la API de Google Kubernetes Engine
- Si quieres usar Google Cloud CLI para esta tarea, instálala y, a continuación, inicialízala. Si ya has instalado la gcloud CLI, obtén la versión más reciente ejecutando
gcloud components update
.
- Familiarízate con el flujo de trabajo y complétalo en Sirve Gemma mediante TPUs en GKE con JetStream. Asegúrate de que el argumento PROMETHEUS_PORT esté definido en el manifiesto de implementación de JetStream.
Autoescalar con métricas
Puedes usar las métricas de rendimiento específicas de la carga de trabajo que emite el servidor de inferencia de JetStream o las métricas de rendimiento de TPU para dirigir el autoescalado de tus pods.
Para configurar el escalado automático con métricas, sigue estos pasos:
Exporta las métricas del servidor JetStream a Cloud Monitoring. Usas Managed Service para Prometheus de Google Cloud, que simplifica el despliegue y la configuración de tu recopilador de Prometheus. Google Cloud Managed Service para Prometheus está habilitado de forma predeterminada en tu clúster de GKE. También puedes habilitarlo manualmente.
En el siguiente manifiesto de ejemplo se muestra cómo configurar las definiciones de recursos PodMonitoring para dirigir Google Cloud Managed Service para Prometheus a que obtenga métricas de tus pods a intervalos recurrentes de 15 segundos:
Si necesitas raspar métricas del servidor, usa el siguiente manifiesto. Con las métricas de servidor, se admiten intervalos de raspado de hasta 5 segundos.
apiVersion: monitoring.googleapis.com/v1 kind: PodMonitoring metadata: name: jetstream-podmonitoring spec: selector: matchLabels: app: maxengine-server endpoints: - interval: 15s path: "/" port: PROMETHEUS_PORT targetLabels: metadata: - pod - container - node
Si necesitas raspar métricas de TPU, usa el siguiente manifiesto. Con las métricas del sistema, se admiten intervalos de raspado de hasta 15 segundos.
apiVersion: monitoring.googleapis.com/v1 kind: PodMonitoring metadata: name: tpu-metrics-exporter namespace: kube-system labels: k8s-app: tpu-device-plugin spec: endpoints: - port: 2112 interval: 15s selector: matchLabels: k8s-app: tpu-device-plugin
Instala un adaptador de métricas. Este adaptador hace que las métricas del servidor que has exportado a Monitoring sean visibles para el controlador de HPA. Para obtener más información, consulta Escalado automático horizontal de pods en la documentación de Google Cloud Managed Service para Prometheus.
- Si quieres que JetStream se ajuste a las métricas individuales, usa el adaptador de métricas personalizadas de Stackdriver.
- Si quieres que JetStream se ajuste a la escala del valor de una expresión compuesta por varias métricas distintas, usa el adaptador de Prometheus de terceros.
Adaptador de métricas personalizadas de Stackdriver
El adaptador de Stackdriver para métricas personalizadas admite consultas de métricas de Google Cloud Managed Service para Prometheus a partir de la versión 0.13.1 del adaptador.
Para instalar el adaptador de métricas personalizadas de Stackdriver, siga estos pasos:
Configure la recogida gestionada en su clúster.
Instala el adaptador de métricas personalizadas de Stackdriver en tu clúster.
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml
Si tienes habilitada la federación de Workload Identity para GKE en tu clúster de Kubernetes y la usas, también debes conceder el rol Lector de Monitoring a la cuenta de servicio con la que se ejecuta el adaptador. Sustituye
PROJECT_ID
por el ID de tu proyecto.
export PROJECT_NUMBER=$(gcloud projects describe PROJECT_ID --format 'get(projectNumber)') gcloud projects add-iam-policy-binding projects/PROJECT_ID \ --role roles/monitoring.viewer \ --member=principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/custom-metrics/sa/custom-metrics-stackdriver-adapter
Adaptador de Prometheus
Ten en cuenta estas consideraciones al usar
prometheus-adapter
para escalar con Google Cloud Managed Service para Prometheus:- Encamina las consultas a través del proxy de la interfaz de usuario de frontend de Prometheus, al igual que cuando consultas Google Cloud Managed Service para Prometheus con la API o la interfaz de usuario de Prometheus. Este frontend se instala en un paso posterior.
- De forma predeterminada, el argumento
prometheus-url
deprometheus-adapter
Deployment se define como--prometheus-url=http://frontend.default.svc:9090/
, dondedefault
es el espacio de nombres en el que has implementado el frontend. Si has implementado el frontend en otro espacio de nombres, configura este argumento en consecuencia. - En el campo
.seriesQuery
de la configuración de las reglas, no puede usar un comparador de expresiones regulares (regex) en un nombre de métrica. En su lugar, especifique los nombres de las métricas por completo.
Como los datos pueden tardar un poco más en estar disponibles en Google Cloud Managed Service para Prometheus que en el Prometheus upstream, configurar una lógica de escalado automático demasiado ambiciosa puede provocar un comportamiento no deseado. Aunque no se garantiza la actualización de los datos, normalmente se pueden consultar entre 3 y 7 segundos después de enviarlos a Google Cloud Managed Service para Prometheus, sin incluir la latencia de la red.
Todas las consultas emitidas por
prometheus-adapter
tienen un ámbito global. Esto significa que, si tienes aplicaciones en dos espacios de nombres que emiten métricas con el mismo nombre, una configuración de HPA que use esa métrica se escalará usando datos de ambas aplicaciones. Para evitar que se escale con datos incorrectos, utilice siempre los filtrosnamespace
ocluster
en PromQL.Para configurar un ejemplo de HPA con
prometheus-adapter
y la recogida gestionada, sigue estos pasos:- Configure la recogida gestionada en su clúster.
Despliega el proxy de la interfaz de usuario de frontend de Prometheus en tu clúster. Crea el siguiente archivo de manifiesto llamado
prometheus-frontend.yaml
:apiVersion: apps/v1 kind: Deployment metadata: name: frontend spec: replicas: 2 selector: matchLabels: app: frontend template: metadata: labels: app: frontend spec: automountServiceAccountToken: true affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/arch operator: In values: - arm64 - amd64 - key: kubernetes.io/os operator: In values: - linux containers: - name: frontend image: gke.gcr.io/prometheus-engine/frontend:v0.8.0-gke.4 args: - "--web.listen-address=:9090" - "--query.project-id=PROJECT_ID" ports: - name: web containerPort: 9090 readinessProbe: httpGet: path: /-/ready port: web securityContext: allowPrivilegeEscalation: false capabilities: drop: - all privileged: false runAsGroup: 1000 runAsNonRoot: true runAsUser: 1000 livenessProbe: httpGet: path: /-/healthy port: web --- apiVersion: v1 kind: Service metadata: name: prometheus spec: clusterIP: None selector: app: frontend ports: - name: web port: 9090
A continuación, aplica el manifiesto:
kubectl apply -f prometheus-frontend.yaml
Asegúrate de que
prometheus-adapter
esté instalado en tu clúster instalando el gráfico de Helmprometheus-community/prometheus-adapter
. Crea el siguiente archivovalues.yaml
:rules: default: false external: - seriesQuery: 'jetstream_prefill_backlog_size' resources: template: <<.Resource>> name: matches: "" as: "jetstream_prefill_backlog_size" metricsQuery: avg(<<.Series>>{<<.LabelMatchers>>,cluster="CLUSTER_NAME"}) - seriesQuery: 'jetstream_slots_used_percentage' resources: template: <<.Resource>> name: matches: "" as: "jetstream_slots_used_percentage" metricsQuery: avg(<<.Series>>{<<.LabelMatchers>>,cluster="CLUSTER_NAME"}) - seriesQuery: 'memory_used' resources: template: <<.Resource>> name: matches: "" as: "memory_used_percentage" metricsQuery: avg(memory_used{cluster="CLUSTER_NAME",exported_namespace="default",container="jetstream-http"}) / avg(memory_total{cluster="CLUSTER_NAME",exported_namespace="default",container="jetstream-http"})
A continuación, usa este archivo como archivo de valores para implementar tu gráfico de Helm:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts && helm repo update && helm install example-release prometheus-community/prometheus-adapter -f values.yaml
Si usas Workload Identity Federation para GKE, también debes configurar y autorizar una cuenta de servicio ejecutando los siguientes comandos:
Primero, crea tus cuentas de servicio y en el clúster: Trusted Cloud by S3NS
gcloud iam service-accounts create prom-frontend-sa && kubectl create sa prom-frontend-sa
A continuación, vincula las dos cuentas de servicio. No olvides sustituir
PROJECT_ID
por el ID de tu proyecto:gcloud iam service-accounts add-iam-policy-binding \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[default/prom-frontend-sa]" \ jetstream-iam-sa@PROJECT_ID.s3ns-system.iam.gserviceaccount.com \ && kubectl annotate serviceaccount \ --namespace default \ prom-frontend-sa \ iam.gke.io/gcp-service-account=jetstream-iam-sa@PROJECT_ID.s3ns-system.iam.gserviceaccount.com
A continuación, asigna el rol
monitoring.viewer
a la cuenta de servicio: Trusted Cloud by S3NSgcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:jetstream-iam-sa@PROJECT_ID.s3ns-system.iam.gserviceaccount.com \ --role=roles/monitoring.viewer
Por último, define la cuenta de servicio de tus implementaciones de frontend como tu nueva cuenta de servicio en el clúster:
kubectl set serviceaccount deployment frontend prom-frontend-sa
Configura el recurso HPA basado en métricas. Despliega un recurso HPA basado en la métrica de servidor que prefieras. Para obtener más información, consulta Escalado automático horizontal de pods en la documentación de Google Cloud Managed Service para Prometheus. La configuración específica de HPA depende del tipo de métrica (servidor o TPU) y del adaptador de métricas que esté instalado.
Hay algunos valores que son obligatorios en todas las configuraciones de HPA y que se deben definir para crear un recurso de HPA:
- MIN_REPLICAS: número mínimo de réplicas de pods de JetStream permitidas. Si no vas a modificar el manifiesto de implementación de JetStream en el paso Implementar JetStream, te recomendamos que le asignes el valor 1.
- MAX_REPLICAS: número máximo de réplicas de pods de JetStream permitidas. El ejemplo de implementación de JetStream requiere 8 chips por réplica y el pool de nodos contiene 16 chips. Si quieres que la latencia de ampliación siga siendo baja, asigna el valor 2. Cuanto más altos sean los valores, más tiempo tardará la herramienta de adaptación dinámica del clúster en crear nodos en el grupo de nodos, lo que aumentará la latencia de escalado vertical.
TARGET: el promedio objetivo de esta métrica en todas las instancias de JetStream. Consulta la documentación de Kubernetes sobre el autoescalado para obtener más información sobre cómo se determina el número de réplicas a partir de este valor.
Adaptador de métricas personalizadas de Stackdriver
El adaptador de métricas personalizadas de Stackdriver permite escalar tu carga de trabajo con el valor medio de las consultas de métricas individuales de Google Cloud Managed Service para Prometheus en todos los pods. Cuando se usa el adaptador de métricas personalizadas de Stackdriver, recomendamos escalar con las métricas de servidor
jetstream_prefill_backlog_size
yjetstream_slots_used_percentage
, así como con la métrica de TPUmemory_used
.Para crear un manifiesto de HPA para escalar con métricas del servidor, crea el siguiente archivo
hpa.yaml
:apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: jetstream-hpa namespace: default spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: maxengine-server minReplicas: MIN_REPLICAS maxReplicas: MAX_REPLICAS metrics: - type: Pods pods: metric: name: prometheus.googleapis.com|jetstream_METRIC|gauge target: type: AverageValue averageValue: TARGET
Cuando se usa el adaptador de Stackdriver de métricas personalizadas con métricas de TPU, recomendamos usar solo la métrica
kubernetes.io|node|accelerator|memory_used
para el escalado. Para crear un manifiesto de HPA para escalar con esta métrica, cree el siguiente archivohpa.yaml
:apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: jetstream-hpa namespace: default spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: maxengine-server minReplicas: MIN_REPLICAS maxReplicas: MAX_REPLICAS metrics: - type: External external: metric: name: prometheus.googleapis.com|memory_used|gauge selector: matchLabels: metric.labels.container: jetstream-http metric.labels.exported_namespace: default target: type: AverageValue averageValue: TARGET
Adaptador de Prometheus
Prometheus Adapter admite el escalado de tu carga de trabajo con el valor de las consultas de PromQL de Google Cloud Managed Service para Prometheus. Antes, ha definido las métricas de servidor
jetstream_prefill_backlog_size
yjetstream_slots_used_percentage
que representan el valor medio de todos los pods.Para crear un manifiesto de HPA para escalar con métricas del servidor, crea el siguiente archivo
hpa.yaml
:apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: jetstream-hpa namespace: default spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: maxengine-server minReplicas: MIN_REPLICAS maxReplicas: MAX_REPLICAS metrics: - type: External external: metric: name: jetstream_METRIC target: type: AverageValue averageValue: TARGET
Para crear un manifiesto de HPA para escalar con métricas de TPU, te recomendamos que solo uses el
memory_used_percentage
definido en el archivo de valores de Helm de prometheus-adapter.memory_used_percentage
es el nombre que se le ha dado a la siguiente consulta de PromQL, que refleja la media actual de memoria utilizada en todos los aceleradores:avg(kubernetes_io:node_accelerator_memory_used{cluster_name="CLUSTER_NAME"}) / avg(kubernetes_io:node_accelerator_memory_total{cluster_name="CLUSTER_NAME"})
Para crear un manifiesto de HPA para escalar con
memory_used_percentage
, crea el siguiente archivohpa.yaml
:apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: jetstream-hpa namespace: default spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: maxengine-server minReplicas: MIN_REPLICAS maxReplicas: MAX_REPLICAS metrics: - type: External external: metric: name: memory_used_percentage target: type: AverageValue averageValue: TARGET
Escalar con varias métricas
También puedes configurar el escalado en función de varias métricas. Para saber cómo se determina el número de réplicas mediante varias métricas, consulta la documentación de Kubernetes sobre el autoescalado. Para crear este tipo de manifiesto de HPA, recopila todas las entradas del campo spec.metrics
de cada recurso de HPA en un único recurso de HPA. El siguiente fragmento muestra un ejemplo de cómo puedes agrupar los recursos de HPA:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: jetstream-hpa-multiple-metrics
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: maxengine-server
minReplicas: MIN_REPLICAS
maxReplicas: MAX_REPLICAS
metrics:
- type: Pods
pods:
metric:
name: jetstream_METRIC
target:
type: AverageValue
averageValue: JETSTREAM_METRIC_TARGET
- type: External
external:
metric:
name: memory_used_percentage
target:
type: AverageValue
averageValue: EXTERNAL_METRIC_TARGET
Monitorizar y probar el autoescalado
Puedes observar cómo se escalan tus cargas de trabajo de JetStream en función de tu configuración de HPA.
Para observar el número de réplicas en tiempo real, ejecuta el siguiente comando:
kubectl get hpa --watch
El resultado de este comando debería ser similar al siguiente:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
jetstream-hpa Deployment/maxengine-server 0/10 (avg) 1 2 1 1m
Para probar la capacidad de escalado de tu HPA, usa el siguiente comando, que envía una ráfaga de 100 solicitudes al endpoint del modelo. De esta forma, se agotarán los espacios de decodificación disponibles y se producirá un retraso en la cola de relleno previo, lo que hará que HPA aumente el tamaño de la implementación del modelo.
seq 100 | xargs -P 100 -n 1 curl --request POST --header "Content-type: application/json" -s localhost:8000/generate --data '{ "prompt": "Can you provide a comprehensive and detailed overview of the history and development of artificial intelligence.", "max_tokens": 200 }'
Siguientes pasos
- Consulta cómo optimizar el ajuste de escala automático de pods en función de las métricas de Cloud Monitoring.
- Consulta más información sobre el autoescalado de pods horizontal en la documentación de Kubernetes de código abierto.