En este tutorial se muestra cómo desplegar y servir un modelo de lenguaje grande (LLM) mediante un grupo de nodos de segmento de TPU de varios hosts en Google Kubernetes Engine (GKE) con Saxml para crear una arquitectura escalable y eficiente.
Fondo
Saxml es un sistema experimental que sirve los frameworks Paxml, JAX y PyTorch. Puedes usar las TPUs para acelerar el procesamiento de datos con estos frameworks. Para mostrar la implementación de TPUs en GKE, en este tutorial se usa el modelo de prueba LmCloudSpmd175B32Test de 175 000 millones. GKE despliega este modelo de prueba en dos grupos de nodos de segmentos de TPU v5e con topologías 4x8
respectivamente.
Para desplegar correctamente el modelo de prueba, la topología de la TPU se ha definido en función del tamaño del modelo. Dado que el modelo de N mil millones de 16 bits requiere aproximadamente 2 veces (2 × N) GB de memoria, el modelo 175B LmCloudSpmd175B32Test requiere unos 350 GB de memoria. El chip de TPU único de la versión 5e de TPU tiene 16 GB. Para admitir 350 GB, GKE necesita 21 chips de TPU v5e (350/16= 21). Según la asignación de la configuración de TPU, la configuración de TPU adecuada para este tutorial es la siguiente:
- Tipo de máquina:
ct5lp-hightpu-4t
- Topología:
4x8
(32 chips de TPU)
Seleccionar la topología de TPU adecuada para servir un modelo es importante al desplegar TPUs en GKE. Para obtener más información, consulta Planificar la configuración de las TPU.
Objetivos
Este tutorial está dirigido a ingenieros de MLOps o DevOps, o bien a administradores de plataformas, que quieran usar las funciones de orquestación de GKE para ofrecer modelos de datos.
Este tutorial abarca los siguientes pasos:
- Prepara tu entorno con un clúster de GKE Standard. El clúster tiene dos grupos de nodos de segmentos de TPU v5e con topología
4x8
. - Despliega Saxml. Saxml necesita un servidor de administrador, un grupo de pods que funcionen como servidor de modelo, un servidor HTTP precompilado y un balanceador de carga.
- Usa Saxml para servir el LLM.
En el siguiente diagrama se muestra la arquitectura que se implementa en el siguiente tutorial:
Antes de empezar
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator
(
roles/resourcemanager.projectCreator
), which contains theresourcemanager.projects.create
permission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
Enable the required API.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin
), which contains theserviceusage.services.enable
permission. Learn how to grant roles. -
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator
(
roles/resourcemanager.projectCreator
), which contains theresourcemanager.projects.create
permission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
Enable the required API.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin
), which contains theserviceusage.services.enable
permission. Learn how to grant roles. -
Make sure that you have the following role or roles on the project: roles/container.admin, roles/iam.serviceAccountAdmin, roles/iam.policyAdmin
Check for the roles
-
In the Google Cloud console, go to the IAM page.
Go to IAM - Select the project.
-
In the Principal column, find all rows that identify you or a group that you're included in. To learn which groups you're included in, contact your administrator.
- For all rows that specify or include you, check the Role column to see whether the list of roles includes the required roles.
Grant the roles
-
In the Google Cloud console, go to the IAM page.
Ir a IAM - Selecciona el proyecto.
- Haz clic en Conceder acceso.
-
En el campo Nuevos principales, introduce tu identificador de usuario. Normalmente, se trata de la dirección de correo de una cuenta de Google.
- En la lista Selecciona un rol, elige un rol.
- Para conceder más roles, haz clic en Añadir otro rol y añade cada rol adicional.
- Haz clic en Guardar.
- Asegúrate de que tu proyecto tiene suficiente cuota para usar Cloud TPU en GKE.
En la Google Cloud consola, inicia una instancia de Cloud Shell:
Abrir Cloud ShellDefine las variables de entorno predeterminadas:
gcloud config set project PROJECT_ID export PROJECT_ID=$(gcloud config get project) export CONTROL_PLANE_LOCATION=CONTROL_PLANE_LOCATION export BUCKET_NAME=PROJECT_ID-gke-bucket
Sustituye los siguientes valores:
- PROJECT_ID: tu Google Cloud ID de proyecto.
- CONTROL_PLANE_LOCATION: la zona de Compute Engine del plano de control de tu clúster. Selecciona la zona en la que está disponible
ct5lp-hightpu-4t
.
En este comando,
BUCKET_NAME
especifica el nombre del Google Cloud segmento de almacenamiento en el que se almacenarán las configuraciones del servidor de administrador de Saxml.Crea un clúster estándar que use Workload Identity Federation para GKE:
gcloud container clusters create saxml \ --location=${CONTROL_PLANE_LOCATION} \ --workload-pool=${PROJECT_ID}.svc.id.goog \ --cluster-version=VERSION \ --num-nodes=4
Sustituye
VERSION
por el número de versión de GKE. GKE admite TPU v5e en la versión 1.27.2-gke.2100 y posteriores. Para obtener más información, consulta Disponibilidad de las TPU en GKE.La creación del clúster puede tardar varios minutos.
Crea el primer grupo de nodos llamado
tpu1
:gcloud container node-pools create tpu1 \ --location=${CONTROL_PLANE_LOCATION} \ --machine-type=ct5lp-hightpu-4t \ --tpu-topology=4x8 \ --num-nodes=8 \ --cluster=saxml
El valor de la marca
--num-nodes
se calcula dividiendo la topología de la TPU entre el número de chips de TPU por segmento de TPU. En este caso, sería (4 * 8) / 4.Crea el segundo grupo de nodos llamado
tpu2
:gcloud container node-pools create tpu2 \ --location=${CONTROL_PLANE_LOCATION} \ --machine-type=ct5lp-hightpu-4t \ --tpu-topology=4x8 \ --num-nodes=8 \ --cluster=saxml
El valor de la marca
--num-nodes
se calcula dividiendo la topología de la TPU entre el número de chips de TPU por segmento de TPU. En este caso, sería (4 * 8) / 4.- Un clúster estándar con cuatro nodos de CPU.
- Dos grupos de nodos de segmentos de TPU v5e con topología
4x8
. Cada grupo de nodos representa ocho nodos de segmento de TPU con cuatro chips de TPU cada uno. Configura
kubectl
para que se comunique con tu clúster:gcloud container clusters get-credentials saxml --location=${CONTROL_PLANE_LOCATION}
Crea una cuenta de servicio de Kubernetes para que la use tu aplicación:
kubectl create serviceaccount sax-sa --namespace default
Crea una cuenta de servicio de IAM para tu aplicación:
gcloud iam service-accounts create sax-iam-sa
Añade un enlace de política de gestión de identidades y accesos (IAM) a tu cuenta de servicio de IAM para leer y escribir en Cloud Storage:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member "serviceAccount:sax-iam-sa@${PROJECT_ID}.iam.gserviceaccount.com" \ --role roles/storage.admin
Permite que la cuenta de servicio de Kubernetes suplante la identidad de la cuenta de servicio de gestión de identidades y accesos añadiendo un enlace de política de gestión de identidades y accesos entre las dos cuentas de servicio. Esta vinculación permite que la cuenta de servicio de Kubernetes actúe como la cuenta de servicio de IAM, de modo que la cuenta de servicio de Kubernetes pueda leer y escribir en Cloud Storage.
gcloud iam service-accounts add-iam-policy-binding sax-iam-sa@${PROJECT_ID}.iam.gserviceaccount.com \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:${PROJECT_ID}.svc.id.goog[default/sax-sa]"
Anota la cuenta de servicio de Kubernetes con la dirección de correo de la cuenta de servicio de gestión de identidades y accesos. De esta forma, tu aplicación de muestra sabrá qué cuenta de servicio debe usar para acceder a los servicios de Google Cloud . Por lo tanto, cuando la aplicación usa bibliotecas de cliente de las APIs de Google estándar para acceder a los servicios, usa esa cuenta de servicio de IAM. Google Cloud
kubectl annotate serviceaccount sax-sa \ iam.gke.io/gcp-service-account=sax-iam-sa@${PROJECT_ID}.iam.gserviceaccount.com
Crea el siguiente archivo de manifiesto
sax-admin-server.yaml
:Sustituye
BUCKET_NAME
por el Cloud Storage que has creado anteriormente:perl -pi -e 's|BUCKET_NAME|BUCKET_NAME|g' sax-admin-server.yaml
Aplica el archivo de manifiesto:
kubectl apply -f sax-admin-server.yaml
Comprueba que el pod del servidor de administrador esté en funcionamiento:
kubectl get deployment
El resultado debería ser similar al siguiente:
NAME READY UP-TO-DATE AVAILABLE AGE sax-admin-server 1/1 1 1 52s
Instala JobSet v0.2.3 o una versión posterior.
kubectl apply --server-side -f https://github.com/kubernetes-sigs/jobset/releases/download/JOBSET_VERSION/manifests.yaml
Sustituye
JOBSET_VERSION
por la versión de JobSet. Por ejemplo,v0.2.3
.Valida que el controlador JobSet se esté ejecutando en el espacio de nombres
jobset-system
:kubectl get pod -n jobset-system
El resultado debería ser similar al siguiente:
NAME READY STATUS RESTARTS AGE jobset-controller-manager-69449d86bc-hp5r6 2/2 Running 0 2m15s
Despliega dos servidores de modelos en dos grupos de nodos de segmentos de TPU. Guarda el siguiente archivo de manifiesto
sax-model-server-set
:Sustituye
BUCKET_NAME
por el Cloud Storage que has creado anteriormente:perl -pi -e 's|BUCKET_NAME|BUCKET_NAME|g' sax-model-server-set.yaml
En este manifiesto:
replicas: 2
es el número de réplicas de Job. Cada trabajo representa un servidor de modelos. Por lo tanto, un grupo de 8 pods.parallelism: 8
ycompletions: 8
son iguales al número de nodos de cada grupo de nodos.backoffLimit: 0
debe ser cero para marcar el trabajo como fallido si falla algún pod.ports.containerPort: 8471
es el puerto predeterminado para la comunicación de las VMsname: MEGASCALE_NUM_SLICES
anula la variable de entorno porque GKE no está ejecutando el entrenamiento de Multislice.
Aplica el archivo de manifiesto:
kubectl apply -f sax-model-server-set.yaml
Verifica el estado de los pods del servidor de administración y del servidor de modelos de Saxml:
kubectl get pods
El resultado debería ser similar al siguiente:
NAME READY STATUS RESTARTS AGE sax-admin-server-557c85f488-lnd5d 1/1 Running 0 35h sax-model-server-set-sax-model-server-0-0-nj4sm 1/1 Running 0 24m sax-model-server-set-sax-model-server-0-1-sl8w4 1/1 Running 0 24m sax-model-server-set-sax-model-server-0-2-hb4rk 1/1 Running 0 24m sax-model-server-set-sax-model-server-0-3-qv67g 1/1 Running 0 24m sax-model-server-set-sax-model-server-0-4-pzqz6 1/1 Running 0 24m sax-model-server-set-sax-model-server-0-5-nm7mz 1/1 Running 0 24m sax-model-server-set-sax-model-server-0-6-7br2x 1/1 Running 0 24m sax-model-server-set-sax-model-server-0-7-4pw6z 1/1 Running 0 24m sax-model-server-set-sax-model-server-1-0-8mlf5 1/1 Running 0 24m sax-model-server-set-sax-model-server-1-1-h6z6w 1/1 Running 0 24m sax-model-server-set-sax-model-server-1-2-jggtv 1/1 Running 0 24m sax-model-server-set-sax-model-server-1-3-9v8kj 1/1 Running 0 24m sax-model-server-set-sax-model-server-1-4-6vlb2 1/1 Running 0 24m sax-model-server-set-sax-model-server-1-5-h689p 1/1 Running 0 24m sax-model-server-set-sax-model-server-1-6-bgv5k 1/1 Running 0 24m sax-model-server-set-sax-model-server-1-7-cd6gv 1/1 Running 0 24m
Usa la siguiente imagen de servidor HTTP prediseñada. Guarda el siguiente archivo de manifiesto
sax-http.yaml
:Sustituye
BUCKET_NAME
por el Cloud Storage que has creado anteriormente:perl -pi -e 's|BUCKET_NAME|BUCKET_NAME|g' sax-http.yaml
Aplica el manifiesto
sax-http.yaml
:kubectl apply -f sax-http.yaml
Espera a que termine de crearse el contenedor del servidor HTTP:
kubectl get pods
El resultado debería ser similar al siguiente:
NAME READY STATUS RESTARTS AGE sax-admin-server-557c85f488-lnd5d 1/1 Running 0 35h sax-http-65d478d987-6q7zd 1/1 Running 0 24m sax-model-server-set-sax-model-server-0-0-nj4sm 1/1 Running 0 24m ...
Espera a que se asigne una dirección IP externa al servicio:
kubectl get svc
El resultado debería ser similar al siguiente:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sax-http-lb LoadBalancer 10.48.11.80 10.182.0.87 8888:32674/TCP 7m36s
Obtén la dirección IP del balanceador de carga de Saxml.
LB_IP=$(kubectl get svc sax-http-lb -o jsonpath='{.status.loadBalancer.ingress[*].ip}') PORT="8888"
Carga el modelo de prueba
LmCloudSpmd175B
en dos grupos de nodos de segmento de TPU v5e:curl --request POST \ --header "Content-type: application/json" \ -s ${LB_IP}:${PORT}/publish --data \ '{ "model": "/sax/test/spmd", "model_path": "saxml.server.pax.lm.params.lm_cloud.LmCloudSpmd175B32Test", "checkpoint": "None", "replicas": 2 }'
El modelo de prueba no tiene un punto de control optimizado, sino que los pesos se generan de forma aleatoria. La carga del modelo puede tardar hasta 10 minutos.
El resultado debería ser similar al siguiente:
{ "model": "/sax/test/spmd", "path": "saxml.server.pax.lm.params.lm_cloud.LmCloudSpmd175B32Test", "checkpoint": "None", "replicas": 2 }
Comprueba la preparación del modelo:
kubectl logs sax-model-server-set-sax-model-server-0-0-nj4sm
El resultado debería ser similar al siguiente:
... loading completed. Successfully loaded model for key: /sax/test/spmd
El modelo está totalmente cargado.
Obtener información sobre el modelo:
curl --request GET \ --header "Content-type: application/json" \ -s ${LB_IP}:${PORT}/listcell --data \ '{ "model": "/sax/test/spmd" }'
El resultado debería ser similar al siguiente:
{ "model": "/sax/test/spmd", "model_path": "saxml.server.pax.lm.params.lm_cloud.LmCloudSpmd175B32Test", "checkpoint": "None", "max_replicas": 2, "active_replicas": 2 }
Elimina el clúster que has creado para este tutorial:
gcloud container clusters delete saxml --location ${CONTROL_PLANE_LOCATION}
Elimina la cuenta de servicio:
gcloud iam service-accounts delete sax-iam-sa@${PROJECT_ID}.iam.gserviceaccount.com
Elimina el segmento de Cloud Storage:
gcloud storage rm -r gs://${BUCKET_NAME}
- Consulta las versiones actuales de TPU en la arquitectura del sistema de TPU de Cloud.
- Consulta más información sobre las TPUs en GKE.
Preparar el entorno
Crear un clúster estándar de GKE
Usa Cloud Shell para hacer lo siguiente:
Has creado los siguientes recursos:
El modelo de 175.000 millones de parámetros se debe servir en un slice de TPU v5e de varios hosts con un
4x8
slice de topología (32 chips de TPU v5e) como mínimo.Crea un segmento de Cloud Storage
Crea un segmento de Cloud Storage para almacenar las configuraciones del servidor de administrador de Saxml. Un servidor de administrador en ejecución guarda periódicamente su estado y los detalles de los modelos publicados.
En Cloud Shell, ejecuta lo siguiente:
gcloud storage buckets create gs://${BUCKET_NAME}
Configurar el acceso de las cargas de trabajo mediante Workload Identity Federation para GKE
Asigna una cuenta de servicio de Kubernetes a la aplicación y configura esa cuenta de servicio de Kubernetes para que actúe como cuenta de servicio de gestión de identidades y accesos.
Desplegar Saxml
En esta sección, implementa el servidor de administrador de Saxml y el servidor de modelos de Saxml.
Desplegar el servidor de administrador de Saxml
Desplegar el servidor de modelos de Saxml
Las cargas de trabajo que se ejecutan en slices de TPU de varios hosts requieren un identificador de red estable para que cada Pod pueda detectar los peers del mismo slice de TPU. Para definir estos identificadores, usa IndexedJob, StatefulSet con un servicio sin interfaz gráfica o JobSet, que crea automáticamente un servicio sin interfaz gráfica para todos los trabajos que pertenecen a JobSet. Un JobSet es una API de carga de trabajo que te permite gestionar un grupo de trabajos de Kubernetes como una unidad. El caso de uso más habitual de un JobSet es el entrenamiento distribuido, pero también puedes usarlo para ejecutar cargas de trabajo por lotes.
En la siguiente sección se muestra cómo gestionar varios grupos de pods de servidor de modelos con JobSet.
En este ejemplo, hay 16 contenedores de servidor de modelos:
sax-model-server-set-sax-model-server-0-0-nj4sm
ysax-model-server-set-sax-model-server-1-0-8mlf5
son los dos servidores de modelos principales de cada grupo.Tu clúster de Saxml tiene dos servidores de modelos implementados en dos grupos de nodos de slices de TPU v5e con topologías
4x8
, respectivamente.Implementar el servidor HTTP y el balanceador de carga de Saxml
Usar Saxml
Carga, despliega y sirve el modelo en Saxml en el slice multihost de TPU v5e:
Cargar el modelo
Aplicar el modelo
Enviar una solicitud de petición:
curl --request POST \ --header "Content-type: application/json" \ -s ${LB_IP}:${PORT}/generate --data \ '{ "model": "/sax/test/spmd", "query": "How many days are in a week?" }'
El resultado muestra un ejemplo de la respuesta del modelo. Es posible que esta respuesta no sea significativa porque el modelo de prueba tiene pesos aleatorios.
Anular la publicación del modelo
Ejecuta el siguiente comando para anular la publicación del modelo:
curl --request POST \ --header "Content-type: application/json" \ -s ${LB_IP}:${PORT}/unpublish --data \ '{ "model": "/sax/test/spmd" }'
El resultado debería ser similar al siguiente:
{ "model": "/sax/test/spmd" }
Limpieza
Para evitar que los recursos utilizados en este tutorial se cobren en tu cuenta de Google Cloud, elimina el proyecto que contiene los recursos o conserva el proyecto y elimina los recursos.
Eliminar los recursos desplegados
Siguientes pasos
-