Pubblicare modelli Spark ML utilizzando Vertex AI

Last reviewed 2024-08-14 UTC

I data scientist e gli ingegneri di machine learning (ML) richiedono spesso un'architettura di pubblicazione sufficientemente veloce per soddisfare le esigenze di generazione di previsioni online (o in tempo reale) dai loro modelli di ML. Vertex AI è in grado di soddisfare questa esigenza.

Con Vertex AI puoi pubblicare modelli di diversi framework di ML. Per framework come TensorFlow, PyTorch, XGBoost e scikit-learn, Vertex AI fornisce container predefiniti in cui eseguire questi modelli di ML. Se non utilizzi già uno di questi framework ML, dovrai creare il tuo container personalizzato da utilizzare con Vertex AI.

Questo documento è rivolto agli utenti che devono creare un container personalizzato i propri modelli Spark ML. Questo documento include una descrizione dell'architettura di servizio necessaria per i contenitori personalizzati e un'implementazione di riferimento che mostra questa architettura per un modello Spark MLib.

Per ottenere il massimo dalla parte di implementazione di riferimento di questo documento, devi conoscere l'esportazione dei modelli Spark MLlib in formato MLeap, sapere come utilizzare Vertex AI per pubblicare le previsioni e avere esperienza nell'utilizzo delle immagini container.

Architettura

Sebbene i container predefiniti siano disponibili per alcuni framework ML, gli utenti di altri i framework ML, come Spark, devono creare container personalizzati in cui Vertex AI può eseguire previsioni. Il seguente diagramma illustra l'architettura di pubblicazione necessaria per pubblicare i modelli Spark MLib e altri modelli che richiedono un contenitore personalizzato:

L'architettura di pubblicazione del modello utilizzata nel documento.

Questa architettura include i seguenti componenti:

  • Cloud Storage: fornisce spazio di archiviazione per gli artefatti del modello necessari per l'esecuzione del modello. Per il modello Spark ML utilizzato nell'implementazione di riferimento inclusa, gli elementi del modello sono costituiti da un bundle MLeap e uno schema del modello.
  • Cloud Build: utilizza l'immagine del generatore per creare un'immagine container personalizzata chiamata immagine container di servizio. Il processo di compilazione compila e pacchettizza il codice di pubblicazione del modello, crea l'immagine del container di pubblicazione ed esegue il push l'immagine del container di distribuzione in Artifact Registry.
  • Artifact Registry: contiene i seguenti oggetti:
    • L'immagine container del generatore scala-sbt utilizzata da Cloud Build per creare l'immagine container di servizio.
    • L'immagine del container di servizio creata da Cloud Build.
  • Vertex AI: contiene il modello ML caricato da Cloud Storage. Il modello caricato è configurato con località degli artefatti del modello all'interno di Cloud Storage, dell'immagine container di distribuzione in Artifact Registry. Vertex AI include anche un endpoint a cui è stato eseguito il deployment del modello. Quando il modello di cui è stato eseguito il deployment nell'endpoint, risorse fisiche con il modello, in modo che quest'ultimo possa fornire previsioni online.

Nell'ambito dell'implementazione di questa architettura di pubblicazione, devi esportare il tuo modello ML per l'utilizzo da parte di altre applicazioni e definire la tua immagine del contenitore di pubblicazione. L'implementazione del riferimento fornita in questo documento fornisce il codice utilizzato per definire e creare l'immagine container di pubblicazione. Questo codice include anche gli artefatti del modello per un modello Spark ML esportato in precedenza. Con alcuni modifiche alla configurazione, puoi utilizzare questa implementazione di riferimento per i tuoi modelli Spark ML.

