Este tutorial mostra como implementar e publicar um modelo de linguagem (conteúdo extenso) (MDI/CE) usando um conjunto de nós de fatia de TPU com vários anfitriões no Google Kubernetes Engine (GKE) com o Saxml para uma arquitetura escalável eficiente.
Contexto
O Saxml é um sistema experimental que serve frameworks
Paxml,
JAX e
PyTorch. Pode usar as TPUs para acelerar o processamento de dados com estas frameworks. Para demonstrar a implementação de TPUs no GKE, este tutorial disponibiliza o modelo de teste LmCloudSpmd175B32Test de 175 mil milhões de parâmetros. O GKE implementa este modelo de teste em dois conjuntos de nós de fatias de TPU v5e com topologia 4x8, respetivamente.
Para implementar corretamente o modelo de teste, a topologia da TPU foi definida com base no tamanho do modelo. Dado que o modelo de N mil milhões de bits requer aproximadamente 2 vezes (2xN) GB de memória, o modelo LmCloudSpmd175B32Test de 175 mil milhões requer cerca de 350 GB de memória. O chip de TPU único v5e tem 16 GB. Para suportar 350 GB, o GKE precisa de 21 chips de TPU v5e (350/16= 21). Com base no mapeamento da configuração da TPU, a configuração da TPU adequada para este tutorial é:
- Tipo de máquina: ct5lp-hightpu-4t
- Topologia: 4x8(32 chips de TPU)
Selecionar a topologia de TPU certa para publicar um modelo é importante quando implementa TPUs no GKE. Para saber mais, consulte o artigo Planeie a configuração da TPU.
Prepare o ambiente
- Na Cloud de Confiance consola, inicie uma instância do Cloud Shell: 
 Abrir Cloud Shell
- Defina as variáveis de ambiente predefinidas: - 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- Substitua os seguintes valores: - PROJECT_ID: o seu Cloud de Confiance ID do projeto.
- CONTROL_PLANE_LOCATION: a zona do Compute Engine do plano de controlo do seu cluster. Selecione a zona onde o ct5lp-hightpu-4testá disponível.
 - Neste comando, - BUCKET_NAMEespecifica o nome do Cloud de Confiance contentor de armazenamento para armazenar as configurações do servidor de administrador do Saxml.
