In dieser Anleitung erfahren Sie, wie Sie ein Large Language Model (LLM) unter Verwendung eines TPU-Slice-Knotenpools mit mehreren Hosts auf Google Kubernetes Engine (GKE) mit Saxml für eine effiziente skalierbare Architektur bereitstellen und verfügbar machen.
Hintergrund
Saxml ist ein experimentelles System, das
Paxml
JAX und
PyTorch-Frameworks bereitstellt. Mit TPUs können Sie die Datenverarbeitung mit diesen Frameworks beschleunigen. In dieser Anleitung wird das 175B-Testmodell LmCloudSpmd175B32Test gezeigt, um die Bereitstellung von TPUs in GKE zu demonstrieren. GKE stellt dieses Testmodell auf zwei v5e-TPU-Slice-Knotenpools mit 4x8-Topologie bereit.
Für eine korrekte Bereitstellung des Testmodells wurde die TPU-Topologie anhand der Größe des Modells definiert. Da das N Milliarden 16-Bit-Modell ungefähr zweimal (2xN) GB Arbeitsspeicher erfordert, benötigt das 175B-LmCloudSpmd175B32Test-Modell etwa 350 GB Arbeitsspeicher. Der einzelne TPU-Chip TPU v5e hat 16 GB. Zur Unterstützung von 350 GB benötigt GKE 21 v5e-TPU-Chips (350/16= 21). Basierend auf der Zuordnung der TPU-Konfiguration, ist die richtige TPU-Konfiguration für diese Anleitung:
- Maschinentyp:
ct5lp-hightpu-4t - Topologie:
4x8(32 TPU-Chips)
Bei der Bereitstellung von TPUs in GKE ist es wichtig, die richtige TPU-Topologie für die Modellbereitstellung auszuwählen. Weitere Informationen finden Sie unter TPU-Konfiguration planen.
Umgebung vorbereiten
Starten Sie in der Cloud de Confiance Console eine Cloud Shell-Instanz:
Cloud Shell öffnenLegen Sie die Standardumgebungsvariablen fest:
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-bucketErsetzen Sie die folgenden Werte:
- PROJECT_ID: Ihre Cloud de Confiance Projekt-ID.
- CONTROL_PLANE_LOCATION: die Compute Engine-Zone der Steuerungsebene Ihres Clusters. Wählen Sie die Zone aus, in der die
ct5lp-hightpu-4tverfügbar ist.
In diesem Befehl gibt
BUCKET_NAMEden Namen des Cloud de Confiance-Speicher-Buckets an, in dem die Saxml-Administratorserverkonfigurationen gespeichert werden.
GKE-Standardcluster erstellen
Erledigen Sie mit Cloud Shell Folgendes:
Erstellen Sie einen Standard-Cluster, der die Identitätsföderation von Arbeitslasten für GKE verwendet:
gcloud container clusters create saxml \ --location=${CONTROL_PLANE_LOCATION} \ --workload-pool=${PROJECT_ID}.s3ns.svc.id.goog \ --cluster-version=VERSION \ --num-nodes=4Ersetzen Sie
VERSIONdurch die GKE-Versionsnummer. GKE unterstützt TPU v5e in der Version 1.27.2-gke.2100 und höher. Weitere Informationen finden Sie unter TPU-Verfügbarkeit in GKE.Die Erstellung eines Clusters kann einige Minuten dauern.
Erstellen Sie den ersten Knotenpool mit dem Namen
tpu1:gcloud container node-pools create tpu1 \ --location=${CONTROL_PLANE_LOCATION} \ --machine-type=ct5lp-hightpu-4t \ --tpu-topology=4x8 \ --num-nodes=8 \ --cluster=saxmlDer Wert für das Flag
--num-nodeswird berechnet, indem die TPU-Topologie durch die Anzahl der TPU-Chips pro TPU-Slice dividiert wird. In diesem Fall: (4 * 8) / 4.Erstellen Sie den zweiten Knotenpool mit dem Namen
tpu2:gcloud container node-pools create tpu2 \ --location=${CONTROL_PLANE_LOCATION} \ --machine-type=ct5lp-hightpu-4t \ --tpu-topology=4x8 \ --num-nodes=8 \ --cluster=saxmlDer Wert für das Flag
--num-nodeswird berechnet, indem die TPU-Topologie durch die Anzahl der TPU-Chips pro TPU-Slice dividiert wird. In diesem Fall: (4 * 8) / 4.
Sie haben die folgenden Ressourcen erstellt:
- Ein Standardcluster mit vier CPU-Knoten.
- Zwei v5e-TPU-Slice-Knotenpools mit
4x8-Topologie. Jeder Knotenpool stellt acht TPU-Slice-Knoten mit jeweils 4 TPU-Chips dar.
Das 175B-Modell muss auf einem v5e-TPU-Slice mit mehreren Hosts mit Topologiesegment 4x8 (mindestens 32 v5e-TPU-Chips) bereitgestellt werden.
Cloud Storage-Bucket erstellen
Cloud Storage-Bucket zum Speichern der Saxml-Administratorserverkonfigurationen erstellen. Ein laufender Administratorserver speichert regelmäßig seinen Status und Details zu den veröffentlichten Modellen.
Führen Sie in Cloud Shell folgenden Befehl aus:
gcloud storage buckets create gs://${BUCKET_NAME}
Arbeitslastzugriff mit Identitätsföderation von Arbeitslasten für GKE konfigurieren
Weisen Sie der Anwendung ein Kubernetes-ServiceAccount zu und konfigurieren Sie dieses Kubernetes-Dienstkonto als IAM-Dienstkonto.
Konfigurieren Sie
kubectlfür die Kommunikation mit Ihrem Cluster:gcloud container clusters get-credentials saxml --location=${CONTROL_PLANE_LOCATION}Erstellen Sie ein Kubernetes-ServiceAccount für die Anwendung:
kubectl create serviceaccount sax-sa --namespace defaultErstellen Sie ein IAM-Dienstkonto für Ihre Anwendung:
gcloud iam service-accounts create sax-iam-saFügen Sie eine IAM-Richtlinienbindung für Ihr IAM-Dienstkonto zum Lesen und Schreiben in Cloud Storage hinzu:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member "serviceAccount:sax-iam-sa@${PROJECT_ID}.s3ns.iam.gserviceaccount.com" \ --role roles/storage.adminErlauben Sie dem Kubernetes-ServiceAccount, die Identität des IAM-Dienstkontos zu übernehmen. Fügen Sie dazu eine IAM-Richtlinienbindung zwischen den beiden Dienstkonten hinzu. Durch diese Bindung kann das Kubernetes-ServiceAccount als IAM-Dienstkonto verwendet werden, sodass das Kubernetes-Dienstkonto Daten in Cloud Storage lesen und schreiben kann.
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]"Kennzeichnen Sie das Kubernetes-Dienstkonto mit der E-Mail-Adresse des IAM-Dienstkontos. Dadurch weiß Ihre Beispielanwendung, welches Dienstkonto für den Zugriff auf Cloud de Confiance -Dienste verwendet werden soll. Wenn die App also Google API-Clientbibliotheken für den Zugriff auf Cloud de Confiance -Dienste verwendet, verwendet sie dieses IAM-Dienstkonto.
kubectl annotate serviceaccount sax-sa \ iam.gke.io/gcp-service-account=sax-iam-sa@${PROJECT_ID}.s3ns.iam.gserviceaccount.com
Saxml bereitstellen
In diesem Abschnitt stellen Sie den Saxml-Administratorserver und den Saxml-Modellserver bereit.
Saxml-Administratorserver bereitstellen
Erstellen Sie das folgende
sax-admin-server.yaml-Manifest:Ersetzen Sie
BUCKET_NAMEdurch den Namen des Cloud Storage-Buckets, den Sie zuvor erstellt haben:perl -pi -e 's|BUCKET_NAME|BUCKET_NAME|g' sax-admin-server.yamlWenden Sie das Manifest an:
kubectl apply -f sax-admin-server.yamlPrüfen Sie, ob der Administrator-Server-Pod ausgeführt wird:
kubectl get deploymentDie Ausgabe sieht in etwa so aus:
NAME READY UP-TO-DATE AVAILABLE AGE sax-admin-server 1/1 1 1 52s
Saxml-Modellserver bereitstellen
Arbeitslasten, die in TPU-Slices mit mehreren Hosts ausgeführt werden, benötigen eine stabile Netzwerkkennung für jeden Pod, um Peers im selben TPU-Slice zu erkennen. Verwenden Sie zum Definieren dieser Kennungen IndexedJob, StatefulSet mit einem monitorlosen Dienst oder JobSet. Damit wird automatisch ein monitorloser Service für alle Jobs erstellt, die zum JobSet gehören. Ein Jobset ist eine Arbeitslast-API, mit der Sie eine Gruppe von Kubernetes-Jobs als Einheit verwalten können. Der häufigste Anwendungsfall für ein JobSet ist das verteilte Training. Sie können es aber auch zum Ausführen von Batch-Arbeitslasten verwenden.
Die folgenden Abschnitte zeigen, wie Sie mehrere Gruppen von Modellserver-Pods mit JobSet verwalten.
Installieren Sie JobSet v0.2.3 oder höher.
kubectl apply --server-side -f https://github.com/kubernetes-sigs/jobset/releases/download/JOBSET_VERSION/manifests.yamlErsetzen Sie
JOBSET_VERSIONdurch die JobSet-Version. Beispiel:v0.2.3.Ausführung des JobSet-Controllers im Namespace
jobset-systemprüfen:kubectl get pod -n jobset-systemDie Ausgabe sieht in etwa so aus:
NAME READY STATUS RESTARTS AGE jobset-controller-manager-69449d86bc-hp5r6 2/2 Running 0 2m15sStellen Sie zwei Modellserver in zwei TPU-Slice-Knotenpools bereit. Speichern Sie das folgende
sax-model-server-set-Manifest:Ersetzen Sie
BUCKET_NAMEdurch den Namen des Cloud Storage-Buckets, den Sie zuvor erstellt haben:perl -pi -e 's|BUCKET_NAME|BUCKET_NAME|g' sax-model-server-set.yamlIn diesem Manifest:
replicas: 2ist die Anzahl der Job-Replikate. Jeder Job stellt einen Modellserver dar. Daher eine Gruppe von 8 Pods.parallelism: 8undcompletions: 8entsprechen der Anzahl der Knoten im jeweiligen Knotenpool.backoffLimit: 0muss null sein, damit der Job als fehlgeschlagen markiert wird, wenn ein Pod fehlschlägt.ports.containerPort: 8471ist der Standardport für die Kommunikation der VMs.name: MEGASCALE_NUM_SLICEShebt die Festlegung der Umgebungsvariable auf, weil In der GKE kein Multislice-Training ausgeführt wird.
Wenden Sie das Manifest an:
kubectl apply -f sax-model-server-set.yamlPrüfen Sie den Status der Saxml Admininistratorserver- und Modellserver-Pods:
kubectl get podsDie Ausgabe sieht in etwa so aus:
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
In diesem Beispiel gibt es 16 Modellservercontainer:
sax-model-server-set-sax-model-server-0-0-nj4sm und
sax-model-server-set-sax-model-server-1-0-8mlf5 sind die beiden Hauptmodellserver in jeder Gruppe.
Ihr Saxml-Cluster hat zwei Modellserver, die auf zwei v5e-TPU-Slice-Knotenpools mit 4x8-Topologie bereitgestellt werden.
Saxml-HTTP-Server und Load-Balancer bereitstellen
Verwenden Sie das folgende vorgefertigte HTTP-Server-Image. Speichern Sie das folgende
sax-http.yaml-Manifest:Ersetzen Sie
BUCKET_NAMEdurch den Namen des Cloud Storage-Buckets, den Sie zuvor erstellt haben:perl -pi -e 's|BUCKET_NAME|BUCKET_NAME|g' sax-http.yamlWenden Sie das
sax-http.yaml-Manifest an:kubectl apply -f sax-http.yamlWarten Sie, bis der HTTP-Server-Container erstellt wurde:
kubectl get podsDie Ausgabe sieht in etwa so aus:
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 ...Warten Sie, bis dem Dienst eine externe IP-Adresse zugewiesen wurde:
kubectl get svcDie Ausgabe sieht in etwa so aus:
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
Saxml verwenden
Laden, implementieren und stellen Sie das Modell auf Saxml im v5e TPU-Multihost-Slice bereit:
Modell laden
Rufen Sie die IP-Adresse des Load Balancers für Saxml ab.
LB_IP=$(kubectl get svc sax-http-lb -o jsonpath='{.status.loadBalancer.ingress[*].ip}') PORT="8888"Laden Sie das
LmCloudSpmd175B-Testmodell in zwei v5e-TPU-Slice-Knotenpools: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 }'Das Testmodell hat keinen abgestimmten Prüfpunkt. Die Gewichtungen sind zufällig generiert. Das Laden des Modells kann bis zu 10 Minuten dauern.
Die Ausgabe sieht in etwa so aus:
{ "model": "/sax/test/spmd", "path": "saxml.server.pax.lm.params.lm_cloud.LmCloudSpmd175B32Test", "checkpoint": "None", "replicas": 2 }Prüfen Sie die Modellbereitschaft:
kubectl logs sax-model-server-set-sax-model-server-0-0-nj4smDie Ausgabe sieht in etwa so aus:
... loading completed. Successfully loaded model for key: /sax/test/spmdDas Modell ist vollständig geladen.
Informationen zum Modell abrufen:
curl --request GET \ --header "Content-type: application/json" \ -s ${LB_IP}:${PORT}/listcell --data \ '{ "model": "/sax/test/spmd" }'Die Ausgabe sieht in etwa so aus:
{ "model": "/sax/test/spmd", "model_path": "saxml.server.pax.lm.params.lm_cloud.LmCloudSpmd175B32Test", "checkpoint": "None", "max_replicas": 2, "active_replicas": 2 }
Modell bereitstellen
Stellen Sie einen Prompt bereit:
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?"
}'
Die Ausgabe zeigt ein Beispiel für die Modellantwort: Diese Antwort ist möglicherweise nicht sinnvoll, weil das Testmodell zufällige Gewichtungen hat.
Veröffentlichung des Modells aufheben
Führen Sie den folgenden Befehl aus, um die Veröffentlichung des Modells aufzuheben:
curl --request POST \
--header "Content-type: application/json" \
-s ${LB_IP}:${PORT}/unpublish --data \
'{
"model": "/sax/test/spmd"
}'
Die Ausgabe sieht etwa so aus:
{
"model": "/sax/test/spmd"
}