Modell mit PyTorch, Ray und Google Kubernetes Engine (GKE) trainieren

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.

Ziele

Dieser Leitfaden richtet sich an Kunden von generativer KI, neue oder bestehende Nutzer von GKE, ML-Entwickler, MLOps-Entwickler (DevOps) oder Plattformadministratoren, die daran interessiert sind, Funktionen zur Kubernetes-Containerorchestrierung für die Bereitstellung von Modellen mit Ray zu nutzen.

  • Einen GKE-Cluster installieren
  • Erstellen Sie mit der benutzerdefinierten RayCluster-Ressource einen Ray-Cluster.
  • Modell mit einem Ray-Job trainieren.
  • Stellen Sie einen Ray-Job mit der benutzerdefinierten RayJob bereit.

Kosten

In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:

Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen.

Neuen Nutzern von Google Cloud steht möglicherweise eine kostenlose Testversion zur Verfügung.

Nach Abschluss der in diesem Dokument beschriebenen Aufgaben können Sie weitere Kosten vermeiden, indem Sie die erstellten Ressourcen löschen. Weitere Informationen finden Sie unter Bereinigen.

Hinweis

Die Software, die Sie für diese Anleitung benötigen, ist in Cloud Shell vorinstalliert, einschließlich kubectl und der gcloud CLI. Wenn Sie Cloud Shell nicht verwenden, müssen Sie die gcloud CLI installieren.

  1. Melden Sie sich in Ihrem Google Cloud -Konto an. Wenn Sie mit Google Cloudnoch nicht vertraut sind, erstellen Sie ein Konto, um die Leistungsfähigkeit unserer Produkte in der Praxis sehen und bewerten zu können. Neukunden erhalten außerdem ein Guthaben von 300 $, um Arbeitslasten auszuführen, zu testen und bereitzustellen.
  2. Installieren Sie die Google Cloud CLI.

  3. Wenn Sie einen externen Identitätsanbieter (IdP) verwenden, müssen Sie sich zuerst mit Ihrer föderierten Identität in der gcloud CLI anmelden.

  4. Führen Sie den folgenden Befehl aus, um die gcloud CLI zu initialisieren:

    gcloud init
  5. Erstellen Sie ein Google Cloud Projekt oder wählen Sie eines aus.

    Rollen, die zum Auswählen oder Erstellen eines Projekts erforderlich sind

    • Projekt auswählen: Für die Auswahl eines Projekts ist keine bestimmte IAM-Rolle erforderlich. Sie können jedes Projekt auswählen, für das Ihnen eine Rolle zugewiesen wurde.
    • Projekt erstellen: Zum Erstellen eines Projekts benötigen Sie die Rolle „Projektersteller“ (roles/resourcemanager.projectCreator), die die Berechtigung resourcemanager.projects.create enthält. Weitere Informationen zum Zuweisen von Rollen
    • So erstellen Sie ein Google Cloud -Projekt:

      gcloud projects create PROJECT_ID

      Ersetzen Sie PROJECT_ID durch einen Namen für das Google Cloud -Projekt, das Sie erstellen.

    • Wählen Sie das von Ihnen erstellte Google Cloud Projekt aus:

      gcloud config set project PROJECT_ID

      Ersetzen Sie PROJECT_ID durch den Namen Ihres Projekts in Google Cloud .

  6. Prüfen Sie, ob für Ihr Google Cloud Projekt die Abrechnung aktiviert ist.

  7. Aktivieren Sie die GKE API:

    Rollen, die zum Aktivieren von APIs erforderlich sind

    Zum Aktivieren von APIs benötigen Sie die IAM-Rolle „Service Usage-Administrator“ (roles/serviceusage.serviceUsageAdmin), die die Berechtigung serviceusage.services.enable enthält. Weitere Informationen zum Zuweisen von Rollen

    gcloud services enable container.googleapis.com
  8. Installieren Sie die Google Cloud CLI.

  9. Wenn Sie einen externen Identitätsanbieter (IdP) verwenden, müssen Sie sich zuerst mit Ihrer föderierten Identität in der gcloud CLI anmelden.

  10. Führen Sie den folgenden Befehl aus, um die gcloud CLI zu initialisieren:

    gcloud init
  11. Erstellen Sie ein Google Cloud Projekt oder wählen Sie eines aus.

    Rollen, die zum Auswählen oder Erstellen eines Projekts erforderlich sind

    • Projekt auswählen: Für die Auswahl eines Projekts ist keine bestimmte IAM-Rolle erforderlich. Sie können jedes Projekt auswählen, für das Ihnen eine Rolle zugewiesen wurde.
    • Projekt erstellen: Zum Erstellen eines Projekts benötigen Sie die Rolle „Projektersteller“ (roles/resourcemanager.projectCreator), die die Berechtigung resourcemanager.projects.create enthält. Weitere Informationen zum Zuweisen von Rollen
    • So erstellen Sie ein Google Cloud -Projekt:

      gcloud projects create PROJECT_ID

      Ersetzen Sie PROJECT_ID durch einen Namen für das Google Cloud -Projekt, das Sie erstellen.

    • Wählen Sie das von Ihnen erstellte Google Cloud Projekt aus:

      gcloud config set project PROJECT_ID

      Ersetzen Sie PROJECT_ID durch den Namen Ihres Projekts in Google Cloud .

  12. Prüfen Sie, ob für Ihr Google Cloud Projekt die Abrechnung aktiviert ist.

  13. Aktivieren Sie die GKE API:

    Rollen, die zum Aktivieren von APIs erforderlich sind

    Zum Aktivieren von APIs benötigen Sie die IAM-Rolle „Service Usage-Administrator“ (roles/serviceusage.serviceUsageAdmin), die die Berechtigung serviceusage.services.enable enthält. Weitere Informationen zum Zuweisen von Rollen

    gcloud services enable container.googleapis.com
  14. Weisen Sie Ihrem Nutzerkonto Rollen zu. Führen Sie den folgenden Befehl für jede der folgenden IAM-Rollen einmal aus: roles/container.clusterAdmin, roles/container.admin

    gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE

    Ersetzen Sie Folgendes:

    • PROJECT_ID: Ihre Projekt-ID.
    • USER_IDENTIFIER: Die Kennung für Ihr Nutzerkonto . Beispiel: myemail@example.com
    • ROLE: Die IAM-Rolle, die Sie Ihrem Nutzerkonto zuweisen.

