In dieser Anleitung wird beschrieben, wie Sie ein Modell in Google Kubernetes Engine (GKE) mit Ray, PyTorch und dem Ray Operator-Add-on trainieren.
Über Ray
Ray ist ein skalierbares Open-Source-Computing-Framework für KI/ML-Anwendungen. Ray Train ist eine Komponente in Ray, die für das Training und die Feinabstimmung von verteilten Modellen entwickelt wurde. Sie können die Ray Train API verwenden, um das Training über mehrere Computer hinweg zu skalieren und in ML-Bibliotheken wie PyTorch einzubinden.
Sie können Ray-Trainingsjobs mit der Ressource RayCluster oder RayJob bereitstellen. Aus folgenden Gründen sollten Sie beim Bereitstellen von Ray-Jobs in der Produktion eine RayJob-Ressource verwenden:
- Die RayJob-Ressource erstellt einen sitzungsspezifischen Ray-Cluster, der automatisch gelöscht werden kann, wenn ein Job abgeschlossen ist.
- Die RayJob-Ressource unterstützt Wiederholungsrichtlinien für die stabile Jobausführung.
- Sie können Ray-Jobs mit vertrauten Kubernetes API-Mustern verwalten.
Umgebung vorbereiten
So bereiten Sie die Umgebung vor:
Starten Sie eine Cloud Shell-Sitzung über die Google Cloud Console. Klicken Sie dazu in der Google Cloud Console auf
Cloud Shell aktivieren. Dadurch wird im unteren Bereich der Google Cloud Console eine Sitzung gestartet.
Legen Sie Umgebungsvariablen fest:
export PROJECT_ID=PROJECT_ID export CLUSTER_NAME=ray-cluster export COMPUTE_REGION=us-central1 export COMPUTE_ZONE=us-central1-c export CLUSTER_VERSION=CLUSTER_VERSION export TUTORIAL_HOME=`pwd`
Ersetzen Sie Folgendes:
PROJECT_ID
: Ihre Google Cloud Projekt-ID.CLUSTER_VERSION
ist die zu verwendende GKE-Version. Es muss1.30.1
oder höher sein.
Klonen Sie das GitHub-Repository:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
Wechseln Sie in das Arbeitsverzeichnis:
cd kubernetes-engine-samples/ai-ml/gke-ray/raytrain/pytorch-mnist
Erstellen Sie eine virtuelle Python-Umgebung:
python -m venv myenv && \ source myenv/bin/activate
GKE-Cluster erstellen
Autopilot- oder Standard-GKE-Cluster erstellen:
Autopilot
Autopilot-Cluster erstellen:
gcloud container clusters create-auto ${CLUSTER_NAME} \
--enable-ray-operator \
--cluster-version=${CLUSTER_VERSION} \
--location=${COMPUTE_REGION}
Standard
Standardcluster erstellen:
gcloud container clusters create ${CLUSTER_NAME} \
--addons=RayOperator \
--cluster-version=${CLUSTER_VERSION} \
--machine-type=e2-standard-8 \
--location=${COMPUTE_ZONE} \
--num-nodes=4
RayCluster-Ressource bereitstellen
Stellen Sie eine RayCluster-Ressource in Ihrem Cluster bereit:
Prüfen Sie das folgende Manifest:
Dieses Manifest beschreibt eine benutzerdefinierte RayCluster-Ressource.
Wenden Sie das Manifest auf Ihren GKE-Cluster an:
kubectl apply -f ray-cluster.yaml
Prüfen Sie, ob die RayCluster-Ressource bereit ist:
kubectl get raycluster
Die Ausgabe sieht in etwa so aus:
NAME DESIRED WORKERS AVAILABLE WORKERS CPUS MEMORY GPUS STATUS AGE pytorch-mnist-cluster 2 2 6 20Gi 0 ready 63s
In dieser Ausgabe gibt
ready
in der SpalteSTATUS
an, dass die RayCluster-Ressource bereit ist.
Verbindung zur RayCluster-Ressource herstellen
Stellen Sie eine Verbindung zur RayCluster-Ressource her, um einen Ray-Job zu senden.
Prüfen Sie, ob GKE den RayCluster-Dienst erstellt hat:
kubectl get svc pytorch-mnist-cluster-head-svc
Die Ausgabe sieht in etwa so aus:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE pytorch-mnist-cluster-head-svc ClusterIP 34.118.238.247 <none> 10001/TCP,8265/TCP,6379/TCP,8080/TCP 109s
Richten Sie eine Portweiterleitungssitzung zum Ray-Head ein:
kubectl port-forward svc/pytorch-mnist-cluster-head-svc 8265:8265 2>&1 >/dev/null &
Prüfen Sie, ob der Ray-Client über localhost eine Verbindung zum Ray-Cluster herstellen kann:
ray list nodes --address http://localhost:8265
Die Ausgabe sieht in etwa so aus:
Stats: ------------------------------ Total: 3 Table: ------------------------------ NODE_ID NODE_IP IS_HEAD_NODE STATE NODE_NAME RESOURCES_TOTAL LABELS 0 1d07447d7d124db641052a3443ed882f913510dbe866719ac36667d2 10.28.1.21 False ALIVE 10.28.1.21 CPU: 2.0 ray.io/node_id: 1d07447d7d124db641052a3443ed882f913510dbe866719ac36667d2 # Several lines of output omitted
Modell trainieren
Trainieren Sie ein PyTorch-Modell mit dem Fashion MNIST-Dataset:
Senden Sie einen Ray-Job und warten Sie, bis der Job abgeschlossen ist:
ray job submit --submission-id pytorch-mnist-job --working-dir . --runtime-env-json='{"pip": ["torch", "torchvision"], "excludes": ["myenv"]}' --address http://localhost:8265 -- python train.py
Die Ausgabe sieht in etwa so aus:
Job submission server address: http://localhost:8265 -------------------------------------------- Job 'pytorch-mnist-job' submitted successfully -------------------------------------------- Next steps Query the logs of the job: ray job logs pytorch-mnist-job Query the status of the job: ray job status pytorch-mnist-job Request the job to be stopped: ray job stop pytorch-mnist-job Handling connection for 8265 Tailing logs until the job exits (disable with --no-wait): ... ...
Prüfen Sie den Jobstatus:
ray job status pytorch-mnist
Die Ausgabe sieht in etwa so aus:
Job submission server address: http://localhost:8265 Status for job 'pytorch-mnist-job': RUNNING Status message: Job is currently running.
Warten Sie in diesem Fall, bis
Status for job
den WertCOMPLETE
hat. Dies kann 15 Minuten oder länger dauern.So rufen Sie Ray-Joblogs auf:
ray job logs pytorch-mnist
Die Ausgabe sieht in etwa so aus:
Training started with configuration: ╭─────────────────────────────────────────────────╮ │ Training config │ ├──────────────────────────────────────────────────┤ │ train_loop_config/batch_size_per_worker 8 │ │ train_loop_config/epochs 10 │ │ train_loop_config/lr 0.001 │ ╰─────────────────────────────────────────────────╯ # Several lines omitted Training finished iteration 10 at 2024-06-19 08:29:36. Total running time: 9min 18s ╭───────────────────────────────╮ │ Training result │ ├────────────────────────────────┤ │ checkpoint_dir_name │ │ time_this_iter_s 25.7394 │ │ time_total_s 351.233 │ │ training_iteration 10 │ │ accuracy 0.8656 │ │ loss 0.37827 │ ╰───────────────────────────────╯ # Several lines omitted ------------------------------- Job 'pytorch-mnist' succeeded -------------------------------
RayJob bereitstellen
Die benutzerdefinierte RayJob verwaltet den Lebenszyklus einer RayCluster-Ressource während der Ausführung eines einzelnen Ray-Jobs.
Prüfen Sie das folgende Manifest:
Dieses Manifest beschreibt eine benutzerdefinierte RayJob-Ressource.
Wenden Sie das Manifest auf Ihren GKE-Cluster an:
kubectl apply -f ray-job.yaml
Prüfen Sie, ob die RayJob-Ressource ausgeführt wird:
kubectl get rayjob
Die Ausgabe sieht in etwa so aus:
NAME JOB STATUS DEPLOYMENT STATUS START TIME END TIME AGE pytorch-mnist-job RUNNING Running 2024-06-19T15:43:32Z 2m29s
In dieser Ausgabe gibt die Spalte
DEPLOYMENT STATUS
an, dass die RayJob-RessourceRunning
ist.Rufen Sie den RayJob-Ressourcenstatus auf:
kubectl logs -f -l job-name=pytorch-mnist-job
Die Ausgabe sieht in etwa so aus:
Training started with configuration: ╭─────────────────────────────────────────────────╮ │ Training config │ ├──────────────────────────────────────────────────┤ │ train_loop_config/batch_size_per_worker 8 │ │ train_loop_config/epochs 10 │ │ train_loop_config/lr 0.001 │ ╰─────────────────────────────────────────────────╯ # Several lines omitted Training finished iteration 10 at 2024-06-19 08:29:36. Total running time: 9min 18s ╭───────────────────────────────╮ │ Training result │ ├────────────────────────────────┤ │ checkpoint_dir_name │ │ time_this_iter_s 25.7394 │ │ time_total_s 351.233 │ │ training_iteration 10 │ │ accuracy 0.8656 │ │ loss 0.37827 │ ╰───────────────────────────────╯ # Several lines omitted ------------------------------- Job 'pytorch-mnist' succeeded -------------------------------
Prüfen Sie, ob der Ray-Job abgeschlossen ist:
kubectl get rayjob
Die Ausgabe sieht in etwa so aus:
NAME JOB STATUS DEPLOYMENT STATUS START TIME END TIME AGE pytorch-mnist-job SUCCEEDED Complete 2024-06-19T15:43:32Z 2024-06-19T15:51:12Z 9m6s
In dieser Ausgabe gibt die Spalte
DEPLOYMENT STATUS
an, dass die RayJob-RessourceComplete
ist.