Spark ML-Modelle mit Vertex AI bereitstellen

Last reviewed 2024-08-14 UTC

Data Scientists und ML-Entwickler benötigen oft eine Bereitstellungsarchitektur, die schnell genug ist, um den Anforderungen des Generierens von Onlinevorhersagen (oder Echtzeitvorhersagen) aus ihren Modellen zu genügen. Vertex AI kann diese Anforderung erfüllen.

Mit Vertex AI können Sie Modelle aus einer Vielzahl von ML-Frameworks bereitstellen. Für Frameworks wie TensorFlow, PyTorch, XGBoost und scikit-learn bietet Vertex AI vordefinierte Container, in denen diese ML-Modelle ausgeführt werden können. Wenn Sie keines dieser ML-Frameworks verwenden, müssen Sie einen eigenen benutzerdefinierten Container für Vertex AI erstellen.

Dieses Dokument richtet sich an Nutzer, die einen benutzerdefinierten Container zum Bereitstellen ihrer Spark-ML-Modelle erstellen müssen. Das Dokument enthält sowohl eine Beschreibung der Bereitstellungsarchitektur, die für benutzerdefinierte Container benötigt wird, als auch eine Referenzimplementierung, die diese Architektur für ein Spark MLib-Modell veranschaulicht.

Damit Sie den Referenzimplementierungsteil dieses Dokuments optimal nutzen können, sollten Sie mit dem Export von Spark MLlib-Modellen in das MLeap-Format vertraut sein. Informieren Sie sich außerdem darüber, wie Vertex AI für das Bereitstellen von Vorhersagen verwendet wird und bringen Sie Erfahrung mit der Verwendung von Container-Images mit.

Architektur

Für einige ML-Frameworks sind vordefinierte Container verfügbar. Nutzer anderer ML-Frameworks wie Spark müssen jedoch benutzerdefinierte Container erstellen, in denen Vertex AI Vorhersagen ausführen kann. Das folgende Diagramm zeigt die Bereitstellungsarchitektur, die Sie zum Bereitstellen von Spark MLib-Modellen und anderen Modellen benötigen, für die ein benutzerdefinierter Container erforderlich ist:

Grafik: Die Bereitstellungsarchitektur für das Modell, das in der Dokument verwendet wird.

Diese Architektur umfasst die folgenden Komponenten:

  • Cloud Storage: bietet Speicher für die Modellartefakte, die zum Ausführen des Modells erforderlich sind. Bei dem in der zugehörigen Referenzimplementierung verwendeten Spark ML-Modell bestehen die Modellartefakte aus einem MLeap-Bundle und einem Modellschema.
  • Cloud Build:Hier wird das Builder-Image verwendet, um ein benutzerdefiniertes Container-Image zu erstellen, das Bereitstellungscontainer-Image genannt wird. Der Build-Prozess kompiliert und verpackt den Modellbereitstellungscode, erstellt das Bereitstellungscontainer-Image und überträgt das Bereitstellungscontainer-Image dann per Push an Artifact Registry.
  • Artifact Registry:Enthält die folgenden Objekte:
    • Das scala-sbt-Builder-Container-Image, das von Cloud Build zum Erstellen des Bereitstellungscontainer-Images verwendet wird.
    • Das Container-Image für die Bereitstellung, das von Cloud Build erstellt wird.
  • Vertex AI:Enthält das ML-Modell, das aus Cloud Storage hochgeladen wurde. Das hochgeladene Modell wird mit dem Speicherort der Modellartefakte in Cloud Storage und dem Speicherort des Bereitstellungscontainer-Images in Artifact Registry konfiguriert. Vertex AI enthält auch einen Endpunkt, auf dem das Modell bereitgestellt wurde. Nachdem das Modell auf dem Endpunkt bereitgestellt wurde, verknüpft Vertex AI physische Ressourcen mit dem Modell, damit es Onlinevorhersagen bereitstellen kann.