Tuttavia, puoi implementare questa architettura di pubblicazione autonomamente e non utilizzare come riferimento dell'implementazione. Se decidi di implementare la tua architettura, devi svolgere le seguenti operazioni:

  • Esporta il modello in modo che possa essere utilizzato da altre applicazioni. Questo processo dipende dai framework ML e dagli strumenti che usi. Ad esempio, potresti scegliere di esportare i modelli Spark MLlib creando un bundle MLeap come descritto nell'implementazione di riferimento. Puoi trovare altri esempi su come esportare i modelli in Esportazione degli artefatti del modello per la previsione.
  • Progetta l'immagine del container di pubblicazione in modo che soddisfi i requisiti dei container personalizzati che la rendono compatibile con Vertex AI. Il codice può essere nel linguaggio di programmazione che preferisci.
  • Impacchetta il codice in un formato file del pacchetto compatibile con il linguaggio di programmazione utilizzato. Ad esempio, puoi utilizzare un file JAR per il codice Java o un wheel Python per il codice Python.
  • Crea un'immagine container personalizzata in grado di gestire la tua modalità personalizzata le API nel tuo codice.

Implementazione dei riferimenti

La seguente implementazione di riferimento serve un modello Spark MLib che prevede la specie di iris in base alla lunghezza e alla larghezza dei sepali e dei petali del fiore.

Puoi trovare il modello utilizzato in questa implementazione nella directory example_model del repository vertex-ai-spark-ml-serving.git. La directory contiene gli artefatti del modello utilizzati container per eseguire previsioni e include i seguenti file:

  • Il file example_model/model.zip è un modello di regressione logistica che è stato creato utilizzando Spark MLlib, è stato addestrato utilizzando il set di dati Iris e infine è stato convertito in un bundle MLeap. Il modello prevede la specie un fiore di iris usando la lunghezza e la larghezza dei sepali e petali.
  • Il file example_model/schema.json è un file JSON che descrive lo schema del modello. Lo schema del modello descrive i campi di input previsti per le istanze di previsione e i campi di output per i risultati di previsione obbligatori per lo schema MLeap.

Utilizza il tuo modello Mlib

Per utilizzare il tuo modello con questa implementazione di riferimento, assicurati innanzitutto che il tuo modello Spark MLlib è stato esportato in un pacchetto MLeap. Quindi, per pubblicare il tuo modello Spark MLib, devi fornire il modello appropriato artefatti: il bundle MLeap e lo schema del modello.

Pacchetto MLeap

Il contenitore di pubblicazione determina la posizione del bundle MLeap utilizzando la variabile di ambiente AIP_STORAGE_URI che viene passata da Vertex AI al contenitore all'avvio. Il valore della variabile AIP_STORAGE_URI viene specificato quando carichi il modello in Vertex AI.

Schema modello

Lo schema del modello descrive le caratteristiche di input e l'output di previsione di un modello. Lo schema del modello è rappresentato utilizzando i dati JSON. Di seguito è riportato lo schema utilizzato in questa implementazione di riferimento per prevedere la specie di iris in base alla lunghezza e alla larghezza dei sepali e dei petali del fiore:

{
  "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"
    }
  ]
}

Nello schema di esempio, l'array input contiene i campi di input (colonne) per il modello mentre l'array output contiene i campi di output (colonne) da restituito dal modello. In entrambi gli array, ogni oggetto dell'array contiene le seguenti proprietà:

  • name: il nome del campo (colonna).
  • type: il tipo di campo (colonna). I tipi validi includono BOOLEAN, BYTE, DOUBLE, FLOAT, INTEGER, LONG, SHORT e STRING.
  • (Facoltativo) struct: la struttura dei campi, ad esempio uno scalare o uno array. Le strutture valide includono BASIC (tipo di scala), ARRAY (Spark Array), e VECTOR (Spark DenseVector). BASIC viene utilizzato se il campo struct non è presente.

Per passare lo schema del modello al contenitore di pubblicazione, puoi utilizzare uno dei seguenti metodi:

  • Specifica i dati JSON che definiscono lo schema nel campo MLEAP_SCHEMA variabile di ambiente. La variabile di ambiente MLEAP_SCHEMA deve i dati JSON e non un percorso di un file che contiene Schema JSON.
  • Archivia i dati JSON in un file denominato schema.json e crea questo file disponibili per il container all'indirizzo ${AIP_STORAGE_URI}/schema.json. Questo è il utilizzato per il modello MLib di esempio fornito con questo documentazione.

