Zpracování obrázků pomocí nasazení dávkového modelu

PLATÍ PRO:Rozšíření Azure CLI ml v2 (aktuální)Python SDK azure-ai-ml v2 (aktuální)

Nasazení modelu Batch je možné použít ke zpracování tabulkových dat, ale také k jakémukoli jinému typu souboru, jako jsou image. Tato nasazení se podporují v MLflow i vlastních modelech. V tomto kurzu se dozvíte, jak nasadit model, který klasifikuje obrázky podle taxonomie ImageNet.

O této ukázce

Model, se kterým budeme pracovat, byl sestaven pomocí TensorFlow spolu s architekturou RestNet (mapování identit v hlubokých zbytkových sítích). Tady si můžete stáhnout ukázku tohoto modelu. Model má následující omezení, která je důležité mít na paměti pro nasazení:

  • Funguje s obrázky o velikosti 244x244 (tensors of (224, 224, 3)).
  • Vyžaduje škálování vstupů do rozsahu [0,1].

Informace v tomto článku vycházejí z ukázek kódu obsažených v úložišti azureml-examples . Pokud chcete příkazy spustit místně, aniž byste museli kopírovat a vkládat YAML a další soubory, naklonujte úložiště a pak změňte adresáře na cli/endpoints/batch/deploy-models/imagenet-classifier azure CLI nebo sdk/python/endpoints/batch/deploy-models/imagenet-classifier pokud používáte naši sadu SDK pro Python.

git clone https://github.com/Azure/azureml-examples --depth 1
cd azureml-examples/cli/endpoints/batch/deploy-models/imagenet-classifier

Sledování v poznámkových blocích Jupyter

Tuto ukázku můžete sledovat v poznámkovém bloku Jupyter. V klonovaném úložišti otevřete poznámkový blok: imagenet-classifier-batch.ipynb.

Požadavky