Im Rahmen dieser Implementierung dieser Bereitstellungs-Architektur müssen Sie Ihr ML-Modell für die Verwendung durch andere Anwendungen exportieren und ein eigenes Bereitstellungscontainer-Image definieren. Die in diesem Dokument bereitgestellte Referenzimplementierung enthält den Code, mit dem das Serving-Container-Image definiert und erstellt wird. Dieser Code enthält auch die Modellartefakte für ein zuvor exportiertes Spark ML-Modell. Mit einigen Konfigurationsänderungen können Sie diese Referenzimplementierung verwenden, um Ihre eigenen Spark-ML-Modelle bereitzustellen.

Sie können diese Bereitstellungsarchitektur jedoch für sich genommen implementieren und nicht die Referenzimplementierung verwenden. Wenn Sie sich für die Implementierung einer eigenen Architektur entscheiden, müssen Sie Folgendes tun:

  • Exportieren Sie Ihr Modell, damit es von anderen Anwendungen verwendet werden kann. Dieser Prozess hängt von den verwendeten ML-Frameworks und -Tools ab. Sie können beispielsweise Ihre Spark MLlib-Modelle exportieren, indem Sie ein MLeap-Bundle erstellen, wie in der Referenzimplementierung beschrieben. Weitere Beispiele zum Exportieren von Modellen finden Sie unter Modellartefakte zur Vorhersage exportieren.
  • Entwerfen Sie Ihr Bereitstellungs-Container-Image so, dass es die Anforderungen für benutzerdefinierte Container erfüllt, die es mit Vertex AI kompatibel machen. Der Code kann in einer beliebigen Programmiersprache geschrieben sein.
  • Verpacken Sie den Code in einem Paketdateiformat, das mit der von Ihnen verwendeten Programmiersprache kompatibel ist. Sie können beispielsweise eine JAR-Datei für Java-Code oder ein Python Wheel für Python-Code verwenden.
  • Erstellen Sie ein benutzerdefiniertes Container-Image, mit dem Ihr benutzerdefinierter Moduscode bereitgestellt werden kann.

Referenzimplementierung

Die folgende Referenzimplementierung stellt ein Spark-MLib-Modell bereit, das die Art der Schwertlilie anhand der Länge und Breite der Kelchblätter und der Blütenblätter der jeweiligen Pflanze vorhersagt.

Das in dieser Implementierung verwendete Modell finden Sie im Verzeichnis example_model des Repositorys vertex-ai-spark-ml-serving.git. Das Verzeichnis enthält die Modellartefakte, die vom Bereitstellungscontainer zum Ausführen von Vorhersagen verwendet werden. Außerdem enthält es die folgenden Dateien:

  • Die Datei example_model/model.zip ist ein logistisches Regressionsmodell, das mit Spark MLlib erstellt, mit dem Iris-Dataset trainiert und in ein MLeap-Bundle konvertiert wurde. Das Modell sagt die Art der Schwertlilie (Iris) anhand der Länge und Breite der Kelchblätter (Sepalen) und der Kronblätter (Petalen) vorher.
  • Die Datei example_model/schema.json ist eine JSON-Datei, die das Modellschema beschreibt. Das Modellschema beschreibt die erwarteten Eingabefelder für Vorhersageinstanzen und Ausgabefelder für Vorhersageergebnisse, die für das MLeap-Schema erforderlich sind.

Eigenes Mlib-Modell verwenden

Wenn Sie Ihr eigenes Modell mit dieser Referenzimplementierung verwenden möchten, müssen Sie zuerst dafür sorgen, dass Ihr Spark MLlib-Modell in ein MLeap-Bundle exportiert wurde. Wenn Sie Ihr Spark MLlib-Modell bereitstellen möchten, müssen Sie die entsprechenden Modellartefakte bereitstellen: das MLeap-Bundle und das Modellschema.

MLeap-Bundle