Se utilizzi entrambi i metodi per passare lo schema del modello al container di pubblicazione, I dati JSON archiviati nella variabile di ambiente MLEAP_SCHEMA richiedono la precedenza.

Costi

Questa implementazione di riferimento utilizza i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi in base all'utilizzo previsto, utilizza il Calcolatore prezzi.

Al termine di questa implementazione di riferimento, puoi evitare la fatturazione continua eliminando le risorse che hai creato. Per ulteriori informazioni, consulta la sezione Pulizia.

Prima di iniziare

  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. Individua il tuo ID progetto e impostalo in Cloud Shell.
    export PROJECT_ID=YOUR_PROJECT_ID
    gcloud config set project ${PROJECT_ID}
    

    Sostituisci YOUR_PROJECT_ID con l'ID progetto.

Crea l'immagine del builder scala-sbt

Utilizzi Cloud Build con Strumento per la creazione della community di scala-sbt per creare l'immagine container di pubblicazione. Questo processo di compilazione dipende dall'avere l'immagine del compilatore sbt-scala in Container Registry del progetto.

  1. In Cloud Shell, clona il repository cloud-builders-community:

    git clone https://github.com/GoogleCloudPlatform/cloud-builders-community.git
    
  2. Vai alla directory del progetto:

    cd cloud-builders-community/scala-sbt
    
  3. Crea l'immagine del builder scala-sbt ed eseguine il push in Container Registry:

    gcloud builds submit .
    

Crea l'immagine del container di pubblicazione

Vertex AI utilizza il contenitore di pubblicazione per eseguire le richieste di previsione per il modello di esempio. Il primo passaggio per creare l'immagine del contenitore di servizio è creare un repository Docker in Artifact Registry in cui archiviare l'immagine. Devi quindi concedere a Vertex AI la prenotazione per estrarre l'immagine del contenitore di pubblicazione dal repository. Dopo aver creato il repository e concedere le autorizzazioni, puoi creare l'immagine container di pubblicazione ed eseguire il push in Artifact Registry.

  1. In Cloud Shell, crea un repository Docker in Artifact Registry:

    REPOSITORY="vertex-ai-prediction"
    LOCATION="us-central1"
    
    gcloud artifacts repositories create $REPOSITORY \
        --repository-format=docker \
        --location=$LOCATION
    
  2. Concedi Ruolo Lettore Artifact Registry all'agente di servizio Vertex AI:

    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. Clona il repository spark-ml-serving:

    git clone https://github.com/GoogleCloudPlatform/vertex-ai-spark-ml-serving.git
    
  4. Vai alla directory del progetto:

    cd vertex-ai-spark-ml-serving
    
  5. Crea l'immagine del container di servizio nel tuo progetto:

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

    Il file cloudbuild.yaml specifica due generatori: il generatore scala-sbt e il generatore di immagini docker. Cloud Build utilizza il compilatorescala-sbt per compilare il codice di servizio del modello da Cloud Storage e poi per pacchettizzare il codice compilato in un file JAR eseguibile. Cloud Build utilizza il compilatore docker per creare l'immagine container di servizio contenente il file JAR. Dopo la pubblicazione dell'immagine container, viene eseguito il push dell'immagine su Artifact Registry.

Importa il modello in Vertex AI