Crie um cluster padrão do GKE
Use o Cloud Shell para fazer o seguinte:
- Crie um cluster Standard que use a Workload Identity Federation para o GKE: - gcloud container clusters create saxml \ --location=${CONTROL_PLANE_LOCATION} \ --workload-pool=${PROJECT_ID}.s3ns.svc.id.goog \ --cluster-version=VERSION \ --num-nodes=4- Substitua - VERSIONpelo número da versão do GKE. O GKE suporta a TPU v5e na versão 1.27.2-gke.2100 e posteriores. Para mais informações, consulte o artigo Disponibilidade de TPUs no GKE.- A criação do cluster pode demorar vários minutos. 
- Crie o primeiro node pool com o nome - tpu1:- gcloud container node-pools create tpu1 \ --location=${CONTROL_PLANE_LOCATION} \ --machine-type=ct5lp-hightpu-4t \ --tpu-topology=4x8 \ --num-nodes=8 \ --cluster=saxml- O valor da flag - --num-nodesé calculado dividindo a topologia da TPU pelo número de chips de TPU por fatia de TPU. Neste caso: (4 * 8) / 4.
- Crie o segundo node pool com o nome - tpu2:- gcloud container node-pools create tpu2 \ --location=${CONTROL_PLANE_LOCATION} \ --machine-type=ct5lp-hightpu-4t \ --tpu-topology=4x8 \ --num-nodes=8 \ --cluster=saxml- O valor da flag - --num-nodesé calculado dividindo a topologia da TPU pelo número de chips de TPU por fatia de TPU. Neste caso: (4 * 8) / 4.
Criou os seguintes recursos:
- Um cluster padrão com quatro nós de CPU.
- Dois conjuntos de nós de fatias de TPU v5e com topologia 4x8. Cada conjunto de nós representa oito nós de fatias de TPU com 4 chips de TPU cada.
O modelo de 175 mil milhões de parâmetros tem de ser publicado numa fatia de TPU v5e com vários anfitriões com, no mínimo, uma 4x8
fatia de topologia (32 chips de TPU v5e).
Crie um contentor do Cloud Storage
Crie um contentor do Cloud Storage para armazenar as configurações do servidor de administrador do Saxml. Um servidor de administrador em execução guarda periodicamente o respetivo estado e os detalhes dos modelos publicados.
No Cloud Shell, execute o seguinte:
gcloud storage buckets create gs://${BUCKET_NAME}
Configure o acesso das suas cargas de trabalho através da federação de identidades de cargas de trabalho para o GKE
Atribua uma conta de serviço do Kubernetes à aplicação e configure essa conta de serviço do Kubernetes para funcionar como uma conta de serviço do IAM.
- Configure - kubectlpara comunicar com o cluster:- gcloud container clusters get-credentials saxml --location=${CONTROL_PLANE_LOCATION}
- Crie uma ServiceAccount do Kubernetes para a sua aplicação usar: - kubectl create serviceaccount sax-sa --namespace default
- Crie uma conta de serviço do IAM para a sua aplicação: - gcloud iam service-accounts create sax-iam-sa
- Adicione uma associação de políticas de IAM para a sua conta de serviço de IAM poder ler e escrever no Cloud Storage: - gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member "serviceAccount:sax-iam-sa@${PROJECT_ID}.s3ns.iam.gserviceaccount.com" \ --role roles/storage.admin
- Permita que a conta de serviço do Kubernetes use a identidade da conta de serviço da IAM adicionando uma associação de políticas da IAM entre as duas contas de serviço. Esta associação permite que a conta de serviço do Kubernetes atue como a conta de serviço do IAM, para que a conta de serviço do Kubernetes possa ler e escrever no Cloud Storage. - gcloud iam service-accounts add-iam-policy-binding sax-iam-sa@${PROJECT_ID}.s3ns.iam.gserviceaccount.com \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:${PROJECT_ID}.s3ns.svc.id.goog[default/sax-sa]"
- Anotar a conta de serviço do Kubernetes com o endereço de email da conta de serviço do IAM. Isto permite que a sua app de exemplo saiba que conta de serviço usar para aceder aos serviços Cloud de Confiance . Assim, quando a app usa quaisquer bibliotecas cliente de APIs Google padrão para aceder a serviços, usa essa conta de serviço da IAM. Cloud de Confiance - kubectl annotate serviceaccount sax-sa \ iam.gke.io/gcp-service-account=sax-iam-sa@${PROJECT_ID}.s3ns.iam.gserviceaccount.com
Implemente o Saxml
Nesta secção, implementa o servidor de administrador do Saxml e o servidor do modelo Saxml.
Implemente o servidor de administrador do SAXML
- Crie o seguinte manifesto - sax-admin-server.yaml:
- Substitua - BUCKET_NAMEpelo armazenamento na nuvem criado anteriormente:- perl -pi -e 's|BUCKET_NAME|BUCKET_NAME|g' sax-admin-server.yaml
- Aplique o manifesto: - kubectl apply -f sax-admin-server.yaml
- Verifique se o pod do servidor de administrador está em funcionamento: - kubectl get deployment- O resultado é semelhante ao seguinte: - NAME READY UP-TO-DATE AVAILABLE AGE sax-admin-server 1/1 1 1 52s
Implemente o servidor de modelos Saxml
As cargas de trabalho executadas em fatias de TPU com vários anfitriões requerem um identificador de rede estável para que cada Pod descubra pares na mesma fatia de TPU. Para definir estes identificadores, use IndexedJob, StatefulSet com um serviço sem interface ou JobSet, que cria automaticamente um serviço sem interface para todos os trabalhos que pertencem ao JobSet. Um Jobset é uma API de carga de trabalho que lhe permite gerir um grupo de tarefas do Kubernetes como uma unidade. O exemplo de utilização mais comum de um JobSet é o treino distribuído, mas também o pode usar para executar cargas de trabalho em lote.
A secção seguinte mostra como gerir vários grupos de pods do servidor de modelos com o JobSet.
- Instale o JobSet v0.2.3 ou posterior. - kubectl apply --server-side -f https://github.com/kubernetes-sigs/jobset/releases/download/JOBSET_VERSION/manifests.yaml- Substitua - JOBSET_VERSIONpela versão do JobSet. Por exemplo,- v0.2.3.
- Valide se o controlador JobSet está a ser executado no - jobset-systemespaço de nomes:- kubectl get pod -n jobset-system- O resultado é semelhante ao seguinte: - NAME READY STATUS RESTARTS AGE jobset-controller-manager-69449d86bc-hp5r6 2/2 Running 0 2m15s
- Implemente dois servidores de modelos em dois conjuntos de nós de fatias de TPU. Guarde o seguinte manifesto - sax-model-server-set:
- Substitua - BUCKET_NAMEpelo armazenamento na nuvem criado anteriormente:- perl -pi -e 's|BUCKET_NAME|BUCKET_NAME|g' sax-model-server-set.yaml- Neste manifesto: - replicas: 2é o número de réplicas de tarefas. Cada tarefa representa um servidor de modelos. Por isso, um grupo de 8 Pods.
- parallelism: 8e- completions: 8são iguais ao número de nós em cada conjunto de nós.
- backoffLimit: 0tem de ser zero para marcar a tarefa como falhada se algum pod falhar.
- A porta ports.containerPort: 8471é a porta predefinida para a comunicação das VMs
- name: MEGASCALE_NUM_SLICESanula a definição da variável de ambiente porque o GKE não está a executar o treino de vários fragmentos.
 
