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)
È possibile usare le distribuzioni di modelli batch 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 questo articolo si apprenderà come distribuire un modello che classifica le immagini in base alla tassonomia ImageNet.
Prerequisiti
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. Per creare un'area di lavoro, vedere Gestire le aree di lavoro di Azure Machine Learning.
Assicurarsi di disporre delle autorizzazioni seguenti nell'area di lavoro di Azure Machine Learning:
- Creare o gestire endpoint e distribuzioni batch: usare un ruolo di proprietario, collaboratore o personalizzato che consenta
Microsoft.MachineLearningServices/workspaces/batchEndpoints/*
. - Creare distribuzioni di Azure Resource Manager nel gruppo di risorse dell'area di lavoro: usare un ruolo di Proprietario, Contributore o Personalizzato che consenta
Microsoft.Resources/deployments/write
nel gruppo di risorse in cui viene distribuita l'area di lavoro.
- Creare o gestire endpoint e distribuzioni batch: usare un ruolo di proprietario, collaboratore o personalizzato che consenta
Installare il software seguente per usare Azure Machine Learning:
Eseguire il comando seguente per installare l'interfaccia della riga di comando di Azure e l'
ml
estensione per Azure Machine Learning:az extension add -n ml
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. Usare il comandoaz extension update --name ml
per ottenere la versione più recente.
Connettersi all'area di lavoro
L'area di lavoro è la risorsa di primo livello per Machine Learning. Fornisce una posizione centralizzata per lavorare con tutti gli artefatti creati durante l'uso di Machine Learning. In questa sezione ci si connette all'area di lavoro in cui verranno eseguite le attività di distribuzione.
Immettere 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>
Informazioni sull'esempio
Questo articolo usa un modello compilato usando TensorFlow insieme all'architettura RestNet. Per altre informazioni, vedere Mapping di identità nelle reti residue profonde. È possibile scaricare un esempio di questo modello. Il modello presenta i vincoli seguenti:
- 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 YAML e altri file, clonare il repository. Modificare le directory in 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 Notebook
È possibile seguire questo esempio in un Jupyter Notebook. Nel repository clonato aprire il notebook: imagenet-classifier-batch.ipynb.
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 l'endpoint che ospita il modello:
Specificare il nome dell'endpoint.
ENDPOINT_NAME="imagenet-classifier-batch"
Creare il file YAML seguente per definire l'endpoint batch denominato 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
Registrare il modello
Le distribuzioni di modelli possono distribuire solo modelli registrati. È necessario registrare il modello. È possibile ignorare questo passaggio se il modello che si sta tentando di distribuire è già registrato.
Scaricare 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"
Creare uno script di punteggio
Creare uno script di assegnazione dei punteggi in grado di leggere le immagini fornite dalla distribuzione batch e restituire i punteggi del modello.
- Il metodo
init
carica il modello usando il modulokeras
intensorflow
. - Il metodo
run
viene eseguito per ogni mini batch fornito dalla distribuzione batch. - Il metodo
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. - Lo script restituisce le classi e le probabilità associate alle stime.
Questo codice è il file 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 criterio comune come il tentativo di caricare l'intero batch e inviarlo al modello contemporaneamente potrebbe comportare un utilizzo elevato della memoria sull'executor batch (eccezioni OOM).
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 desidera ottenere un utilizzo elevato della GPU. Per uno script di assegnazione dei punteggi che sfrutta questo approccio, vedere Distribuzioni a velocità effettiva elevata.
Nota
Se si desidera distribuire un modello generativo, che genera file, apprendere come creare uno script di assegnazione dei punteggi: Personalizzare gli output nelle distribuzioni batch.
Creare la distribuzione
Dopo aver creato lo script di assegnazione dei punteggi, creare una distribuzione batch. A tale scopo, seguire questa procedura:
Assicurarsi di avere creato un cluster di elaborazione in cui è possibile creare la distribuzione. In questo esempio usare un cluster di elaborazione denominato
gpu-cluster
. Sebbene non sia necessario, l'uso di GPU velocizza l'elaborazione.Indicare l'ambiente in cui eseguire la distribuzione. In questo esempio il modello viene eseguito su
TensorFlow
. Azure Machine Learning ha già un ambiente con il software necessario installato, quindi è possibile riutilizzare questo ambiente. È necessario aggiungere un paio di dipendenze in un file conda.yml.La definizione dell'ambiente è 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
Creare la distribuzione.
Per creare una nuova distribuzione nell'endpoint creato, creare una
YAML
configurazione simile all'esempio seguente. Per altre proprietà, vedere lo schema YAML dell'endpoint batch completo.$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 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 desidera richiamare l'endpoint stesso e consentire all'endpoint di decidere quale distribuzione usare. Tale distribuzione è denominata distribuzione predefinita.
Questo approccio consente di modificare la distribuzione predefinita, oltre che modificare il modello che gestisce la distribuzione, senza modificare il contratto con l'utente che richiama l'endpoint. Usare il codice seguente per aggiornare la distribuzione predefinita:
az ml batch-endpoint update --name $ENDPOINT_NAME --set defaults.deployment_name=$DEPLOYMENT_NAME
L'endpoint batch è pronto per l'uso.
Testare la distribuzione
Per testare l'endpoint, usare un esempio di 1.000 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. Caricarlo in un archivio dati di Azure Machine Learning. Creare un asset di dati che può essere usato per richiamare l'endpoint per l'assegnazione dei punteggi.
Nota
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
Nota
Se non
wget
è installato in locale, installarlo o usare un browser per ottenere il file .zip.Creare l'asset di dati dai dati scaricati.
Creare una definizione di asset di dati in un file
YAML
denominato 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 l'asset di dati.
az ml data create -f imagenet-sample-unlabeled.yml
Una volta che i dati sono stati caricati e sono 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
Se l'utilità
jq
non è installata, vedere Scaricare jq.
Suggerimento
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 è l'impostazione predefinita. È 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, scaricare le stime.
Per scaricare le previsioni, usare il comando seguente:
az ml job download --name $JOB_NAME --output-name score --download-path ./
Le previsioni hanno un aspetto simile all'output seguente. Le stime vengono combinate con le etichette per praticità del lettore. Per altre informazioni su come ottenere questo effetto, 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 elabora un'immagine alla volta, anche quando la distribuzione batch fornisce un batch di essi. Nella maggior parte dei casi, questo approccio è ottimale. Semplifica l'esecuzione dei modelli ed evita eventuali problemi di memoria insufficiente. Tuttavia, in alcuni altri casi, potrebbe essere necessario saturare il più possibile l'hardware sottostante. Questa situazione è il caso di GPU, ad esempio.
In questi casi, è possibile eseguire l'inferenza sull'intero batch di dati. Questo approccio 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. L'intera pipeline si verifica 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.
Creare lo 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"] )
- Questo script costruisce 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
.
- Questo script costruisce 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
Creare la distribuzione.
- Per creare una nuova distribuzione nell'endpoint creato, creare una
YAML
configurazione simile all'esempio seguente. Per altre proprietà, vedere lo schema YAML dell'endpoint batch completo.
$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 la distribuzione con il comando seguente:
az ml batch-deployment create --file deployment-by-batch.yml --endpoint-name $ENDPOINT_NAME --set-default
- Per creare una nuova distribuzione nell'endpoint creato, creare una
È possibile usare questa nuova distribuzione con i dati di esempio mostrati in precedenza. Tenere presente che per richiamare questa distribuzione 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 le si utilizza tenere presenti le seguenti considerazioni:
- I file di immagine supportati includono: .png, .jpg, .jpeg, .tiff, .bmp e .gif.
- I modelli MLflow dovrebbero ricevere un
np.ndarray
come input che corrisponde alle dimensioni dell'immagine di input. Per supportare più dimensioni di immagine in ogni batch, l'executor batch richiama il modello MLflow una volta per ogni file di immagine. - I modelli MLflow sono altamente incoraggiati a includere una firma. In caso affermativo, deve 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, includere una firma che possa garantirla. Ad esempio, la firma seguente consente 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 Jupyter Notebook imagenet-classifier-mlflow.ipynb. Per altre informazioni su come usare i modelli MLflow nelle distribuzioni batch, vedere Uso di modelli MLflow nelle distribuzioni batch.