Umgebung vorbereiten

So bereiten Sie die Umgebung vor:

  1. Starten Sie eine Cloud Shell-Sitzung über die Google Cloud Console. Klicken Sie dazu in der Google Cloud Console auf Symbol für die Cloud Shell-Aktivierung Cloud Shell aktivieren. Dadurch wird im unteren Bereich der Google Cloud Console eine Sitzung gestartet.

  2. 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 muss 1.30.1 oder höher sein.
  3. Klonen Sie das GitHub-Repository:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    
  4. Wechseln Sie in das Arbeitsverzeichnis:

    cd kubernetes-engine-samples/ai-ml/gke-ray/raytrain/pytorch-mnist
    
  5. Erstellen Sie eine virtuelle Python-Umgebung:

    python -m venv myenv && \
    source myenv/bin/activate
    
  6. Installieren Sie Ray.

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:

  1. Prüfen Sie das folgende Manifest:

    apiVersion: ray.io/v1
    kind: RayCluster
    metadata:
      name: pytorch-mnist-cluster
    spec:
      rayVersion: '2.37.0'
      headGroupSpec:
        rayStartParams:
          dashboard-host: '0.0.0.0'
        template:
          metadata:
          spec:
            containers:
            - name: ray-head
              image: rayproject/ray:2.37.0
              ports:
              - containerPort: 6379
                name: gcs
              - containerPort: 8265
                name: dashboard
              - containerPort: 10001
                name: client
              resources:
                limits:
                  cpu: "2"
                  ephemeral-storage: "9Gi"
                  memory: "4Gi"
                requests:
                  cpu: "2"
                  ephemeral-storage: "9Gi"
                  memory: "4Gi"
      workerGroupSpecs:
      - replicas: 4
        minReplicas: 1
        maxReplicas: 5
        groupName: worker-group
        rayStartParams: {}
        template:
          spec:
            containers:
            - name: ray-worker
              image: rayproject/ray:2.37.0
              resources:
                limits:
                  cpu: "4"
                  ephemeral-storage: "9Gi"
                  memory: "8Gi"
                requests:
                  cpu: "4"
                  ephemeral-storage: "9Gi"
                  memory: "8Gi"

    Dieses Manifest beschreibt eine benutzerdefinierte RayCluster-Ressource.

  2. Wenden Sie das Manifest auf Ihren GKE-Cluster an:

    kubectl apply -f ray-cluster.yaml
    
  3. 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 Spalte STATUS 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.

  1. 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
    
  2. Richten Sie eine Portweiterleitungssitzung zum Ray-Head ein:

    kubectl port-forward svc/pytorch-mnist-cluster-head-svc 8265:8265 2>&1 >/dev/null &
    
  3. 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:

  1. 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):
    ...
    ...
    
  2. 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 Wert COMPLETE hat. Dies kann 15 Minuten oder länger dauern.

  3. 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.

  1. Prüfen Sie das folgende Manifest:

    apiVersion: ray.io/v1
    kind: RayJob
    metadata:
      name: pytorch-mnist-job
    spec:
      shutdownAfterJobFinishes: true
      entrypoint: python ai-ml/gke-ray/raytrain/pytorch-mnist/train.py
      runtimeEnvYAML: |
        pip:
          - torch
          - torchvision
        working_dir: "https://github.com/GoogleCloudPlatform/kubernetes-engine-samples/archive/main.zip"
        env_vars:
          NUM_WORKERS: "4"
          CPUS_PER_WORKER: "2"
      rayClusterSpec:
        rayVersion: '2.37.0'
        headGroupSpec:
          rayStartParams: {}
          template:
            spec:
              containers:
                - name: ray-head
                  image: rayproject/ray:2.37.0
                  ports:
                    - containerPort: 6379
                      name: gcs-server
                    - containerPort: 8265
                      name: dashboard
                    - containerPort: 10001
                      name: client
                  resources:
                    limits:
                      cpu: "2"
                      ephemeral-storage: "9Gi"
                      memory: "4Gi"
                    requests:
                      cpu: "2"
                      ephemeral-storage: "9Gi"
                      memory: "4Gi"
        workerGroupSpecs:
          - replicas: 4
            minReplicas: 1
            maxReplicas: 5
            groupName: small-group
            rayStartParams: {}
            template:
              spec:
                containers:
                  - name: ray-worker
                    image: rayproject/ray:2.37.0
                    resources:
                      limits:
                        cpu: "4"
                        ephemeral-storage: "9Gi"
                        memory: "8Gi"
                      requests:
                        cpu: "4"
                        ephemeral-storage: "9Gi"
                        memory: "8Gi"

    Dieses Manifest beschreibt eine benutzerdefinierte RayJob-Ressource.

  2. Wenden Sie das Manifest auf Ihren GKE-Cluster an:

    kubectl apply -f ray-job.yaml
    
  3. 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-Ressource Running ist.

  4. 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
    -------------------------------
    
  5. 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-Ressource Complete ist.

Ray-Arbeitslasten beobachten

Wenn Sie Details zu Ihren RayJobs aufrufen möchten, können Sie in der Google Cloud Console den Abschnitt Kubernetes Engine > KI/ML > Jobs aufrufen.

RayJobs in der Google Cloud Console ansehen

Bereinigen

Projekt löschen

    Google Cloud -Projekt löschen:

    gcloud projects delete PROJECT_ID

Einzelne Ressourcen löschen

Wenn Sie ein vorhandenes Projekt verwendet haben und es nicht löschen möchten, können Sie die einzelnen Ressourcen löschen. Zum Löschen des Clusters geben Sie Folgendes ein:

gcloud container clusters delete ${CLUSTER_NAME}

Nächste Schritte

  • Referenzarchitekturen, Diagramme und Best Practices zu Google Cloud kennenlernen. Weitere Informationen zu Cloud Architecture Center