Deploying 🤗 ViT su Vertex AI

Implementazione 🤗 ViT su Vertex AI

Nelle precedenti pubblicazioni, abbiamo mostrato come distribuire un modello Vision Transformers (ViT) da 🤗 Transformers in locale e su un cluster Kubernetes . Questa pubblicazione ti mostrerà come distribuire lo stesso modello sulla piattaforma Vertex AI . Otterrai lo stesso livello di scalabilità della distribuzione basata su Kubernetes, ma con significativamente meno codice.

Questa pubblicazione si basa sulle due precedenti pubblicazioni collegate sopra. Ti consigliamo di darci un’occhiata se non lo hai già fatto.

Puoi trovare un esempio completamente sviluppato nel Notebook di Colab collegato all’inizio della pubblicazione.

Secondo Google Cloud :

Vertex AI fornisce strumenti per supportare l’intero flusso di lavoro di Machine Learning, attraverso diversi tipi di modelli e diversi livelli di competenza in ML.

Per quanto riguarda la distribuzione del modello, Vertex AI fornisce alcune importanti funzionalità con un design API unificato:

  • Autenticazione

  • Autoscaling basato sul traffico

  • Versioning del modello

  • Divisione del traffico tra diverse versioni di un modello

  • Limite di velocità

  • Monitoraggio e registrazione del modello

  • Supporto per le previsioni online e batch

Per i modelli TensorFlow, offre varie utility pronte all’uso, a cui accederai in questa pubblicazione. Ma supporta anche in modo simile altri framework come PyTorch e scikit-learn .

Per utilizzare Vertex AI, avrai bisogno di un progetto Google Cloud Platform (GCP) con attivazione della fatturazione e i seguenti servizi abilitati:

  • Vertex AI

  • Cloud Storage

Utilizzerai lo stesso modello ViT B/16 implementato in TensorFlow come hai fatto nelle ultime due pubblicazioni. Hai serializzato il modello con le relative operazioni di pre-elaborazione e post-elaborazione incorporate per ridurre lo scostamento tra addestramento e servizio . Fai riferimento alla prima pubblicazione che ne discute in dettaglio. La firma del SavedModel serializzato finale è la seguente:

Il SavedModel SignatureDef fornito contiene le seguenti voci di input:
  inputs['string_input'] tensor_info:
      dtype: DT_STRING
      shape: (-1)
      name: serving_default_string_input:0
Il SavedModel SignatureDef fornito contiene le seguenti voci di output:
  outputs['confidence'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1)
      name: StatefulPartitionedCall:0
  outputs['label'] tensor_info:
      dtype: DT_STRING
      shape: (-1)
      name: StatefulPartitionedCall:1
Il nome del metodo è: tensorflow/serving/predict

Il modello accetterà stringhe di immagini codificate in base64, eseguirà la pre-elaborazione, effettuerà l’inferenza e infine eseguirà le fasi di post-elaborazione. Le stringhe sono codificate in base64 per evitare eventuali modifiche durante la trasmissione in rete. La pre-elaborazione include il ridimensionamento dell’immagine di input a una risoluzione di 224×224, la standardizzazione nell’intervallo [-1, 1] e la trasposizione nel layout di memoria channels_first. La post-elaborazione include la mappatura dei logit predetti in etichette stringa.

Per effettuare una distribuzione su Vertex AI, è necessario mantenere gli artefatti del modello in un bucket Google Cloud Storage (GCS) . Il Notebook di Colab allegato mostra come creare un bucket GCS e salvare gli artefatti del modello al suo interno.

La figura sottostante mostra un flusso di lavoro pittorico per distribuire un modello TensorFlow già addestrato su Vertex AI.

Discutiamo ora cosa sono il Registro modelli di Vertex AI e il Punto di accesso.

Registro modelli di Vertex AI

Il Registro modelli di Vertex AI è un registro di modelli di machine learning completamente gestito. Ci sono un paio di cose da notare su cosa significa “completamente gestito” qui. Primo, non devi preoccuparti di come e dove vengono archiviati i modelli. In secondo luogo, gestisce diverse versioni dello stesso modello.

Queste funzionalità sono importanti per il machine learning in produzione. Costruire un registro di modelli che garantisca alta disponibilità e sicurezza non è banale. Inoltre, ci sono spesso situazioni in cui si desidera ripristinare il modello corrente a una versione precedente poiché non possiamo controllare l’interno di un modello di machine learning a scatola nera. Il Registro modelli di Vertex AI ci consente di raggiungere questi obiettivi senza troppa difficoltà.

