En este instructivo, se muestra cómo entregar un modelo grande de lenguaje (LLM) con GPU en Google Kubernetes Engine (GKE). En este instructivo, se crea un clúster de GKE que usa varias GPU L4 y prepara la infraestructura de GKE para entregar cualquiera de los siguientes modelos:
Según el formato de datos del modelo, la cantidad de GPU varía. En este instructivo, cada modelo usa dos GPU L4. Para obtener más información, consulta Calcula la cantidad de GPU.
Antes de completar este instructivo en GKE, te recomendamos que aprendas Información sobre las GPU en GKE
Objetivos
Este instructivo está dirigido a administradores de plataforma o ingenieros de MLOps o DevOps que deseen usar las funciones de organización de GKE para entregar LLM.
En este instructivo, se abarcan los siguientes pasos:
- Crea un clúster y grupos de nodos.
- Prepara tu carga de trabajo.
- Implementa tu carga de trabajo.
- Interactúa con la interfaz de LLM.
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 gcloud CLI, ejecuta
gcloud components update
para obtener la versión más reciente.
Algunos modelos tienen requisitos adicionales. Asegúrate de cumplir con los siguientes requisitos:
- Para acceder a los modelos de Hugging Face, usa un token de HuggingFace.
- Para el modelo Mixtral 8x7b: acepta las condiciones del modelo Mistral Mixtral.
- En el caso del modelo Llama 3 70b, asegúrate de tener una licencia activa para los modelos de Meta Llama.
Prepare el entorno
En la consola de Google Cloud, inicia una instancia de Cloud Shell:
Abrir Cloud ShellConfigura las variables de entorno predeterminadas:
gcloud config set project PROJECT_ID export PROJECT_ID=$(gcloud config get project) export REGION=us-central1
Reemplaza PROJECT_ID por el ID del proyecto de Google Cloud.
Crea un clúster de GKE y un grupo de nodos
Puedes entregar LLM en GPU en un clúster de GKE Autopilot o Standard. Te recomendamos que uses un clúster de Autopilot para una experiencia de Kubernetes completamente administrada. Para elegir el modo de operación de GKE que se adapte mejor a tus cargas de trabajo, consulta Elige un modo de operación de GKE.
Autopilot
En Cloud Shell, ejecuta el siguiente comando:
gcloud container clusters create-auto l4-demo \ --project=${PROJECT_ID} \ --region=${REGION} \ --release-channel=rapid
GKE crea un clúster de Autopilot con nodos de CPU y GPU según lo solicitan las cargas de trabajo implementadas.
Configura
kubectl
para comunicarse con tu clúster:gcloud container clusters get-credentials l4-demo --region=${REGION}
Estándar
En Cloud Shell, ejecuta el siguiente comando para crear un clúster estándar que use la federación de identidades para cargas de trabajo para GKE:
gcloud container clusters create l4-demo --location ${REGION} \ --workload-pool ${PROJECT_ID}.svc.id.goog \ --enable-image-streaming \ --node-locations=$REGION-a \ --workload-pool=${PROJECT_ID}.svc.id.goog \ --machine-type n2d-standard-4 \ --num-nodes 1 --min-nodes 1 --max-nodes 5 \ --release-channel=rapid
La creación del clúster puede tomar varios minutos.
Ejecuta el siguiente comando para crear un grupo de nodos para el clúster:
gcloud container node-pools create g2-standard-24 --cluster l4-demo \ --accelerator type=nvidia-l4,count=2,gpu-driver-version=latest \ --machine-type g2-standard-24 \ --enable-autoscaling --enable-image-streaming \ --num-nodes=0 --min-nodes=0 --max-nodes=3 \ --node-locations $REGION-a,$REGION-c --region $REGION --spot
GKE crea los siguientes recursos para el LLM:
- Un clúster público de Google Kubernetes Engine (GKE) de edición Standard
- Un grupo de nodos con el tipo de máquina
g2-standard-24
en el que se redujo la escala verticalmente a 0 nodos. No se te cobrará por ninguna GPU hasta que inicies Pods que soliciten GPU. Este grupo de nodos aprovisiona VMs Spot, que tienen un precio menor que las VMs estándar de Compute Engine predeterminadas y no proporcionan garantía de disponibilidad. Puedes quitar la marca--spot
de este comando y el selector de nodoscloud.google.com/gke-spot
en la configuracióntext-generation-inference.yaml
para usar VMs a pedido.
Configura
kubectl
para comunicarse con tu clúster:gcloud container clusters get-credentials l4-demo --region=${REGION}
Prepara tu carga de trabajo
En la siguiente sección, se muestra cómo configurar la carga de trabajo según el modelo que deseas usar:
Llama 3 70b
Configura las variables de entorno predeterminadas:
export HF_TOKEN=HUGGING_FACE_TOKEN
Reemplaza
HUGGING_FACE_TOKEN
por tu token de HuggingFace.Crea un Secret de Kubernetes para el token de HuggingFace:
kubectl create secret generic l4-demo \ --from-literal=HUGGING_FACE_TOKEN=${HF_TOKEN} \ --dry-run=client -o yaml | kubectl apply -f -
Crea el siguiente manifiesto
text-generation-inference.yaml
:En el manifiesto se muestra lo siguiente:
NUM_SHARD
debe ser2
porque el modelo requiere dos GPU NVIDIA L4.QUANTIZE
se configura comobitsandbytes-nf4
, lo que significa que el modelo se carga en 4 bits en lugar de 32 bits. Esto permite que GKE reduzca la cantidad de memoria de GPU necesaria y mejora la velocidad de inferencia. Sin embargo, la exactitud del modelo puede disminuir. Para aprender a calcular las GPU que se solicitarán, consulta Calcula la cantidad de GPU.
Aplica el manifiesto
kubectl apply -f text-generation-inference.yaml
El resultado es similar al siguiente:
deployment.apps/llm created
Verifica el estado del modelo:
kubectl get deploy
El resultado es similar al siguiente:
NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 20m
Observa los registros de la implementación en ejecución:
kubectl logs -l app=llm
El resultado es similar al siguiente:
{"timestamp":"2024-03-09T05:08:14.751646Z","level":"INFO","message":"Warming up model","target":"text_generation_router","filename":"router/src/main.rs","line_number":291} {"timestamp":"2024-03-09T05:08:19.961136Z","level":"INFO","message":"Setting max batch total tokens to 133696","target":"text_generation_router","filename":"router/src/main.rs","line_number":328} {"timestamp":"2024-03-09T05:08:19.961164Z","level":"INFO","message":"Connected","target":"text_generation_router","filename":"router/src/main.rs","line_number":329} {"timestamp":"2024-03-09T05:08:19.961171Z","level":"WARN","message":"Invalid hostname, defaulting to 0.0.0.0","target":"text_generation_router","filename":"router/src/main.rs","line_number":343}
Mixtral 8x7b
Configura las variables de entorno predeterminadas:
export HF_TOKEN=HUGGING_FACE_TOKEN
Reemplaza
HUGGING_FACE_TOKEN
por tu token de HuggingFace.Crea un Secret de Kubernetes para el token de HuggingFace:
kubectl create secret generic l4-demo \ --from-literal=HUGGING_FACE_TOKEN=${HF_TOKEN} \ --dry-run=client -o yaml | kubectl apply -f -
Crea el siguiente manifiesto
text-generation-inference.yaml
:En el manifiesto se muestra lo siguiente:
NUM_SHARD
debe ser2
porque el modelo requiere dos GPU NVIDIA L4.QUANTIZE
se configura comobitsandbytes-nf4
, lo que significa que el modelo se carga en 4 bits en lugar de 32 bits. Esto permite que GKE reduzca la cantidad de memoria de GPU necesaria y mejora la velocidad de inferencia. Sin embargo, esto puede reducir la exactitud del modelo. Para aprender a calcular las GPU que se solicitarán, consulta Calcula la cantidad de GPU.
Aplica el manifiesto
kubectl apply -f text-generation-inference.yaml
El resultado es similar al siguiente:
deployment.apps/llm created
Verifica el estado del modelo:
watch kubectl get deploy
El resultado es similar al siguiente cuando la implementación está lista. Para salir de la visualización, escribe
CTRL + C
:NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 10m
Observa los registros de la implementación en ejecución:
kubectl logs -l app=llm
El resultado es similar al siguiente:
{"timestamp":"2024-03-09T05:08:14.751646Z","level":"INFO","message":"Warming up model","target":"text_generation_router","filename":"router/src/main.rs","line_number":291} {"timestamp":"2024-03-09T05:08:19.961136Z","level":"INFO","message":"Setting max batch total tokens to 133696","target":"text_generation_router","filename":"router/src/main.rs","line_number":328} {"timestamp":"2024-03-09T05:08:19.961164Z","level":"INFO","message":"Connected","target":"text_generation_router","filename":"router/src/main.rs","line_number":329} {"timestamp":"2024-03-09T05:08:19.961171Z","level":"WARN","message":"Invalid hostname, defaulting to 0.0.0.0","target":"text_generation_router","filename":"router/src/main.rs","line_number":343}
Falcon 40b
Crea el siguiente manifiesto
text-generation-inference.yaml
:En el manifiesto se muestra lo siguiente:
NUM_SHARD
debe ser2
porque el modelo requiere dos GPU NVIDIA L4.QUANTIZE
se configura comobitsandbytes-nf4
, lo que significa que el modelo se carga en 4 bits en lugar de 32 bits. Esto permite que GKE reduzca la cantidad de memoria de GPU necesaria y mejora la velocidad de inferencia. Sin embargo, la exactitud del modelo puede disminuir. Para aprender a calcular las GPU que se solicitarán, consulta Calcula la cantidad de GPU.
Aplica el manifiesto
kubectl apply -f text-generation-inference.yaml
El resultado es similar al siguiente:
deployment.apps/llm created
Verifica el estado del modelo:
watch kubectl get deploy
El resultado es similar al siguiente cuando la implementación está lista. Para salir de la visualización, escribe
CTRL + C
:NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 10m
Observa los registros de la implementación en ejecución:
kubectl logs -l app=llm
El resultado es similar al siguiente:
{"timestamp":"2024-03-09T05:08:14.751646Z","level":"INFO","message":"Warming up model","target":"text_generation_router","filename":"router/src/main.rs","line_number":291} {"timestamp":"2024-03-09T05:08:19.961136Z","level":"INFO","message":"Setting max batch total tokens to 133696","target":"text_generation_router","filename":"router/src/main.rs","line_number":328} {"timestamp":"2024-03-09T05:08:19.961164Z","level":"INFO","message":"Connected","target":"text_generation_router","filename":"router/src/main.rs","line_number":329} {"timestamp":"2024-03-09T05:08:19.961171Z","level":"WARN","message":"Invalid hostname, defaulting to 0.0.0.0","target":"text_generation_router","filename":"router/src/main.rs","line_number":343}
Crea un Service de tipo ClusterIP
Crea el siguiente manifiesto
llm-service.yaml
:apiVersion: v1 kind: Service metadata: name: llm-service spec: selector: app: llm type: ClusterIP ports: - protocol: TCP port: 80 targetPort: 8080
Aplica el manifiesto
kubectl apply -f llm-service.yaml
Implementa una interfaz de chat
Usa Gradio para crear una aplicación web que te permita interactuar con el modelo. Gradio es una biblioteca de Python que tiene un wrapper de ChatInterface que crea interfaces de usuario para chatbots.
Llama 3 70b
Crea un archivo llamado
gradio.yaml
:Aplica el manifiesto
kubectl apply -f gradio.yaml
Busca la dirección IP externa del Service:
kubectl get svc
El resultado es similar al siguiente:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gradio-service LoadBalancer 10.24.29.197 34.172.115.35 80:30952/TCP 125m
Copia la dirección IP externa de la columna
EXTERNAL-IP
.Para ver la interfaz del modelo desde tu navegador web, usa la dirección IP externa con el puerto expuesto:
http://EXTERNAL_IP
Mixtral 8x7b
Crea un archivo llamado
gradio.yaml
:Aplica el manifiesto
kubectl apply -f gradio.yaml
Busca la dirección IP externa del Service:
kubectl get svc
El resultado es similar al siguiente:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gradio-service LoadBalancer 10.24.29.197 34.172.115.35 80:30952/TCP 125m
Copia la dirección IP externa de la columna
EXTERNAL-IP
.Para ver la interfaz del modelo desde tu navegador web, usa la dirección IP externa con el puerto expuesto:
http://EXTERNAL_IP
Falcon 40b
Crea un archivo llamado
gradio.yaml
:Aplica el manifiesto
kubectl apply -f gradio.yaml
Busca la dirección IP externa del Service:
kubectl get svc
El resultado es similar al siguiente:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gradio-service LoadBalancer 10.24.29.197 34.172.115.35 80:30952/TCP 125m
Copia la dirección IP externa de la columna
EXTERNAL-IP
.Para ver la interfaz del modelo desde tu navegador web, usa la dirección IP externa con el puerto expuesto:
http://EXTERNAL_IP
Calcula la cantidad de GPU
La cantidad de GPU depende del valor de la marca QUANTIZE
. En este
instructivo, QUANTIZE
se configura como bitsandbytes-nf4
, lo que significa que el modelo se
carga en 4 bits.
Un modelo de 70,000 millones de parámetros requeriría un mínimo de 40 GB de memoria de GPU, que equivale a 70,000 millones de veces 4 bits (70,000 millones x 4 bits = 35 GB) y considera una sobrecarga de 5 GB. En este caso, una sola GPU L4 no tendría suficiente memoria. Por lo tanto, en los ejemplos de este instructivo, se usan dos GPU L4 de memoria (2 x 24 = 48 GB). Esta configuración es suficiente para ejecutar Falcon 40b o Llama 3 70b en las GPU L4.
Limpia
Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales.
Borre el clúster
Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos que creaste en esta guía, borra el clúster de GKE:
gcloud container clusters delete l4-demo --region ${REGION}