Il container di pubblicazione legge gli artefatti del modello da Cloud Storage. Tu devi creare una posizione di archiviazione per questi artefatti prima di importare in Vertex AI. Quando poi importi il modello, è necessario sia la posizione di archiviazione dell'artefatto del modello che l'immagine container Artifact Registry.

  1. In Cloud Shell, crea un bucket per gli elementi del modello:

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

    Sostituisci YOUR_BUCKET_NAME con il nome del tuo bucket.

  2. Copia gli elementi del modello nel bucket:

    gcloud storage cp example_model/* gs://$BUCKET/example_model/
    
  3. Importa il modello 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"
    

    Nel comando gcloud ai models upload, il valore del parametro --artifact-uri specifica il valore della variabile AIP_STORAGE_URI. Questa variabile fornisce la posizione del bundle MLeap che viene importato in Vertex AI.

esegui il deployment del modello su un nuovo endpoint

Affinché Vertex AI possa eseguire le previsioni, il modello importato deve essere eseguito su un endpoint. Sono necessari sia l'ID dell'endpoint che l'ID del modello quando esegui il deployment del modello.

  1. In Cloud Shell, crea l'endpoint del modello:

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

    Lo strumento a riga di comando gcloud potrebbe richiedere alcuni secondi per creare l'endpoint.

  2. Recupera l'ID dell'endpoint appena creato:

    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. Recupera l'ID del modello importato nella Importa il modello in Vertex AI sezione:

    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. Esegui il deployment del modello nell'endpoint:

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

    Il comando gcloud esegue il deployment del modello nell'endpoint. I valori predefiniti sono utilizzata per il tipo di risorsa della macchina, il numero minimo e massimo di nodi e altre opzioni di configurazione. Per ulteriori informazioni sul deployment, per i modelli, consulta le Documentazione di Vertex AI.

Testa l'endpoint

Dopo aver eseguito il deployment del modello nell'endpoint, puoi testare l'implementazione. Per testare l'endpoint, puoi utilizzare il client di esempio incluso nel codice di implementazione di riferimento. Il client di esempio genera istanze di previsione e invia richieste di previsione all'endpoint. Ogni istanza di previsione contiene valori casuali per sepal_length, sepal_width, petal_length e petal_width. Per impostazione predefinita, il client di esempio combina più istanze di previsione in una singola richiesta. La risposta dell'endpoint include una previsione per ogni istanza inviata nella richiesta. La previsione contiene le probabilità per ogni classe nel set di dati Iris (setosa, versicolor e virginica).

  • In Cloud Shell, esegui il client di previsione di esempio:

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

    Quando esegui lo script per la prima volta, viene creato un file Python un ambiente virtuale e installa le dipendenze. Dopo l'installazione le dipendenze, lo script esegue il client di esempio. Per ogni richiesta, il client stampa le istanze di previsione e le probabilità delle classi corrispondenti al terminale. Di seguito è riportato un estratto dell'output:

    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
    

Esegui la pulizia

Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questa implementazione di riferimento, elimina il progetto che contiene le risorse oppure mantieni il progetto ed elimina le singole risorse.

Elimina il progetto

  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.

Elimina singole risorse

  1. In Cloud Shell, annulla il deployment del modello dall'endpoint:

    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. Elimina l'endpoint:

    gcloud ai endpoints delete $ENDPOINT_ID \
        --region=$REGION \
        --quiet
    
  3. Elimina il modello:

    gcloud ai models delete $MODEL_ID \
        --region=$REGION
    
  4. Elimina l'immagine del container di pubblicazione:

    gcloud artifacts docker images delete \
        $LOCATION-docker.pkg.dev/$PROJECT_ID/$REPOSITORY/$IMAGE \
        --delete-tags \
        --quiet
    
  5. Elimina il contenitore del generatore scala-sbt:

    gcloud container images delete gcr.io/$PROJECT_ID/scala-sbt \
        --force-delete-tags \
        --quiet
    
  6. Elimina tutti i bucket Cloud Storage che non sono più necessari:

    gcloud storage rm YOUR_BUCKET_NAME --recursive
    

    L'eliminazione di un bucket comporta anche l'eliminazione di tutti gli oggetti archiviati al suo interno. I bucket e gli oggetti eliminati non possono essere recuperati dopo l'eliminazione.

Passaggi successivi