I tipi di modelli attualmente supportati includono SavedModel da TensorFlow, scikit-learn e XGBoost.

Endpoint di Vertex AI

Dalla prospettiva dell’utente, l’Endpoint di Vertex AI fornisce semplicemente un endpoint per ricevere richieste e inviare risposte. Tuttavia, ha molte cose sotto il cofano che gli operatori di machine learning possono configurare. Ecco alcune delle configurazioni che puoi scegliere:

  • Versione di un modello

  • Specifiche di VM in termini di CPU, memoria e acceleratori

  • Numero minimo/massimo di nodi di calcolo

  • Percentuale di divisione del traffico

  • Lunghezza della finestra di monitoraggio del modello e i relativi obiettivi

  • Tasso di campionamento delle richieste di previsione

La libreria Python google-cloud-aiplatform fornisce API semplici per gestire il ciclo di vita di un deployment su Vertex AI. È diviso in quattro passaggi:

  1. caricamento di un modello
  2. creazione di un endpoint
  3. deploy del modello sull’endpoint
  4. effettuare richieste di previsione.

Durante questi passaggi, avrai bisogno dei moduli ModelServiceClient, EndpointServiceClient e PredictionServiceClient della libreria Python google-cloud-aiplatform per interagire con Vertex AI.

1. Il primo passaggio del flusso di lavoro consiste nel caricare il SavedModel nel registro dei modelli di Vertex AI:

tf28_gpu_model_dict = {
    "display_name": "Modello GPU ViT Base TF2.8",
    "artifact_uri": f"{GCS_BUCKET}/{LOCAL_MODEL_DIR}",
    "container_spec": {
        "image_uri": "us-docker.pkg.dev/vertex-ai/prediction/tf2-gpu.2-8:latest",
    },
}
tf28_gpu_model = (
    model_service_client.upload_model(parent=PARENT, model=tf28_gpu_model_dict)
    .result(timeout=180)
    .model
)

