Processamento de imagem com implantações de modelo em lote
APLICA-SE A:Azure CLI ml extension v2 (current)Python SDK azure-ai-ml v2 (current)
Você pode usar implantações de modelo em lote para processar dados tabulares, mas também quaisquer outros tipos de arquivo, como imagens. Essas implantações são suportadas em modelos MLflow e personalizados. Neste artigo, você aprenderá a implantar um modelo que classifica imagens de acordo com a taxonomia do ImageNet.
Pré-requisitos
Uma subscrição do Azure. Se não tiver uma subscrição do Azure, crie uma conta gratuita antes de começar.
Uma área de trabalho do Azure Machine Learning. Para criar um espaço de trabalho, consulte Gerenciar espaços de trabalho do Azure Machine Learning.
As seguintes permissões no espaço de trabalho do Azure Machine Learning:
- Para criar ou gerenciar pontos de extremidade e implantações em lote: use um Proprietário, Colaborador ou função personalizada que tenha recebido as
Microsoft.MachineLearningServices/workspaces/batchEndpoints/*
permissões. - Para criar implantações do Azure Resource Manager no grupo de recursos do espaço de trabalho: use um Proprietário, Colaborador ou função personalizada à qual tenha sido atribuída a
Microsoft.Resources/deployments/write
permissão no grupo de recursos em que o espaço de trabalho está implantado.
- Para criar ou gerenciar pontos de extremidade e implantações em lote: use um Proprietário, Colaborador ou função personalizada que tenha recebido as
A CLI do Azure Machine Learning ou o SDK do Azure Machine Learning para Python:
Execute o seguinte comando para instalar a CLI do Azure e a extensão para o
ml
Azure Machine Learning:az extension add -n ml
As implantações de componentes de pipeline para pontos de extremidade em lote são introduzidas na versão 2.7 da
ml
extensão para a CLI do Azure. Use oaz extension update --name ml
comando para obter a versão mais recente.
Ligar à sua área de trabalho
O espaço de trabalho é o recurso de nível superior para o Azure Machine Learning. Ele fornece um local centralizado para trabalhar com todos os artefatos que você cria quando usa o Azure Machine Learning. Nesta seção, você se conecta ao espaço de trabalho onde executa suas tarefas de implantação.
No comando a seguir, insira sua ID de assinatura, nome do espaço de trabalho, nome do grupo de recursos e local:
az account set --subscription <subscription>
az configure --defaults workspace=<workspace> group=<resource-group> location=<location>
Sobre este exemplo
Este artigo usa um modelo que foi criado usando o TensorFlow junto com a arquitetura RestNet. Para obter mais informações, consulte Mapeamentos de identidade em redes residuais profundas. Você pode baixar uma amostra deste modelo. O modelo tem as seguintes restrições:
- Funciona com imagens de tamanho 244x244 (tensores de
(224, 224, 3)
). - Requer que as entradas sejam dimensionadas para o intervalo
[0,1]
.
As informações neste artigo são baseadas em exemplos de código contidos no repositório azureml-examples . Para executar os comandos localmente sem ter que copiar/colar YAML e outros arquivos, clone o repo. Altere os diretórios para cli/endpoints/batch/deploy-models/imagenet-classifier se estiver usando a CLI do Azure ou sdk/python/endpoints/batch/deploy-models/imagenet-classifier se estiver usando o SDK para Python.
git clone https://github.com/Azure/azureml-examples --depth 1
cd azureml-examples/cli/endpoints/batch/deploy-models/imagenet-classifier
Acompanhe em Jupyter Notebooks
Você pode acompanhar este exemplo em um Caderno Jupyter. No repositório clonado, abra o bloco de anotações: imagenet-classifier-batch.ipynb.
Classificação de imagem com implantações em lote
Neste exemplo, você aprenderá a implantar um modelo de aprendizado profundo que pode classificar uma determinada imagem de acordo com a taxonomia da ImageNet.
Criar o ponto de extremidade
Crie o ponto de extremidade que hospeda o modelo:
Especifique o nome do ponto de extremidade.
ENDPOINT_NAME="imagenet-classifier-batch"
Crie o seguinte arquivo YAML para definir o ponto de extremidade em lote, chamado 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
Para criar o ponto de extremidade, execute o seguinte código:
az ml batch-endpoint create --file endpoint.yml --name $ENDPOINT_NAME
Registar o modelo
As implantações de modelo só podem implantar modelos registrados. É necessário registrar o modelo. Você pode pular esta etapa se o modelo que está tentando implantar já estiver registrado.
Faça o download de uma cópia do modelo.
wget https://azuremlexampledata.blob.core.windows.net/data/imagenet/model.zip unzip model.zip -d .
Registar o modelo.
MODEL_NAME='imagenet-classifier' az ml model create --name $MODEL_NAME --path "model"
Criar um script de pontuação
Crie um script de pontuação que possa ler as imagens fornecidas pela implantação em lote e retornar as pontuações do modelo.
- O
init
método carrega o modelo usando okeras
módulo emtensorflow
. - O
run
método é executado para cada minilote fornecido pela implantação em lote. - O
run
método lê uma imagem do arquivo de cada vez. - O
run
método redimensiona as imagens para os tamanhos esperados para o modelo. - O
run
método redimensiona as imagens para o domínio de intervalo[0,1]
, que é o que o modelo espera. - O script retorna as classes e as probabilidades associadas às previsões.
Este código é o ficheiro 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)
Gorjeta
Embora as imagens sejam fornecidas em minilotes pela implantação, esse script de pontuação processa uma imagem de cada vez. Este é um padrão comum porque tentar carregar o lote inteiro e enviá-lo para o modelo de uma só vez pode resultar em alta pressão de memória no executor de lote (exceções OOM).
Há certos casos em que isso permite uma alta taxa de transferência na tarefa de pontuação. Este é o caso de implantações em lote sobre hardware de GPU onde você deseja alcançar alta utilização de GPU. Para obter um script de pontuação que aproveite essa abordagem, consulte Implantações de alta taxa de transferência.
Nota
Se você quiser implantar um modelo generativo, que gera arquivos, saiba como criar um script de pontuação: Personalizar saídas em implantações em lote.
Criar a implantação
Depois de criar o script de pontuação, crie uma implantação em lote para ele. Utilize o seguinte procedimento:
Certifique-se de ter um cluster de computação criado onde você possa criar a implantação. Neste exemplo, use um cluster de computação chamado
gpu-cluster
. Embora não seja necessário, o uso de GPUs acelera o processamento.Indique em qual ambiente executar a implantação. Neste exemplo, o modelo é executado em
TensorFlow
. O Azure Machine Learning já tem um ambiente com o software necessário instalado, para que possa reutilizar este ambiente. Você precisa adicionar algumas dependências em um arquivo de conda.yml .A definição de ambiente está incluída no arquivo de implantação.
compute: azureml:gpu-cluster environment: name: tensorflow212-cuda11-gpu image: mcr.microsoft.com/azureml/curated/tensorflow-2.12-cuda11:latest
Crie a implantação.
Para criar uma nova implantação sob o ponto de extremidade criado, crie uma
YAML
configuração como o exemplo a seguir. Para outras propriedades, consulte o esquema YAML de ponto de extremidade de lote 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
Crie a implantação com o seguinte comando:
az ml batch-deployment create --file deployment-by-file.yml --endpoint-name $ENDPOINT_NAME --set-default
Embora você possa invocar uma implantação específica dentro de um ponto de extremidade, geralmente deseja invocar o ponto de extremidade em si e permitir que o ponto de extremidade decida qual implantação usar. Essa implantação é chamada de implantação padrão .
Essa abordagem permite alterar a implantação padrão e alterar o modelo que serve a implantação sem alterar o contrato com o usuário que invoca o ponto de extremidade. Use o código a seguir para atualizar a implantação padrão:
az ml batch-endpoint update --name $ENDPOINT_NAME --set defaults.deployment_name=$DEPLOYMENT_NAME
Seu ponto de extremidade em lote está pronto para ser usado.
Testar a implementação
Para testar o ponto de extremidade, use uma amostra de 1.000 imagens do conjunto de dados ImageNet original. Os pontos de extremidade em lote só podem processar dados localizados na nuvem e acessíveis a partir do espaço de trabalho do Azure Machine Learning. Carregue-o para um armazenamento de dados do Azure Machine Learning. Crie um ativo de dados que possa ser usado para invocar o ponto de extremidade para pontuação.
Nota
Os pontos de extremidade de lote aceitam dados que podem ser colocados em vários tipos de locais.
Faça o download dos dados de exemplo associados.
wget https://azuremlexampledata.blob.core.windows.net/data/imagenet/imagenet-1000.zip unzip imagenet-1000.zip -d data
Nota
Se você não tiver
wget
instalado localmente, instale-o ou use um navegador para obter o arquivo .zip .Crie o ativo de dados a partir dos dados baixados.
Crie uma definição de ativo de dados em um
YAML
arquivo chamado 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
Crie o ativo de dados.
az ml data create -f imagenet-sample-unlabeled.yml
Quando os dados estiverem carregados e prontos para serem usados, invoque o ponto de extremidade.
JOB_NAME=$(az ml batch-endpoint invoke --name $ENDPOINT_NAME --input azureml:imagenet-sample-unlabeled@latest --query name -o tsv)
Nota
Se o utilitário
jq
não estiver instalado, consulte Download jq.
Gorjeta
Você não indica o nome da implantação na operação de invocação. Isso ocorre porque o ponto de extremidade roteia automaticamente o trabalho para a implantação padrão. Como o ponto de extremidade tem apenas uma implantação, essa é a padrão. Você pode direcionar uma implantação específica indicando o argumento/parâmetro deployment_name
.
Um trabalho em lote é iniciado assim que o comando retorna. Você pode monitorar o status do trabalho até que ele seja concluído.
az ml job show -n $JOB_NAME --web
Após a conclusão da implantação, baixe as previsões.
Para baixar as previsões, use o seguinte comando:
az ml job download --name $JOB_NAME --output-name score --download-path ./
As previsões se parecem com a saída a seguir. As previsões são combinadas com os rótulos para a conveniência do leitor. Para saber mais sobre como obter esse efeito, consulte o bloco de anotações associado.
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
ficheiro classe probabilidades etiqueta n02088094_Afghan_hound. JPEG 161 0.994745 Cão afegão n02088238_basset 162 0.999397 Basset n02088364_beagle. JPEG 165 0.366914 carrapato azul n02088466_bloodhound. JPEG 164 0.926464 Bloodhound ... ... ... ...
Implantações de alta taxa de transferência
Como mencionado anteriormente, a implantação processa uma imagem por vez, mesmo quando a implantação em lote está fornecendo um lote delas. Na maioria dos casos, esta abordagem é a melhor. Simplifica a forma como os modelos são executados e evita possíveis problemas de falta de memória. No entanto, em alguns outros casos, você pode querer saturar o máximo possível o hardware subjacente. É o caso das GPUs, por exemplo.
Nesses casos, convém fazer inferência em todo o lote de dados. Essa abordagem implica carregar todo o conjunto de imagens na memória e enviá-las diretamente para o modelo. O exemplo a seguir usa TensorFlow
para ler lotes de imagens e marcá-las todas de uma vez. Ele também usa TensorFlow
ops para fazer qualquer pré-processamento de dados. Todo o pipeline acontece no mesmo dispositivo que está sendo usado (CPU/GPU).
Aviso
Alguns modelos têm uma relação não linear com o tamanho das entradas em termos de consumo de memória. Para evitar exceções de falta de memória, faça o lote novamente (como feito neste exemplo) ou diminua o tamanho dos lotes criados pela implantação em lote.
Crie o código do script de pontuação/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"] )
- Este script constrói um conjunto de dados tensor a partir do minilote enviado pela implantação em lote. Este conjunto de dados é pré-processado para obter os tensores esperados para o modelo usando a
map
operação com a funçãodecode_img
. - O conjunto de dados é agrupado novamente (16) para enviar os dados para o modelo. Use esse parâmetro para controlar a quantidade de informações que você pode carregar na memória e enviar para o modelo de uma só vez. Se estiver sendo executado em uma GPU, você precisa ajustar cuidadosamente esse parâmetro para obter o uso máximo da GPU antes de obter uma exceção OOM.
- Depois que as previsões são calculadas, os tensores são convertidos em
numpy.ndarray
.
- Este script constrói um conjunto de dados tensor a partir do minilote enviado pela implantação em lote. Este conjunto de dados é pré-processado para obter os tensores esperados para o modelo usando a
Crie a implantação.
- Para criar uma nova implantação sob o ponto de extremidade criado, crie uma
YAML
configuração como o exemplo a seguir. Para outras propriedades, consulte o esquema YAML de ponto de extremidade de lote 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
- Crie a implantação com o seguinte comando:
az ml batch-deployment create --file deployment-by-batch.yml --endpoint-name $ENDPOINT_NAME --set-default
- Para criar uma nova implantação sob o ponto de extremidade criado, crie uma
Você pode usar essa nova implantação com os dados de exemplo mostrados anteriormente. Lembre-se de que, para invocar essa implantação, indique o nome da implantação no método de invocação ou defina-o como padrão.
Considerações para modelos MLflow que processam imagens
Os modelos MLflow em Batch Endpoints suportam a leitura de imagens como dados de entrada. Como as implantações MLflow não exigem um script de pontuação, tenha as seguintes considerações ao usá-las:
- Os ficheiros de imagem suportados incluem: .png, .jpg, .jpeg, .tiff, .bmp e .gif.
- Os modelos MLflow devem esperar receber uma
np.ndarray
entrada como que corresponda às dimensões da imagem de entrada. Para suportar vários tamanhos de imagem em cada lote, o executor de lote invoca o modelo MLflow uma vez por arquivo de imagem. - Os modelos MLflow são altamente incentivados a incluir uma assinatura. Se o fizerem, deve ser do tipo
TensorSpec
. As entradas são remodeladas para corresponder à forma do tensor, se disponível. Se nenhuma assinatura estiver disponível, tensores do tiponp.uint8
são inferidos. - Para modelos que incluem uma assinatura e devem lidar com imagens de tamanho variável, inclua uma assinatura que possa garanti-la. Por exemplo, o exemplo de assinatura a seguir permite lotes de 3 imagens canalizadas.
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)
Você pode encontrar um exemplo de trabalho no bloco de anotações Jupyter imagenet-classifier-mlflow.ipynb. Para obter mais informações sobre como usar modelos MLflow em implantações em lote, consulte Usando modelos MLflow em implantações em lote.