Der Bereitstellungscontainer ermittelt den Speicherort des MLeap-Bundles mithilfe der Umgebungsvariable AIP_STORAGE_URI, die beim Start von Vertex AI an den Container übergeben wird. Der Wert der Variablen AIP_STORAGE_URI wird angegeben, wenn Sie das Modell in Vertex AI hochladen.

Modellschema

Das Modellschema beschreibt die Eingabefeatures und die Vorhersageausgabe eines Modells. Das Modellschema wird mithilfe von JSON-Daten dargestellt. Im Folgenden finden Sie das Schema das in dieser Referenzimplementierung verwendet wird, um die Art der Schwertlilie anhand der Länge und Breite der Kelchblätter und Blütenblätter der jeweiligen Blume vorherzusagen:

{
  "input": [
    {
      "name": "sepal_length",
      "type": "FLOAT"
    },
    {
      "name": "sepal_width",
      "type": "FLOAT"
    },
    {
      "name": "petal_length",
      "type": "FLOAT"
    },
    {
      "name": "petal_width",
      "type": "FLOAT"
    }
  ],
  "output": [
    {
      "name": "probability",
      "type": "DOUBLE",
      "struct": "VECTOR"
    }
  ]
}

Im Beispielschema enthält das Array input die Eingabefelder (Spalten) für das Modell, während das Array output die Ausgabefelder (Spalten) enthält, die vom Modell zurückgegeben werden sollen. In beiden Arrays enthält jedes Objekt des Arrays die folgenden Attribute:

  • name: Der Name des Felds (Spalte).
  • type: Der Typ des Felds (Spalte). Gültige Typen sind BOOLEAN, BYTE, DOUBLE, FLOAT, INTEGER, LONG, SHORT und STRING.
  • (Optional) struct: Die Feldstruktur, z. B. ein Skalar oder ein Array. Gültige Strukturen sind BASIC (Skalartyp), ARRAY (Spark Array) und VECTOR (Spark DenseVector). BASIC wird verwendet, wenn das Feld struct nicht vorhanden ist.

Sie können eine der folgenden Methoden verwenden, um das Modellschema an den Bereitstellungscontainer zu übergeben:

  • Geben Sie die JSON-Daten an, die das Schema in der Umgebungsvariable MLEAP_SCHEMA definieren. Die Umgebungsvariable MLEAP_SCHEMA sollte die JSON-Daten selbst enthalten und keinen Pfad zu einer Datei, die das JSON-Schema enthält.
  • Speichern Sie die JSON-Daten in einer Datei mit dem Namen schema.json und stellen Sie diese Datei dem Container unter ${AIP_STORAGE_URI}/schema.json zur Verfügung. Diese Methode wird für das Beispiel-MLlib-Modell verwendet, das in dieser Dokumentation enthalten ist.

Wenn Sie beide Methoden verwenden, um das Modellschema an den Bereitstellungscontainer zu übergeben, haben die in der Umgebungsvariable MLEAP_SCHEMA gespeicherten JSON-Daten Vorrang.

Kosten

Für diese Referenzimplementierung werden die folgenden kostenpflichtigen Komponenten von Google Cloud verwendet:

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

Nach Abschluss dieser Implementierung können Sie weitere Kosten vermeiden, indem Sie die erstellten Ressourcen löschen. Weitere Informationen finden Sie unter Bereinigen.

Hinweise

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  2. Make sure that billing is enabled for your Google Cloud project.

  3. Enable the Vertex AI, Cloud Build, Cloud Storage, and Artifact Registry APIs.

    Enable the APIs

  4. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

  5. Suchen Sie Ihre Projekt-ID und legen Sie sie in Cloud Shell fest.
    export PROJECT_ID=YOUR_PROJECT_ID
    gcloud config set project ${PROJECT_ID}
    

    Ersetzen Sie YOUR_PROJECT_ID durch Ihre Projekt-ID.

Scala-SBT-Builder-Image erstellen