Než budete postupovat podle kroků v tomto článku, ujistěte se, že máte následující požadavky:

  • Předplatné Azure. Pokud ještě nemáte předplatné Azure, vytvořte si napřed bezplatný účet. Vyzkoušejte bezplatnou nebo placenou verzi služby Azure Machine Učení.

  • Pracovní prostor služby Azure Machine Learning. Pokud ho nemáte, vytvořte ho pomocí kroků v článku Správa Učení pracovních prostorů Azure.

  • Ujistěte se, že máte v pracovním prostoru následující oprávnění:

    • Vytváření nebo správa dávkových koncových bodů a nasazení: Použijte roli Vlastník, Přispěvatel nebo Vlastní, která umožňuje Microsoft.MachineLearningServices/workspaces/batchEndpoints/*.

    • Vytvořte nasazení ARM ve skupině prostředků pracovního prostoru: Použijte roli Vlastník, Přispěvatel nebo Vlastní, která umožňuje Microsoft.Resources/deployments/write ve skupině prostředků, ve které je pracovní prostor nasazený.

  • Abyste mohli pracovat se službou Azure Machine Učení, musíte nainstalovat následující software:

    Azure CLI a mlrozšíření pro azure machine Učení.

    az extension add -n ml
    

    Poznámka:

    Nasazení součástí kanálu pro koncové body služby Batch byla zavedena ve verzi 2.7 ml rozšíření pro Azure CLI. Slouží az extension update --name ml k získání poslední verze.

Připojení k pracovnímu prostoru

Pracovní prostor je prostředek nejvyšší úrovně pro Azure Machine Learning, který nabízí centralizované místo, kde můžete pracovat se všemi artefakty, které vytvoříte při použití služby Azure Machine Learning. V této části se připojíme k pracovnímu prostoru, ve kterém budete provádět úlohy nasazení.

Hodnoty ID předplatného, pracovního prostoru, umístění a skupiny prostředků předejte v následujícím kódu:

az account set --subscription <subscription>
az configure --defaults workspace=<workspace> group=<resource-group> location=<location>

Klasifikace obrázků s využitím dávkových nasazení

V tomto příkladu se dozvíme, jak nasadit model hlubokého učení, který dokáže klasifikovat daný obrázek podle taxonomie imageNet.

Vytvoření koncového bodu

Nejprve vytvoříme koncový bod, který bude hostovat model:

Rozhodněte se o názvu koncového bodu:

ENDPOINT_NAME="imagenet-classifier-batch"

Následující soubor YAML definuje dávkový koncový bod:

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

Spuštěním následujícího kódu vytvořte koncový bod.

az ml batch-endpoint create --file endpoint.yml  --name $ENDPOINT_NAME

Registrace modelu

Nasazení modelů můžou nasazovat jenom registrované modely, takže je potřebujeme zaregistrovat. Tento krok můžete přeskočit, pokud už je model, který se pokoušíte nasadit, zaregistrovaný.

  1. Stažení kopie modelu:

    wget https://azuremlexampledata.blob.core.windows.net/data/imagenet/model.zip
    unzip model.zip -d .
    
  2. Zaregistrujte model:

    MODEL_NAME='imagenet-classifier'
    az ml model create --name $MODEL_NAME --path "model"
    

Vytvoření hodnoticího skriptu

Potřebujeme vytvořit bodovací skript, který může číst image poskytované dávkovém nasazením a vracet skóre modelu. Následující skript:

  • Označuje init funkci, která načte model pomocí keras modulu v tensorflow.
  • Označuje run funkci, která se spustí pro každou minidávku, kterou poskytuje dávkové nasazení.
  • Funkce run načte jeden obrázek souboru najednou.
  • Metoda run změní velikost obrázků na očekávané velikosti modelu.
  • Metoda run rescales the images to the range [0,1] domain, což je to, co model očekává.
  • Vrátí třídy a pravděpodobnosti přidružené k předpovědím.

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)

Tip

I když nasazení poskytuje image v minidávkách, tento skript bodování zpracovává najednou jednu image. Jedná se o běžný vzor při pokusu o načtení celé dávky a jeho odeslání do modelu najednou může vést k vysokému zatížení paměti v dávkovém exekutoru (exepce OOM). Existují však určité případy, kdy to umožňuje vysokou propustnost v hodnoticí úloze. Jedná se o případ dávkových nasazení přes hardware GPU, kde chceme dosáhnout vysokého využití GPU. Příklad hodnoticího skriptu, který ho využívá, najdete v nasazení s vysokou propustností.

Poznámka:

Pokud se pokoušíte nasadit generující model (který generuje soubory), přečtěte si, jak vytvořit bodovací skript, jak je vysvětleno při nasazení modelů, které vytváří více souborů.

Vytvoření nasazení

Jeden skript bodování se vytvoří, je čas pro něj vytvořit dávkové nasazení. Vytvořte ho následujícím postupem:

  1. Ujistěte se, že máte vytvořený výpočetní cluster, kde můžeme vytvořit nasazení. V tomto příkladu použijeme výpočetní cluster s názvem gpu-cluster. I když to není povinné, ke zrychlení zpracování používáme gpu.

  2. Musíme určit, ve kterém prostředí nasazení spustíme. V našem případě náš model běží na TensorFlow. Azure Machine Učení už má prostředí s nainstalovaným požadovaným softwarem, abychom toto prostředí mohli znovu využít. Do souboru přidáme několik závislostí conda.yml .

    Definice prostředí bude zahrnuta v souboru nasazení.

    compute: azureml:gpu-cluster
    environment:
      name: tensorflow212-cuda11-gpu
      image: mcr.microsoft.com/azureml/curated/tensorflow-2.12-cuda11:latest
    
  3. Teď pojďme vytvořit nasazení.

    Pokud chcete vytvořit nové nasazení v rámci vytvořeného koncového bodu, vytvořte YAML konfiguraci jako v následujícím příkladu. Můžete zkontrolovat, jestli schéma YAML celého dávkového koncového bodu obsahuje další vlastnosti.

    $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
    

    Pak vytvořte nasazení pomocí následujícího příkazu:

    az ml batch-deployment create --file deployment-by-file.yml --endpoint-name $ENDPOINT_NAME --set-default
    
  4. I když můžete vyvolat konkrétní nasazení uvnitř koncového bodu, obvykle budete chtít vyvolat samotný koncový bod a nechat koncový bod rozhodnout, které nasazení použít. Toto nasazení se nazývá výchozí nasazení. To vám umožní změnit výchozí nasazení – a tím změnit model obsluhující nasazení – beze změny kontraktu s uživatelem, který vyvolá koncový bod. K aktualizaci výchozího nasazení použijte následující pokyny:

    az ml batch-endpoint update --name $ENDPOINT_NAME --set defaults.deployment_name=$DEPLOYMENT_NAME
    
  5. V tuto chvíli je náš dávkový koncový bod připravený k použití.

Testování nasazení

K otestování našeho koncového bodu použijeme ukázku 1000 obrázků z původní datové sady ImageNet. Koncové body služby Batch můžou zpracovávat pouze data umístěná v cloudu a přístupná z pracovního prostoru Azure Machine Učení. V tomto příkladu ho nahrajeme do úložiště dat azure machine Učení. Zejména vytvoříme datový asset, který se dá použít k vyvolání koncového bodu pro bodování. Všimněte si však, že dávkové koncové body přijímají data, která lze umístit do více typů umístění.

  1. Pojďme si stáhnout přidružená ukázková data:

    wget https://azuremlexampledata.blob.core.windows.net/data/imagenet/imagenet-1000.zip
    unzip imagenet-1000.zip -d data
    
  2. Teď vytvoříme datový asset z právě stažených dat.

    Vytvoření definice datového assetu v 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
    

    Pak vytvořte datový asset:

    az ml data create -f imagenet-sample-unlabeled.yml
    
  3. Teď, když jsou data nahraná a připravená k použití, vyvoláme koncový bod:

    JOB_NAME=$(az ml batch-endpoint invoke --name $ENDPOINT_NAME --input azureml:imagenet-sample-unlabeled@latest --query name -o tsv)
    

    Poznámka:

    jq Nástroj nemusí být nainstalován v každé instalaci. Pokyny najdete na tomto odkazu.

    Tip

    Všimněte si, že v operaci vyvolání indikujeme název nasazení. Důvodem je to, že koncový bod automaticky směruje úlohu do výchozího nasazení. Vzhledem k tomu, že náš koncový bod má jenom jedno nasazení, je to výchozí. Konkrétní nasazení můžete cílit zadáním argumentu nebo parametru deployment_name.

  4. Dávková úloha se spustí hned po vrácení příkazu. Stav úlohy můžete monitorovat, dokud se nedokončí:

    az ml job show -n $JOB_NAME --web
    
  5. Po dokončení nasazení si můžeme stáhnout předpovědi:

    K stažení předpovědí použijte následující příkaz:

    az ml job download --name $JOB_NAME --output-name score --download-path ./
    
  6. Predikce výstupu budou vypadat následovně. Všimněte si, že předpovědi byly kombinovány s popisky pro pohodlí čtenáře. Další informace o tom, jak toho dosáhnout, najdete v přidruženém poznámkovém bloku.

    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
    
    soubor class Pravděpodobnosti popisek
    n02088094_Afghan_hound. JPEG 161 0.994745 Afghánský hound
    n02088238_basset 162 0.999397 Basset
    n02088364_beagle. JPEG 165 0.366914 bluetick
    n02088466_bloodhound. JPEG 164 0.926464 Bloodhound
    ... ... ... ...

Nasazení s vysokou propustností

Jak už bylo zmíněno dříve, nasazení, které jsme právě vytvořili, zpracovává jednu image, i když dávkové nasazení poskytuje dávku z nich. Ve většině případů je to nejlepší přístup, protože zjednodušuje provádění modelů a zabraňuje jakýmkoli možným problémům s nedostatkem paměti. V některých jiných ale můžeme chtít saturovat co nejvíce využití základního hardwaru. Jedná se například o gpu.

V těchto případech můžeme chtít provést odvozování pro celou dávku dat. To znamená, že se celá sada obrázků načítá do paměti a odesílá je přímo do modelu. Následující příklad používá TensorFlow ke čtení dávky obrázků a hodnocení všech najednou. Používá TensorFlow také operace k předběžnému zpracování dat, takže se celý kanál provede na stejném zařízení, které se používá (cpu/GPU).

Upozorňující

Některé modely mají nelineární vztah s velikostí vstupů z hlediska spotřeby paměti. Opakujte dávku (jak je to v tomto příkladu) nebo snižte velikost dávek vytvořených nasazením dávky, abyste se vyhnuli výjimkám mimo paměť.

  1. Vytvoření hodnoticího skriptu:

    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"]
        )
    

    Tip

    • Všimněte si, že tento skript vytváří datovou sadu tensoru z minidávkové dávky odeslané nasazením dávky. Tato datová sada je předem zpracována k získání očekávaných tenzorů pro model pomocí map operace s funkcí decode_img.
    • Datová sada se znovu odešle do modelu (16). Pomocí tohoto parametru můžete řídit, kolik informací můžete načíst do paměti a odeslat do modelu najednou. Pokud běží na GPU, budete muset pečlivě vyladit tento parametr, abyste dosáhli maximálního využití GPU těsně před získáním výjimky OOM.
    • Po výpočtu předpovědí se tensory převedou na numpy.ndarray.
  2. Teď pojďme vytvořit nasazení.

    Pokud chcete vytvořit nové nasazení v rámci vytvořeného koncového bodu, vytvořte YAML konfiguraci jako v následujícím příkladu. Můžete zkontrolovat, jestli schéma YAML celého dávkového koncového bodu obsahuje další vlastnosti.

    $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
    

    Pak vytvořte nasazení pomocí následujícího příkazu:

    az ml batch-deployment create --file deployment-by-batch.yml --endpoint-name $ENDPOINT_NAME --set-default
    
  3. Toto nové nasazení můžete použít s ukázkovými daty zobrazenými dříve. Nezapomeňte, že pokud chcete toto nasazení vyvolat, měli byste buď určit název nasazení ve vyvolání metody, nebo ho nastavit jako výchozí.

Důležité informace o modelech MLflow zpracovávajících obrázky

Modely MLflow v koncových bodech služby Batch podporují čtení obrázků jako vstupních dat. Vzhledem k tomu, že nasazení MLflow nevyžadují bodovací skript, při jejich použití je potřeba vzít v úvahu následující skutečnosti:

  • Mezi podporované soubory obrázků patří: .png, .jpg, .jpeg, .bmp.tiffa .gif.
  • Modely MLflow by měly očekávat, že obdrží np.ndarray jako vstup, který bude odpovídat rozměrům vstupního obrázku. Aby bylo možné podporovat více velikostí obrázků v každé dávce, vyvolá dávkové exekutor model MLflow jednou na soubor obrázku.
  • Modely MLflow jsou vysoce podporovány, aby zahrnovaly podpis, a pokud to dělají, musí být typu TensorSpec. Vstupy se mění tak, aby odpovídaly obrazci tensoru, pokud jsou k dispozici. Pokud není k dispozici žádný podpis, odvozují se tensory typu np.uint8 .
  • U modelů, které obsahují podpis a očekává se, že budou zpracovávat proměnlivou velikost obrázků, pak zahrňte podpis, který ho může zaručit. Následující příklad podpisu například umožní dávky se 3 kanálovými obrázky.
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)

Funkční příklad najdete v poznámkovém bloku Jupyter imagenet-classifier-mlflow.ipynb. Další informace o používání modelů MLflow v dávkových nasazeních najdete v tématu Použití modelů MLflow v dávkových nasazeních.

Další kroky