- Aplique o manifesto: - kubectl apply -f sax-model-server-set.yaml
- Verifique o estado dos pods do servidor de administração e do servidor de modelos do Saxml: - kubectl get pods- O resultado é semelhante ao seguinte: - 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
Neste exemplo, existem 16 contentores de servidores de modelos:
sax-model-server-set-sax-model-server-0-0-nj4sm e
sax-model-server-set-sax-model-server-1-0-8mlf5 são os dois servidores de modelos principais em cada grupo.
O seu cluster Saxml tem dois servidores de modelos implementados em dois node pools de fatias de TPU v5e com a topologia 4x8, respetivamente.
Implemente o servidor HTTP Saxml e o balanceador de carga
- Use a seguinte imagem do servidor HTTP de imagem pré-criada. Guarde o seguinte manifesto - sax-http.yaml:
- Substitua - BUCKET_NAMEpelo armazenamento na nuvem criado anteriormente:- perl -pi -e 's|BUCKET_NAME|BUCKET_NAME|g' sax-http.yaml
- Aplique o manifesto - sax-http.yaml:- kubectl apply -f sax-http.yaml
- Aguarde pela conclusão da criação do contentor do servidor HTTP: - kubectl get pods- O resultado é semelhante ao seguinte: - 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 ...
- Aguarde até que o serviço tenha um endereço IP externo atribuído: - kubectl get svc- O resultado é semelhante ao seguinte: - 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
Use o Saxml
Carregue, implemente e publique o modelo no Saxml na fatia de vários anfitriões da TPU v5e:
Carregue o modelo
- Obtenha o endereço IP do balanceador de carga para o Saxml. - LB_IP=$(kubectl get svc sax-http-lb -o jsonpath='{.status.loadBalancer.ingress[*].ip}') PORT="8888"
- Carregue o modelo de teste - LmCloudSpmd175Bem dois conjuntos de nós de fatias 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 }'- O modelo de teste não tem um ponto de verificação otimizado. Os pesos são gerados aleatoriamente. O carregamento do modelo pode demorar até 10 minutos. - O resultado é semelhante ao seguinte: - { "model": "/sax/test/spmd", "path": "saxml.server.pax.lm.params.lm_cloud.LmCloudSpmd175B32Test", "checkpoint": "None", "replicas": 2 }
- Verifique a prontidão do modelo: - kubectl logs sax-model-server-set-sax-model-server-0-0-nj4sm- O resultado é semelhante ao seguinte: - ... loading completed. Successfully loaded model for key: /sax/test/spmd- O modelo está totalmente carregado. 
- Obtenha informações sobre o modelo: - curl --request GET \ --header "Content-type: application/json" \ -s ${LB_IP}:${PORT}/listcell --data \ '{ "model": "/sax/test/spmd" }'- O resultado é semelhante ao seguinte: - { "model": "/sax/test/spmd", "model_path": "saxml.server.pax.lm.params.lm_cloud.LmCloudSpmd175B32Test", "checkpoint": "None", "max_replicas": 2, "active_replicas": 2 }
Publique o modelo
Apresentar um pedido de comando:
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?"
}'
O resultado mostra um exemplo da resposta do modelo. Esta resposta pode não ser significativa porque o modelo de teste tem ponderações aleatórias.
Anule a publicação do modelo
Execute o seguinte comando para anular a publicação do modelo:
curl --request POST \
--header "Content-type: application/json" \
-s ${LB_IP}:${PORT}/unpublish --data \
'{
    "model": "/sax/test/spmd"
}'
O resultado é semelhante ao seguinte:
{
  "model": "/sax/test/spmd"
}