Sie verwenden Cloud Build mit dem scala-sbt-Community-Builder, um das Bereitstellungscontainer-Image zu erstellen. Dieser Build-Prozess hängt davon ab, ob sich das sbt-scala-Builder-Image in der Container Registry Ihres Projekts befindet.

  1. Klonen Sie in Cloud Shell das Repository cloud-builders-community:

    git clone https://github.com/GoogleCloudPlatform/cloud-builders-community.git
    
  2. Wechseln Sie zum Projektverzeichnis:

    cd cloud-builders-community/scala-sbt
    
  3. Erstellen Sie das Builder-Image scala-sbt und übertragen Sie es per Push in Container Registry:

    gcloud builds submit .
    

Container-Image bereitstellen

Vertex AI verwendet den Bereitstellungscontainer, um Vorhersageanfragen für das Beispielmodell auszuführen. Ein erster Schritt zum Erstellen des Container-Images ist, ein Docker-Repository in Artifact Registry zu erstellen, in dem das Image gespeichert werden soll. Anschließend müssen Sie Vertex AI die Berechtigung erteilen, das Image des Bereitstellungscontainers aus dem Repository abzurufen. Nachdem Sie das Repository erstellt und Berechtigungen erteilt haben, können Sie das Bereitstellungscontainer-Image erstellen und es per Push in die Artifact Registry senden.

  1. In Cloud Shell erstellen Sie ein Docker-Repository in Artifact Registry:

    REPOSITORY="vertex-ai-prediction"
    LOCATION="us-central1"
    
    gcloud artifacts repositories create $REPOSITORY \
        --repository-format=docker \
        --location=$LOCATION
    
  2. Weisen Sie dem Vertex AI-Dienst-Agent die Rolle „Artifact Registry-Leser“ zu:

    PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID \
        --format="value(projectNumber)")
    SERVICE_ACCOUNT="service-$PROJECT_NUMBER@gcp-sa-aiplatform.iam.gserviceaccount.com"
    
    gcloud projects add-iam-policy-binding $PROJECT_ID \
        --member="serviceAccount:$SERVICE_ACCOUNT" \
        --role="roles/artifactregistry.reader"
    
  3. Klonen Sie das Repository spark-ml-serving:

    git clone https://github.com/GoogleCloudPlatform/vertex-ai-spark-ml-serving.git
    
  4. Wechseln Sie zum Projektverzeichnis:

    cd vertex-ai-spark-ml-serving
    
  5. Erstellen Sie das Bereitstellungscontainer-Image in Ihrem Projekt:

    IMAGE=spark-ml-serving
    
    gcloud builds submit --config=cloudbuild.yaml \
        --substitutions="_LOCATION=$LOCATION,_REPOSITORY=$REPOSITORY,_IMAGE=$IMAGE" .
    

    Die Datei cloudbuild.yaml gibt zwei Builder an: den scala-sbt-Builder und den docker-Image-Builder. Cloud Build verwendet den Builder scala-sbt, um den Code zur Modellbereitstellung aus Cloud Storage zu kompilieren, und verpackt dann den kompilierten Code in eine ausführbare JAR-Datei. Cloud Build verwendet den Builder docker, um das Bereitstellungscontainer-Image zu erstellen, das die JAR-Datei enthält. Nachdem das Bereitstellungscontainer-Image erstellt wurde, wird das Image per Push an Artifact Registry übertragen.

Modell in Vertex AI importieren