Analizziamo il codice pezzo per pezzo:

  • GCS_BUCKET indica il percorso del tuo bucket GCS in cui si trovano gli artefatti del modello (ad esempio, gs://hf-tf-vision ).

  • In container_spec , fornisci l’URI di un’immagine Docker che verrà utilizzata per fornire previsioni. Vertex AI fornisce immagini pre-costruite per servire modelli TensorFlow, ma puoi anche utilizzare le tue immagini Docker personalizzate quando utilizzi un framework diverso (un esempio ).

  • model_service_client è un oggetto ModelServiceClient che espone i metodi per caricare un modello nel Registro dei Modelli di Vertex AI.

  • PARENT è impostato su f"projects/{PROJECT_ID}/locations/{REGION}" che consente a Vertex AI di determinare dove il modello verrà posizionato all’interno di GCP.

2. Successivamente, è necessario creare un Endpoint di Vertex AI:

tf28_gpu_endpoint_dict = {
    "display_name": "Endpoint GPU ViT Base TF2.8",
}
tf28_gpu_endpoint = (
    endpoint_service_client.create_endpoint(
        parent=PARENT, endpoint=tf28_gpu_endpoint_dict
    )
    .result(timeout=300)
    .name
)

Qui stai utilizzando un oggetto endpoint_service_client che è un oggetto EndpointServiceClient. Ti consente di creare e configurare il tuo Endpoint di Vertex AI.

3. Ora sei pronto per effettuare il deployment effettivo!

tf28_gpu_deployed_model_dict = {
    "model": tf28_gpu_model,
    "display_name": "Modello deployato GPU ViT Base TF2.8",
    "dedicated_resources": {
        "min_replica_count": 1,
        "max_replica_count": 1,
        "machine_spec": {
            "machine_type": DEPLOY_COMPUTE, # "n1-standard-8"
            "accelerator_type": DEPLOY_GPU, # aip.AcceleratorType.NVIDIA_TESLA_T4
            "accelerator_count": 1,
        },
    },
}

tf28_gpu_deployed_model = endpoint_service_client.deploy_model(
    endpoint=tf28_gpu_endpoint,
    deployed_model=tf28_gpu_deployed_model_dict,
    traffic_split={"0": 100},
).result()

Qui, stai concatenando il modello che hai caricato nel Registro dei modelli di Vertex AI e l’Endpoint che hai creato nei passaggi precedenti. Innanzitutto, stai definendo le configurazioni del deployment sotto tf28_gpu_deployed_model_dict.

Sotto dedicated_resources stai configurando:

  • min_replica_count e max_replica_count che gestiscono gli aspetti di autoscaling del tuo deployment.

  • machine_spec ti consente di definire le configurazioni dell’hardware del deployment:

    • machine_type è il tipo di macchina di base che verrà utilizzato per eseguire l’immagine Docker. L’autoscaler sottostante scalera questa macchina in base al carico di traffico. Puoi scegliere uno tra i tipi di macchine supportati.

    • accelerator_type è l’acceleratore hardware che verrà utilizzato per eseguire l’inferenza.

    • accelerator_count indica il numero di acceleratori hardware da associare a ogni replica.

Nota che fornire un acceleratore non è un requisito per il deployment dei modelli su Vertex AI.

Successivamente, esegui il deployment dell’endpoint utilizzando le specifiche sopra indicate:

tf28_gpu_deployed_model = endpoint_service_client.deploy_model(
    endpoint=tf28_gpu_endpoint,
    deployed_model=tf28_gpu_deployed_model_dict,
    traffic_split={"0": 100},
).result()

Nota come stai definendo la suddivisione del traffico per il modello. Se avessi avuto più versioni del modello, avresti potuto definire un dizionario in cui le chiavi avrebbero indicato la versione del modello e i valori avrebbero indicato la percentuale di traffico che il modello deve gestire.

Con un Registro dei modelli e un’interfaccia dedicata per gestire gli Endpoints, Vertex AI ti consente di controllare facilmente gli aspetti importanti del deployment.

È necessario circa 15-30 minuti a Vertex AI per impostare il deployment. Una volta completato, dovresti poterlo vedere sulla console.

Se il tuo deployment è andato a buon fine, puoi testare l’Endpoint deployato effettuando una richiesta di previsione.

Prima, prepara una stringa di immagine codificata in base64:

import base64
import tensorflow as tf

image_path = tf.keras.utils.get_file(
    "image.jpg", "http://images.cocodataset.org/val2017/000000039769.jpg"
)
bytes = tf.io.read_file(image_path)
b64str = base64.b64encode(bytes.numpy()).decode("utf-8")

4. La seguente utility prepara prima una lista di istanze (solo un’istanza in questo caso) e quindi utilizza un client di servizio di previsione (di tipo PredictionServiceClient). serving_input è il nome della chiave di firma di input del modello servito. In questo caso, il serving_input è string_input, che puoi verificare dall’output della firma SavedModel mostrato sopra.

from google.protobuf import json_format
from google.protobuf.struct_pb2 import Value

def predict_image(image, endpoint, serving_input):
    # Il formato di ogni istanza deve conformarsi allo schema di input di previsione del modello deployato.
    instances_list = [{serving_input: {"b64": image}}]
    instances = [json_format.ParseDict(s, Value()) for s in instances_list]

    print(
        prediction_service_client.predict(
            endpoint=endpoint,
            instances=instances,
        )
    )

predict_image(b64str, tf28_gpu_endpoint, serving_input)

Per i modelli TensorFlow deployati su Vertex AI, il payload della richiesta deve essere formattato in un certo modo. Per modelli come ViT che trattano dati binari come immagini, devono essere codificati in base64. Secondo la guida ufficiale, il payload della richiesta per ogni istanza deve essere così:

{serving_input: {"b64": base64.b64encode(jpeg_data).decode()}}

L’utility predict_image() prepara il payload della richiesta conformemente a questa specifica.

Se tutto va bene con il deployment, quando chiami predict_image(), dovresti ottenere un output del genere:

predictions {
  struct_value {
    fields {
      key: "confidence"
      value {
        number_value: 0.896659553
      }
    }
    fields {
      key: "label"
      value {
        string_value: "Gatto egiziano"
      }
    }
  }
}
deployed_model_id: "5163311002082607104"
model: "projects/29880397572/locations/us-central1/models/7235960789184544768"
model_display_name: "Modello ViT Base TF2.8 GPU"

Nota, tuttavia, questa non è l’unico modo per ottenere previsioni utilizzando un Endpoint di Vertex AI. Se vai alla console degli Endpoint e selezioni il tuo endpoint, ti mostrerà due diversi modi per ottenere previsioni:

È anche possibile evitare le richieste cURL e ottenere previsioni in modo programmato senza utilizzare l’SDK di Vertex AI. Fai riferimento a questo notebook per saperne di più.

Ora che hai imparato come utilizzare Vertex AI per distribuire un modello TensorFlow, discutiamo ora alcune funzionalità utili fornite da Vertex AI. Queste ti aiutano a ottenere una visione più approfondita della tua distribuzione.

Vertex AI ti consente anche di monitorare il tuo modello senza alcuna configurazione. Dalla console degli Endpoint, puoi ottenere dettagli sulle prestazioni dell’Endpoint e sull’utilizzo delle risorse allocate.

Come si può vedere nel grafico sopra, per un breve periodo di tempo, il ciclo di utilizzo dell’acceleratore è stato circa del 100%, il che è un sollievo per gli occhi. Per il resto del tempo, non ci sono state richieste da elaborare, quindi le cose erano inattive.

Questo tipo di monitoraggio ti aiuta a individuare rapidamente l’Endpoint attualmente distribuito e apportare eventuali modifiche necessarie. È anche possibile richiedere il monitoraggio delle spiegazioni del modello. Fai riferimento qui per saperne di più.

Abbiamo effettuato un test di carico locale per comprendere meglio i limiti dell’Endpoint con Locust. La tabella di seguito riassume le statistiche delle richieste:

Tra tutte le diverse statistiche mostrate nella tabella, Average (ms) si riferisce alla latenza media dell’Endpoint. Locust ha inviato circa 17230 richieste e la latenza media segnalata è di 646 millisecondi, il che è impressionante. Nella pratica, si desidera simulare un traffico più reale effettuando il test di carico in modo distribuito. Fai riferimento qui per saperne di più.

Questa directory contiene tutte le informazioni necessarie per sapere come abbiamo effettuato il test di carico.

Puoi utilizzare l’estimatore dei costi di GCP per stimare il costo dell’utilizzo, e la tabella dei prezzi orari esatti può essere trovata qui. È importante notare che ti vengono addebitati solo quando il nodo sta elaborando le effettive richieste di previsione, e devi calcolare il prezzo con e senza GPU.

Per la previsione di Vertex per un modello addestrato personalizzato, è possibile scegliere tipi di macchine N1 da n1-standard-2 a n1-highcpu-32. In questo post hai utilizzato n1-standard-8 che è dotato di 8 vCPUs e 32 GB di RAM.

Inoltre, quando si allegano acceleratori al nodo di calcolo, verranno addebitati costi extra in base al tipo di acceleratore desiderato. In questo post del blog abbiamo utilizzato NVIDIA_TESLA_T4, ma sono supportati quasi tutti gli acceleratori moderni, inclusi i TPU. Puoi trovare ulteriori informazioni qui.

La collezione di modelli di visione TensorFlow in 🤗 Transformers sta crescendo. Ora supporta la segmentazione semantica all’avanguardia con SegFormer. Ti incoraggiamo a estendere il flusso di lavoro di distribuzione che hai appreso in questo post a modelli di segmentazione semantica come SegFormer.

In questo post, hai imparato come distribuire un modello Vision Transformer con la piattaforma Vertex AI utilizzando le facili API che fornisce. Hai anche appreso come le funzionalità di Vertex AI beneficiano del processo di distribuzione del modello, consentendoti di concentrarti su configurazioni dichiarative e rimuovendo le parti complesse. Vertex AI supporta anche la distribuzione di modelli PyTorch tramite percorsi di previsione personalizzati. Fai riferimento qui per ulteriori dettagli.

La serie ti ha introdotto per la prima volta a TensorFlow Serving per distribuire localmente un modello di visione da 🤗 Transformers. Nel secondo post, hai imparato come scalare quella distribuzione locale con Docker e Kubernetes. Speriamo che questa serie sulla distribuzione online di modelli di visione TensorFlow sia stata utile per portare il tuo set di strumenti di ML al livello successivo. Non vediamo l’ora di vedere cosa costruirai con questi strumenti.

Grazie al team del programma di relazioni con gli sviluppatori di ML di Google, che ci ha fornito crediti GCP per condurre gli esperimenti.

Parti del codice di distribuzione sono state prese da questo notebook del repository ufficiale di GitHub degli esempi di codice di Vertex AI.