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í dávkového modelu můžete použít ke zpracování tabulkových dat, ale také k jakýmkoli jiným typům souborů, jako jsou image. Tato nasazení se podporují v MLflow i vlastních modelech. V tomto článku se dozvíte, jak nasadit model, který klasifikuje obrázky podle taxonomie ImageNet.

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 Learning.

  • Pracovní prostor služby Azure Machine Learning. Pokud chcete vytvořit pracovní prostor, přečtěte si téma Správa pracovních prostorů Služby Azure Machine Learning.

  • Ujistěte se, že máte v pracovním prostoru Machine Learning 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í Azure Resource Manageru 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ý.
  • Nainstalujte následující software pro práci se službou Machine Learning:

    Spuštěním následujícího příkazu nainstalujte Azure CLI a ml rozšíření pro Azure Machine Learning:

    az extension add -n ml
    

    Nasazení součástí kanálu pro koncové body služby Batch se zavádí ve verzi 2.7 ml rozšíření pro Azure CLI. az extension update --name ml Pomocí příkazu získejte nejnovější verzi.


Připojení k pracovnímu prostoru

Pracovní prostor je prostředek nejvyšší úrovně pro Machine Learning. Poskytuje centralizované místo pro práci se všemi artefakty, které vytvoříte při použití služby Machine Learning. V této části se připojíte k pracovnímu prostoru, ve kterém provádíte úlohy nasazení.

V následujícím příkazu zadejte hodnoty ID předplatného, pracovního prostoru, umístění a skupiny prostředků:

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

O této ukázce

Tento článek používá model vytvořený pomocí TensorFlow spolu s architekturou RestNet. Další informace najdete v tématu Mapování identit v hlubokých reziduálních sítích. Ukázku tohoto modelu si můžete stáhnout. Model má následující omezení:

  • 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 nebo vkládat YAML a další soubory, naklonujte úložiště. Pokud používáte sadu SDK pro Python, změňte adresáře na cli/endpoints/batch/deploy-models/imagenet-classifier.

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.

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

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

Vytvoření koncového bodu

Vytvořte koncový bod, který je hostitelem modelu:

  1. Zadejte název koncového bodu.

    ENDPOINT_NAME="imagenet-classifier-batch"
    
  2. Vytvořte následující soubor YAML pro definování dávkového koncového bodu s názvem 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
    

    Pokud chcete vytvořit koncový bod, spusťte následující kód:

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

Registrace modelu

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

  1. Stáhněte si kopii 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

Vytvořte bodovací skript, který může číst image poskytované dávkovém nasazením a vracet skóre modelu.

  • Metoda init načte model pomocí keras modulu v tensorflow.
  • Tato run metoda se spustí pro každou minidávku, která poskytuje dávkové nasazení.
  • Metoda 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á.
  • Skript vrátí třídy a pravděpodobnosti přidružené k předpovědím.

Tento kód je soubor 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, protože pokus 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 (výjimky OOM).

Existují 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 chcete dosáhnout vysokého využití GPU. Bodovací skript, který využívá tento přístup, najdete v tématu Nasazení s vysokou propustností.

Poznámka:

Pokud chcete nasadit generující model, který generuje soubory, zjistěte, jak vytvořit bodovací skript: Přizpůsobení výstupů v dávkových nasazeních.

Vytvoření nasazení

Jakmile vytvoříte bodovací skript, vytvořte pro něj dávkové nasazení. Použijte následující postup:

  1. Ujistěte se, že máte vytvořený výpočetní cluster, ve kterém můžete vytvořit nasazení. V tomto příkladu použijte výpočetní cluster s názvem gpu-cluster. I když to není nutné, při použití grafických procesorů se zpracování urychlí.

  2. Uveďte, ve kterém prostředí se má nasazení spustit. V tomto příkladu model běží na TensorFlow. Azure Machine Learning už má prostředí s nainstalovaným požadovaným softwarem, abyste mohli toto prostředí znovu použít. Do souboru conda.yml je potřeba přidat několik závislostí.

    Definice prostředí je součástí souboru nasazení.

    compute: azureml:gpu-cluster
    environment:
      name: tensorflow212-cuda11-gpu
      image: mcr.microsoft.com/azureml/curated/tensorflow-2.12-cuda11:latest
    
  3. Vytvořte 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. Další vlastnosti najdete ve schématu YAML celého dávkového koncového bodu.

    $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
    

    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 chcete vyvolat samotný koncový bod a nechat koncový bod rozhodnout, které nasazení použít. Toto nasazení se nazývá výchozí nasazení.

    Tento přístup umožňuje změnit výchozí nasazení a změnit model obsluhující nasazení beze změny kontraktu s uživatelem vyvoláním koncového bodu. K aktualizaci výchozího nasazení použijte následující kód:

    az ml batch-endpoint update --name $ENDPOINT_NAME --set defaults.deployment_name=$DEPLOYMENT_NAME
    