Der Bereitstellungscontainer liest Modellartefakte aus Cloud Storage. Sie müssen einen Speicherort für diese Artefakte erstellen, bevor Sie das Modell in Vertex AI importieren. Wenn Sie dann das Modell importieren, benötigen Sie sowohl den Speicherort des Modellartefakts als auch das Bereitstellungscontainer-Image in Artifact Registry.

  1. Erstellen Sie in Cloud Shell einen Bucket für die Modellartefakte:

    REGION="us-central1"
    BUCKET="YOUR_BUCKET_NAME"
    gcloud storage buckets create gs://$BUCKET --location=$REGION
    

    Ersetzen Sie YOUR_BUCKET_NAME durch den Namen Ihres Buckets:

  2. Kopieren Sie die Modellartefakte in den Bucket:

    gcloud storage cp example_model/* gs://$BUCKET/example_model/
    
  3. Importieren Sie das Modell in Vertex AI:

    DISPLAY_NAME="iris-$(date +'%Y%m%d%H%M%S')"
    IMAGE_URI="${LOCATION}-docker.pkg.dev/$PROJECT_ID/${REPOSITORY}/${IMAGE}"
    ARTIFACT_URI="gs://$BUCKET/example_model/"
    
    gcloud ai models upload \
        --region=$REGION \
        --display-name=$DISPLAY_NAME \
        --container-image-uri=$IMAGE_URI \
        --artifact-uri=$ARTIFACT_URI \
        --container-health-route="/health" \
        --container-predict-route="/predict"
    

    Im Befehl gcloud ai models upload gibt der Wert des Parameters --artifact-uri den Wert der Variable AIP_STORAGE_URI an. Diese Variable gibt den Speicherort des MLeap-Bundles an, das in Vertex AI importiert wird.

Modell auf einem neuen Endpunkt bereitstellen

Damit Vertex AI Vorhersagen ausführen kann, muss das importierte Modell auf einem Endpunkt bereitgestellt werden. Sie benötigen sowohl die Endpunkt-ID als auch die Modell-ID, wenn Sie das Modell bereitstellen.

  1. Erstellen Sie in Cloud Shell den Modellendpunkt:

    gcloud ai endpoints create \
        --region=$REGION \
        --display-name=$DISPLAY_NAME
    

    Das Erstellen des Endpunkts mit dem gcloud-Befehlszeilentool kann einige Sekunden dauern.

  2. Rufen Sie die Endpunkt-ID des neu erstellten Endpunkts ab:

    ENDPOINT_ID=$(gcloud ai endpoints list \
        --region=$REGION \
        --filter=display_name=$DISPLAY_NAME \
        --format='value(name)')
    
    # Print ENDPOINT_ID to the console
    echo "Your endpoint ID is: $ENDPOINT_ID"
    
  3. Rufen Sie die Modell-ID des Modells ab, das Sie im Abschnitt Modell in Vertex AI importieren importiert haben:

    MODEL_ID=$(gcloud ai models list \
        --region=$REGION \
        --filter=display_name=$DISPLAY_NAME \
        --format='value(name)')
    
    # Print MODEL_ID to the console
    echo "Your model ID is: $MODEL_ID"
    
  4. Stellen Sie das Modell für den Endpunkt bereit:

    gcloud ai endpoints deploy-model $ENDPOINT_ID \
        --region=$REGION \
        --model=$MODEL_ID \
        --display-name=$DISPLAY_NAME \
        --traffic-split="0=100"
    

    Mit dem Befehl gcloud wird das Modell auf dem Endpunkt bereitgestellt. Standardwerte werden für den Ressourcentyp des Computers, die Mindest- und Höchstanzahl von Knoten und andere Konfigurationsoptionen verwendet. Weitere Informationen zu Bereitstellungsoptionen für Modelle finden Sie in der Dokumentation zu Vertex AI.

Endpunkt testen

Nachdem Sie das Modell auf dem Endpunkt bereitgestellt haben, können Sie Ihre Implementierung testen. Zum Testen des Endpunkts können Sie den Beispielclient verwenden, der im Code der Referenzimplementierung enthalten ist. Der Beispielclient generiert Vorhersageinstanzen und sendet Vorhersageanfragen an den Endpunkt. Jede Vorhersageinstanz enthält zufällige Werte für sepal_length, sepal_width, petal_length und petal_width. Standardmäßig kombiniert der Beispielclient mehrere Vorhersageinstanzen zu einer einzigen Anfrage. Die Endpunktantwort enthält eine Vorhersage für jede Instanz, die in der Anfrage gesendet wird. Die Vorhersage enthält die Wahrscheinlichkeiten für jede Klasse im Iris-Dataset (setosa, versicolor und virginica).

  • Führen Sie in Cloud Shell den Beispielvorhersageclient aus:

    cd example_client
    ./run_client.sh --project $PROJECT_ID \
        --location $LOCATION \
        --endpoint $ENDPOINT_ID
    

    Wenn Sie das Script zum ersten Mal ausführen, erstellt das Script eine virtuelle Python-Umgebung und installiert Abhängigkeiten. Nach der Installation der Abhängigkeiten führt das Script den Beispielclient aus. Für jede Anfrage gibt der Client die Vorhersageinstanzen und die entsprechenden Klassenwahrscheinlichkeiten an das Terminal aus. Das folgende Beispiel zeigt einen Auszug:

    Sending 10 asynchronous prediction requests with 3 instances per request ...
    
    ==> Response from request #10:
    
    Instance 1:     sepal_length:   5.925825137450266
                    sepal_width:    4.5047557888651
                    petal_length:   1.0432434310300223
                    petal_width:    0.5050397721287457
    
    Prediction 1:   setosa:         0.2036041134824573
                    versicolor:     0.6062980065549213
                    virginica:      0.1900978799626214
    
    Instance 2:     sepal_length:   6.121228622484405
                    sepal_width:    3.406317728235072
                    petal_length:   3.178583759980504
                    petal_width:    2.815141143581328
    
    Prediction 2:   setosa:         0.471811302254083
                    versicolor:     0.2063720436033448
                    virginica:      0.3218166541425723
    
    Instance 3:     sepal_length:   7.005781590327274
                    sepal_width:    2.532116893508745
                    petal_length:   2.6351337947193474
                    petal_width:    2.270855223519198
    
    Prediction 3:   setosa:         0.453579051699638
                    versicolor:     0.2132869980698818
                    virginica:      0.3331339502304803
    

Bereinigen

Damit Ihrem Google Cloud-Konto die in dieser Verfahren verwendeten Ressourcen nicht in Rechnung gestellt werden, löschen Sie entweder das Projekt, das die Ressourcen enthält, oder Sie behalten das Projekt und löschen die einzelnen Ressourcen.

Projekt löschen

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Einzelne Ressourcen löschen

  1. Heben Sie die Bereitstellung des Modells in Cloud Shell auf dem Endpunkt auf:

    DEPLOYED_MODEL_ID=$(gcloud ai endpoints describe $ENDPOINT_ID \
        --region=$REGION \
        --format='value(deployedModels.id)')
    
    gcloud ai endpoints undeploy-model $ENDPOINT_ID \
        --region=$REGION \
        --deployed-model-id=$DEPLOYED_MODEL_ID
    
  2. Löschen Sie den Endpunkt:

    gcloud ai endpoints delete $ENDPOINT_ID \
        --region=$REGION \
        --quiet
    
  3. Löschen Sie das Modell:

    gcloud ai models delete $MODEL_ID \
        --region=$REGION
    
  4. Löschen Sie das Bereitstellungscontainer-Image:

    gcloud artifacts docker images delete \
        $LOCATION-docker.pkg.dev/$PROJECT_ID/$REPOSITORY/$IMAGE \
        --delete-tags \
        --quiet
    
  5. Löschen Sie den Builder-Container scala-sbt:

    gcloud container images delete gcr.io/$PROJECT_ID/scala-sbt \
        --force-delete-tags \
        --quiet
    
  6. Löschen Sie alle Cloud Storage-Buckets, die nicht mehr benötigt werden:

    gcloud storage rm YOUR_BUCKET_NAME --recursive
    

    Beim Löschen eines Buckets werden auch alle in diesem Bucket gespeicherten Objekte gelöscht. Gelöschte Buckets und Objekte können nach dem Löschen nicht wiederhergestellt werden.

Nächste Schritte