Elaborazione di immagini con distribuzioni di modelli batch
SI APPLICA A:Estensione ML dell'interfaccia della riga di comando di Azure v2 (corrente)Python SDK azure-ai-ml v2 (corrente)
Le distribuzioni di modelli batch possono essere usate per l'elaborazione di dati tabulari, ma anche qualsiasi altro tipo di file, ad esempio immagini. Queste distribuzioni sono supportate sia in MLflow sia in modelli personalizzati. In questa esercitazione si apprenderà come distribuire un modello che classifica le immagini in base alla tassonomia imageNet.
Informazioni sull'esempio
Il modello con cui verrà usato è stato creato usando TensorFlow insieme all'architettura RestNet (mapping di identità in reti residui profonde). Un esempio di questo modello può essere scaricato da qui. Il modello presenta i vincoli seguenti che è importante tenere presente per la distribuzione:
- Funziona con immagini di dimensioni 244x244 (tensori di
(224, 224, 3)
). - Richiede che gli input vengano ridimensionati nell'intervallo
[0,1]
.
Le informazioni contenute in questo articolo si basano sugli esempi di codice contenuti nel repository azureml-examples. Per eseguire i comandi in locale senza dover copiare/incollare il file YAML e altri file, clonare il repository e quindi passare alla directory cli/endpoints/batch/deploy-models/imagenet-classifier
se si usa l'interfaccia della riga di comando di Azure o sdk/python/endpoints/batch/deploy-models/imagenet-classifier
se si usa l'SDK per Python.
git clone https://github.com/Azure/azureml-examples --depth 1
cd azureml-examples/cli/endpoints/batch/deploy-models/imagenet-classifier
Seguire la procedura in Jupyter Notebooks
È possibile seguire questo esempio in un notebook Jupyter. Nel repository clonato aprire il notebook: imagenet-classifier-batch.ipynb.
Prerequisiti
Prima di seguire la procedura descritta in questo articolo, assicurarsi di disporre dei prerequisiti seguenti:
Una sottoscrizione di Azure. Se non si ha una sottoscrizione di Azure, creare un account gratuito prima di iniziare. Provare la versione gratuita o a pagamento di Azure Machine Learning.
Un'area di lavoro di Azure Machine Learning. Se non è disponibile, usare la procedura descritta nell'articolo Gestire le aree di lavoro di Azure Machine Learning per crearne una.
Assicurarsi di disporre delle autorizzazioni seguenti nell'area di lavoro:
Creare o gestire endpoint e distribuzioni batch: usare un ruolo Proprietario, Collaboratore o Personalizzato che consenta
Microsoft.MachineLearningServices/workspaces/batchEndpoints/*
.Creare distribuzioni arm nel gruppo di risorse dell'area di lavoro: usare un ruolo Proprietario, Collaboratore o Personalizzato che consenta
Microsoft.Resources/deployments/write
nel gruppo di risorse in cui viene distribuita l'area di lavoro.
Per usare Azure Machine Learning, è necessario installare il software seguente:
L'Interfaccia della riga di comando di Azure e l'
ml
estensione per Azure Machine Learning.az extension add -n ml
Nota
Le distribuzioni dei componenti della pipeline per gli endpoint batch sono state introdotte nella versione 2.7 dell'estensione
ml
per l'interfaccia della riga di comando di Azure. Usareaz extension update --name ml
per ottenere l'ultima versione.
Connettersi all'area di lavoro
L'area di lavoro è la risorsa di primo livello per Azure Machine Learning, che fornisce una posizione centralizzata da cui gestire tutti gli artefatti creati quando si usa Azure Machine Learning. In questa sezione ci si connetterà all'area di lavoro in cui verranno eseguite le attività di distribuzione.
Passare i valori per l'ID sottoscrizione, l'area di lavoro, la posizione e il gruppo di risorse nel codice seguente:
az account set --subscription <subscription>
az configure --defaults workspace=<workspace> group=<resource-group> location=<location>
Classificazione delle immagini con distribuzioni batch
In questo esempio si apprenderà come distribuire un modello di Deep Learning in grado di classificare una determinata immagine in base alla tassonomia di ImageNet.
Creare l'endpoint
Creare prima di tutto l'endpoint che ospiterà il modello:
Decidere il nome dell'endpoint:
ENDPOINT_NAME="imagenet-classifier-batch"
Il file YAML seguente definisce un endpoint batch:
endpoint.yml
$schema: https://azuremlschemas.azureedge.net/latest/batchEndpoint.schema.json
name: imagenet-classifier-batch
description: A batch endpoint for performing image classification using a TFHub model ImageNet model.
auth_mode: aad_token
Eseguire il codice seguente per creare l'endpoint.
az ml batch-endpoint create --file endpoint.yml --name $ENDPOINT_NAME
Registrazione del modello
Le distribuzioni di modelli possono distribuire solo i modelli registrati, quindi è necessario registrarla. È possibile ignorare questo passaggio se il modello che si sta tentando di distribuire è già registrato.
Download di una copia del modello:
wget https://azuremlexampledata.blob.core.windows.net/data/imagenet/model.zip unzip model.zip -d .
Registrare il modello:
MODEL_NAME='imagenet-classifier' az ml model create --name $MODEL_NAME --path "model"
Creazione di uno script di assegnazione dei punteggi
È necessario creare uno script di assegnazione dei punteggi in grado di leggere le immagini fornite dalla distribuzione batch e restituire i punteggi del modello. Lo script seguente:
- Indica una funzione
init
che carica il modello usando il modulokeras
intensorflow
. - Indica una funzione
run
eseguita per ogni mini batch fornito dalla distribuzione batch. - La funzione
run
legge un'immagine del file alla volta - Il metodo
run
ridimensiona le immagini alle dimensioni previste per il modello. - Il metodo
run
ridimensiona le immagini nell'intervallo di dominio[0,1]
, ovvero quello previsto dal modello. - Restituisce le classi e le probabilità associate alle stime.
code/score-by-file/batch_driver.py
import os
import numpy as np
import pandas as pd
import tensorflow as tf
from os.path import basename
from PIL import Image
from tensorflow.keras.models import load_model
def init():
global model
global input_width
global input_height
# AZUREML_MODEL_DIR is an environment variable created during deployment
model_path = os.path.join(os.environ["AZUREML_MODEL_DIR"], "model")
# load the model
model = load_model(model_path)
input_width = 244
input_height = 244
def run(mini_batch):
results = []
for image in mini_batch:
data = Image.open(image).resize(
(input_width, input_height)
) # Read and resize the image
data = np.array(data) / 255.0 # Normalize
data_batch = tf.expand_dims(
data, axis=0
) # create a batch of size (1, 244, 244, 3)
# perform inference
pred = model.predict(data_batch)
# Compute probabilities, classes and labels
pred_prob = tf.math.reduce_max(tf.math.softmax(pred, axis=-1)).numpy()
pred_class = tf.math.argmax(pred, axis=-1).numpy()
results.append([basename(image), pred_class[0], pred_prob])
return pd.DataFrame(results)
Suggerimento
Anche se le immagini vengono fornite in mini batch dalla distribuzione, questo script di assegnazione dei punteggi elabora un'immagine alla volta. Si tratta di un modello comune come il tentativo di caricare l'intero batch e inviarlo al modello contemporaneamente può comportare un utilizzo elevato della memoria sull'executor batch (exeptions OOM). Tuttavia, esistono alcuni casi in cui questa operazione abilita una velocità effettiva elevata nell'attività di assegnazione dei punteggi. Questo è il caso per le distribuzioni batch su un hardware GPU in cui si vuole ottenere un utilizzo elevato della GPU. Vedere Distribuzioni a velocità effettiva elevata per un esempio di script di assegnazione dei punteggi che ne sfrutta i vantaggi.
Nota
Se si sta provando a distribuire un modello generativo (uno che genera file), leggere come creare uno script di assegnazione dei punteggi come illustrato in Distribuzione di modelli che produce più file.
Creazione della distribuzione
Uno script di assegnazione dei punteggi viene creato, è il momento di creare una distribuzione batch per essa. Per crearlo, seguire questa procedura:
Assicurarsi di avere creato un cluster di calcolo in cui è possibile creare la distribuzione. In questo esempio si userà un cluster di calcolo denominato
gpu-cluster
. Anche se non è necessario, si usano GPU per velocizzare l'elaborazione.È necessario indicare l'ambiente in cui verrà eseguita la distribuzione. In questo caso, il modello viene eseguito in
TensorFlow
. Azure Machine Learning ha già un ambiente con il software necessario installato, quindi è possibile riutilizzare questo ambiente. Si aggiungeranno solo un paio di dipendenze in un file diconda.yml
.La definizione dell'ambiente verrà inclusa nel file di distribuzione.
compute: azureml:gpu-cluster environment: name: tensorflow212-cuda11-gpu image: mcr.microsoft.com/azureml/curated/tensorflow-2.12-cuda11:latest
A questo punto, è possibile creare la distribuzione.
Per creare una nuova distribuzione nell'endpoint creato, creare una
YAML
configurazione simile alla seguente. È possibile controllare lo schema YAML dell'endpoint batch completo per ottenere proprietà aggiuntive.$schema: https://azuremlschemas.azureedge.net/latest/modelBatchDeployment.schema.json endpoint_name: imagenet-classifier-batch name: imagenet-classifier-resnetv2 description: A ResNetV2 model architecture for performing ImageNet classification in batch type: model model: azureml:imagenet-classifier@latest compute: azureml:gpu-cluster environment: name: tensorflow212-cuda11-gpu image: mcr.microsoft.com/azureml/curated/tensorflow-2.12-cuda11:latest conda_file: environment/conda.yaml code_configuration: code: code/score-by-file scoring_script: batch_driver.py resources: instance_count: 2 settings: max_concurrency_per_instance: 1 mini_batch_size: 5 output_action: append_row output_file_name: predictions.csv retry_settings: max_retries: 3 timeout: 300 error_threshold: -1 logging_level: info
Creare quindi la distribuzione con il comando seguente:
az ml batch-deployment create --file deployment-by-file.yml --endpoint-name $ENDPOINT_NAME --set-default
Anche se è possibile richiamare una distribuzione specifica all'interno di un endpoint, in genere si vuole richiamare l'endpoint stesso e consentire all'endpoint di decidere quale distribuzione usare. Tale distribuzione è denominata distribuzione "predefinita". In questo modo è possibile modificare la distribuzione predefinita e quindi modificare il modello che gestisce la distribuzione senza modificare il contratto con l'utente che richiama l'endpoint. Usare l'istruzione seguente per aggiornare la distribuzione predefinita:
az ml batch-endpoint update --name $ENDPOINT_NAME --set defaults.deployment_name=$DEPLOYMENT_NAME
A questo punto, l'endpoint batch è pronto per essere usato.
Test della distribuzione
Per testare l'endpoint, si userà un esempio di 1000 immagini del set di dati ImageNet originale. Gli endpoint batch possono elaborare solo i dati che si trovano nel cloud e sono accessibili dall'area di lavoro di Azure Machine Learning. In questo esempio verranno caricati in un archivio dati di Azure Machine Learning. In particolare, verrà creato un asset di dati che può essere usato per richiamare l'endpoint per l'assegnazione dei punteggi. Si noti tuttavia che gli endpoint batch accettano dati che possono essere inseriti in più tipi di posizioni.
Scaricare i dati di esempio associati:
wget https://azuremlexampledata.blob.core.windows.net/data/imagenet/imagenet-1000.zip unzip imagenet-1000.zip -d data
A questo punto, creare l'asset di dati dai dati appena scaricati
Creare una definizione di asset di dati in
YAML
:imagenet-sample-unlabeled.yml
$schema: https://azuremlschemas.azureedge.net/latest/data.schema.json name: imagenet-sample-unlabeled description: A sample of 1000 images from the original ImageNet dataset. Download content from https://azuremlexampledata.blob.core.windows.net/data/imagenet-1000.zip. type: uri_folder path: data
Creare quindi l'asset di dati:
az ml data create -f imagenet-sample-unlabeled.yml
Ora che i dati sono stati caricati e pronti per l'uso, richiamare l'endpoint:
JOB_NAME=$(az ml batch-endpoint invoke --name $ENDPOINT_NAME --input azureml:imagenet-sample-unlabeled@latest --query name -o tsv)
Nota
L'utilità
jq
potrebbe non essere installata in ogni installazione. È possibile ottenere istruzioni in questo collegamento.Suggerimento
Si noti che non si indica il nome della distribuzione nell'operazione invoke. Questo perché l'endpoint instrada automaticamente il processo alla distribuzione predefinita. Poiché l'endpoint ha una sola distribuzione, quella predefinita è quella. È possibile specificare come destinazione una distribuzione specifica indicando l'argomento/parametro
deployment_name
.Un processo batch viene avviato non appena viene restituito il comando. È possibile monitorare lo stato del processo fino al termine dell'operazione:
az ml job show -n $JOB_NAME --web
Al termine della distribuzione, è possibile scaricare le stime:
Per scaricare le previsioni, usare il comando seguente:
az ml job download --name $JOB_NAME --output-name score --download-path ./
Le stime di output saranno simili alle seguenti. Si noti che le stime sono state combinate con le etichette per praticità del lettore. Per altre informazioni su come ottenere questo risultato, vedere il notebook associato.
import pandas as pd score = pd.read_csv("named-outputs/score/predictions.csv", header=None, names=['file', 'class', 'probabilities'], sep=' ') score['label'] = score['class'].apply(lambda pred: imagenet_labels[pred]) score
file class probabilità label n02088094_Afghan_hound.JPEG 161 0.994745 Levriero afghano n02088238_basset 162 0.999397 bassotto n02088364_beagle.JPEG 165 0.366914 bracco n02088466_bloodhound.JPEG 164 0.926464 segugio ... ... ... ...
Distribuzioni a velocità effettiva elevata
Come accennato in precedenza, la distribuzione appena creata elabora un'immagine alla volta, anche quando la distribuzione batch fornisce un batch di essi. Nella maggior parte dei casi questo è l'approccio migliore perché semplifica l'esecuzione dei modelli ed evita eventuali problemi di memoria insufficiente. Tuttavia, in alcuni altri potrebbe essere necessario saturare il più possibile l'utilizzo dell'hardware sottostante. Questo è il caso di GPU, ad esempio.
In questi casi, è possibile eseguire l'inferenza sull'intero batch di dati. Ciò implica il caricamento dell'intero set di immagini in memoria e l'invio diretto al modello. L'esempio seguente usa TensorFlow
per leggere batch di immagini e assegnare punteggi contemporaneamente. Usa anche operazioni TensorFlow
per eseguire la pre-elaborazione dei dati in modo che l'intera pipeline venga eseguita sullo stesso dispositivo usato (CPU/GPU).
Avviso
Alcuni modelli hanno una relazione non lineare con le dimensioni degli input in termini di consumo di memoria. Eseguire di nuovo batch (come fatto in questo esempio) o ridurre le dimensioni dei batch creati dalla distribuzione batch per evitare eccezioni di memoria insufficiente.
Creazione dello script di assegnazione dei punteggi:
code/score-by-batch/batch_driver.py
import os import numpy as np import pandas as pd import tensorflow as tf from tensorflow.keras.models import load_model def init(): global model global input_width global input_height # AZUREML_MODEL_DIR is an environment variable created during deployment model_path = os.path.join(os.environ["AZUREML_MODEL_DIR"], "model") # load the model model = load_model(model_path) input_width = 244 input_height = 244 def decode_img(file_path): file = tf.io.read_file(file_path) img = tf.io.decode_jpeg(file, channels=3) img = tf.image.resize(img, [input_width, input_height]) return img / 255.0 def run(mini_batch): images_ds = tf.data.Dataset.from_tensor_slices(mini_batch) images_ds = images_ds.map(decode_img).batch(64) # perform inference pred = model.predict(images_ds) # Compute probabilities, classes and labels pred_prob = tf.math.reduce_max(tf.math.softmax(pred, axis=-1)).numpy() pred_class = tf.math.argmax(pred, axis=-1).numpy() return pd.DataFrame( [mini_batch, pred_prob, pred_class], columns=["file", "probability", "class"] )
Suggerimento
- Si noti che questo script sta creando un set di dati tensor dal mini batch inviato dalla distribuzione batch. Questo set di dati viene pre-elaborato per ottenere i tensori previsti per il modello usando l'operazione
map
con la funzionedecode_img
. - Il set di dati viene nuovamente inviato in batch (16) per inviare i dati al modello. Usare questo parametro per controllare la quantità di informazioni che è possibile caricare in memoria e inviare al modello contemporaneamente. Se è in esecuzione in una GPU, è necessario ottimizzare attentamente questo parametro per ottenere l'utilizzo massimo della GPU subito prima di ottenere un'eccezione OOM.
- Una volta calcolate le stime, i tensori vengono convertiti in
numpy.ndarray
.
- Si noti che questo script sta creando un set di dati tensor dal mini batch inviato dalla distribuzione batch. Questo set di dati viene pre-elaborato per ottenere i tensori previsti per il modello usando l'operazione
A questo punto, è possibile creare la distribuzione.
Per creare una nuova distribuzione nell'endpoint creato, creare una
YAML
configurazione simile alla seguente. È possibile controllare lo schema YAML dell'endpoint batch completo per ottenere proprietà aggiuntive.$schema: https://azuremlschemas.azureedge.net/latest/modelBatchDeployment.schema.json endpoint_name: imagenet-classifier-batch name: imagenet-classifier-resnetv2 description: A ResNetV2 model architecture for performing ImageNet classification in batch type: model model: azureml:imagenet-classifier@latest compute: azureml:gpu-cluster environment: name: tensorflow212-cuda11-gpu image: mcr.microsoft.com/azureml/curated/tensorflow-2.12-cuda11:latest conda_file: environment/conda.yaml code_configuration: code: code/score-by-batch scoring_script: batch_driver.py resources: instance_count: 2 tags: device_acceleration: CUDA device_batching: 16 settings: max_concurrency_per_instance: 1 mini_batch_size: 5 output_action: append_row output_file_name: predictions.csv retry_settings: max_retries: 3 timeout: 300 error_threshold: -1 logging_level: info
Creare quindi la distribuzione con il comando seguente:
az ml batch-deployment create --file deployment-by-batch.yml --endpoint-name $ENDPOINT_NAME --set-default
È possibile usare questa nuova distribuzione con i dati di esempio mostrati in precedenza. Tenere presente che per richiamare questa distribuzione è necessario indicare il nome della distribuzione nel metodo di chiamata o impostarlo come predefinito.
Considerazioni per i modelli MLflow che elaborano immagini
I modelli MLflow negli endpoint batch supportano la lettura delle immagini come dati di input. Poiché le distribuzioni di MLflow non richiedono uno script di assegnazione dei punteggi, quando vengono usati, tenere presenti le considerazioni seguenti:
- I file di immagine supportati includono:
.png
,.jpg
,.jpeg
,.tiff
,.bmp
e.gif
. - I modelli MLflow dovrebbero ricevere un
np.ndarray
come input che corrisponderà alle dimensioni dell'immagine di input. Per supportare più dimensioni di immagine in ogni batch, l'executor batch richiamerà il modello MLflow una volta per ogni file di immagine. - I modelli MLflow sono altamente invitati a includere una firma e, se lo fanno, devono essere di tipo
TensorSpec
. Gli input vengono rimodellati in modo che corrispondano alla forma del tensore, se disponibile. Se non è disponibile alcuna firma, vengono dedotti tensori di tiponp.uint8
. - Per i modelli che includono una firma e devono gestire le dimensioni variabili delle immagini, quindi includere una firma che possa garantirla. Ad esempio, l'esempio di firma seguente consentirà batch di 3 immagini con canali.
import numpy as np
import mlflow
from mlflow.models.signature import ModelSignature
from mlflow.types.schema import Schema, TensorSpec
input_schema = Schema([
TensorSpec(np.dtype(np.uint8), (-1, -1, -1, 3)),
])
signature = ModelSignature(inputs=input_schema)
(...)
mlflow.<flavor>.log_model(..., signature=signature)
È possibile trovare un esempio funzionante nel notebook jupyter imagenet-classifier-mlflow.ipynb. Per altre informazioni su come usare i modelli MLflow nelle distribuzioni batch, leggere Uso di modelli MLflow nelle distribuzioni batch.