Váš dávkový koncový bod je připravený k použití.

Otestování nasazení

K otestování koncového bodu použijte ukázku 1 000 obrázků z původní datové sady ImageNet. Koncové body služby Batch můžou zpracovávat pouze data, která jsou umístěná v cloudu a která jsou přístupná z pracovního prostoru Azure Machine Learning. Nahrajte ho do úložiště dat služby Azure Machine Learning. Vytvořte datový prostředek, který lze použít k vyvolání koncového bodu pro bodování.

Poznámka:

Koncové body služby Batch přijímají data, která je možné umístit do více typů umístění.

  1. Stáhněte si přidružená ukázková data.

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

    Poznámka:

    Pokud nemáte wget nainstalovaný místně, nainstalujte ho nebo použijte prohlížeč k získání .zip souboru.

  2. Vytvořte datový asset ze stažených dat.

    1. V souboru s názvem imagenet-sample-unlabeled.yml vytvořte definici datového YAML assetu:

      $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
      
    2. Vytvořte datový asset.

      az ml data create -f imagenet-sample-unlabeled.yml
      
  3. Jakmile se data nahrají a jsou připravená k použití, vyvolejte koncový bod.

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

    Poznámka:

    Pokud není nástroj jq nainstalovaný, přečtěte si téma Stažení jq.


Tip

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

  1. Dávková úloha se spustí, jakmile příkaz vrátí. Stav úlohy můžete monitorovat, dokud se nedokončí.

    az ml job show -n $JOB_NAME --web
    
  2. Po dokončení nasazení stáhněte predikce.

    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 ./
    
  3. Předpovědi vypadají jako následující výstup. Předpovědi jsou kombinovány s popisky pro pohodlí čtenáře. Další informace o tom, jak dosáhnout tohoto efektu, 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 Afgánský chrt
    n02088238_basset 162 0.999397 baset
    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í zpracovává jednu bitovou kopii, a to i v případě, že dávkové nasazení poskytuje dávku z nich. Ve většině případů je tento přístup nejlepší. Zjednodušuje spouštění modelů a vyhýbá se jakýmkoli možným problémům s nedostatkem paměti. V některých jiných případech však můžete chtít saturovat co nejvíce základního hardwaru. Jedná se například o gpu.

V těchto případech můžete chtít odvodit celou dávku dat. Tento přístup znamená načtení celé sady obrázků do paměti a jejich odeslání 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á také TensorFlow operace k předběžnému zpracování dat. K celému kanálu dochází na stejném zařízení, které se používá (PROCESOR/GPU).

Upozorňující

Některé modely mají nelineární vztah s velikostí vstupů z hlediska spotřeby paměti. Pokud se chcete vyhnout výjimkám mimo paměť, proveďte dávku znovu (jak je to v tomto příkladu) nebo zmenšíte velikost dávek vytvořených nasazením dávky.

  1. Vytvořte kód hodnoticího skriptu / 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"]
        )
    
    • Tento skript vytvoří 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 je znovu dávková (16), aby se data odeslala do modelu. Pomocí tohoto parametru můžete řídit, kolik informací můžete načíst do paměti a odeslat do modelu najednou. Pokud běží na GPU, je potřeba 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. Vytvořte nasazení.

    1. 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. Další vlastnosti najdete ve schématu YAML celého dávkového koncového bodu.
    $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
    
    1. 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, buď označíte název nasazení v metodě vyvolání, nebo ho nastavíte 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, .tiff, .bmp a .gif.
  • Modely MLflow by měly očekávat přijetí np.ndarray jako vstupu, který odpovídá rozměrům vstupního obrázku. Aby bylo možné v každé dávce podporovat více velikostí imagí, vyvolá exekutor batch model MLflow jednou na soubor image.
  • Modely MLflow se důrazně doporučují, aby obsahovaly podpis. Pokud ano, 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ů, zahrňte podpis, který ho může zaručit. Například následující příklad podpisu umožňuje dávky 3 kanálových obrázků.
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