Przetwarzanie obrazów przy użyciu wdrożeń modelu wsadowego

DOTYCZY: Rozszerzenie interfejsu wiersza polecenia platformy Azure w wersji 2 (current)Zestaw PYTHON SDK azure-ai-ml v2 (bieżąca)

Wdrożenia modelu usługi Batch mogą służyć do przetwarzania danych tabelarycznych, ale także innych typów plików, takich jak obrazy. Te wdrożenia są obsługiwane zarówno w modelu MLflow, jak i niestandardowym. W tym samouczku dowiesz się, jak wdrożyć model klasyfikujący obrazy zgodnie z taksonomią ImageNet.

Informacje o tym przykładzie

Model, z który będziemy pracować, został utworzony przy użyciu biblioteki TensorFlow wraz z architekturą RestNet (mapowania tożsamości w głębokich sieciach reszt). Przykład tego modelu można pobrać tutaj. Model ma następujące ograniczenia, które są ważne, aby pamiętać o wdrożeniu:

  • Działa z obrazami o rozmiarze 244x244 (tensorami (224, 224, 3)).
  • Wymaga ona skalowania danych wejściowych do zakresu [0,1].

Informacje przedstawione w tym artykule są oparte na przykładach kodu zawartych w repozytorium azureml-examples . Aby uruchomić polecenia lokalnie bez konieczności kopiowania/wklejania kodu YAML i innych plików, sklonuj repozytorium, a następnie zmień katalogi na cli/endpoints/batch/deploy-models/imagenet-classifier , jeśli używasz interfejsu wiersza polecenia platformy Azure lub sdk/python/endpoints/batch/deploy-models/imagenet-classifier jeśli używasz naszego zestawu SDK dla języka Python.

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

Postępuj zgodnie z instrukcjami w notesach Jupyter Notebook

Możesz skorzystać z tego przykładu w notesie Jupyter Notebook. W sklonowanym repozytorium otwórz notes: imagenet-classifier-batch.ipynb.

Wymagania wstępne

Przed wykonaniem kroków opisanych w tym artykule upewnij się, że masz następujące wymagania wstępne:

  • Subskrypcja platformy Azure. Jeśli nie masz subskrypcji platformy Azure, przed rozpoczęciem utwórz bezpłatne konto. Wypróbuj bezpłatną lub płatną wersję usługi Azure Machine Edukacja.

  • Obszar roboczy usługi Azure Machine Learning. Jeśli go nie masz, wykonaj kroki opisane w artykule Manage Azure Machine Edukacja workspaces (Zarządzanie obszarami roboczymi usługi Azure Machine Edukacja), aby je utworzyć.

  • Upewnij się, że masz następujące uprawnienia w obszarze roboczym:

    • Tworzenie punktów końcowych i wdrożeń wsadowych lub zarządzanie nimi: użyj roli właściciela, współautora lub niestandardowej, która zezwala na Microsoft.MachineLearningServices/workspaces/batchEndpoints/*usługę .

    • Tworzenie wdrożeń usługi ARM w grupie zasobów obszaru roboczego: użyj roli Właściciel, Współautor lub Niestandardowy, która umożliwia Microsoft.Resources/deployments/write korzystanie z grupy zasobów, w której wdrożono obszar roboczy.

  • Aby pracować z usługą Azure Machine Edukacja, należy zainstalować następujące oprogramowanie:

    Interfejs wiersza polecenia platformy mlAzure i rozszerzenie usługi Azure Machine Edukacja.

    az extension add -n ml
    

    Uwaga

    Wdrożenia składników potoku dla punktów końcowych usługi Batch zostały wprowadzone w wersji 2.7 rozszerzenia dla interfejsu ml wiersza polecenia platformy Azure. Użyj az extension update --name ml polecenia , aby pobrać ostatnią wersję.

Nawiązywanie połączenia z obszarem roboczym

Obszar roboczy jest zasobem najwyższego poziomu dla usługi Azure Machine Learning, który udostępnia scentralizowane miejsce do pracy z wszystkimi tworzonymi podczas korzystania usługi Azure Machine Learning artefaktami. W tej sekcji połączymy się z obszarem roboczym, w którym wykonasz zadania wdrażania.

Przekaż wartości identyfikatora subskrypcji, obszaru roboczego, lokalizacji i grupy zasobów w następującym kodzie:

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

Klasyfikacja obrazów z wdrożeniami wsadowymi

W tym przykładzie dowiesz się, jak wdrożyć model uczenia głębokiego, który może sklasyfikować dany obraz zgodnie z taksonomią usługi ImageNet.

Tworzenie punktu końcowego

Najpierw utwórzmy punkt końcowy, który będzie hostować model:

Zdecyduj o nazwie punktu końcowego:

ENDPOINT_NAME="imagenet-classifier-batch"

Następujący plik YAML definiuje punkt końcowy partii:

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

Uruchom następujący kod, aby utworzyć punkt końcowy.

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

Rejestrowanie modelu

Wdrożenia modelu mogą wdrażać tylko zarejestrowane modele, więc musimy je zarejestrować. Ten krok można pominąć, jeśli model, który próbujesz wdrożyć, jest już zarejestrowany.

  1. Pobieranie kopii modelu:

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

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

Tworzenie skryptu oceniania

Musimy utworzyć skrypt oceniania, który może odczytywać obrazy dostarczane przez wdrożenie wsadowe i zwracać wyniki modelu. Następujący skrypt:

  • Wskazuje funkcję, która ładuje init model przy użyciu keras modułu w programie tensorflow.
  • run Wskazuje funkcję, która jest wykonywana dla każdej mini-partii zapewnia wdrożenie wsadowe.
  • Funkcja run odczytuje jeden obraz pliku naraz
  • Metoda run zmienia rozmiar obrazów na oczekiwane rozmiary modelu.
  • Metoda run ponownie skaluje obrazy do domeny zakresu [0,1] , czyli tego, czego oczekuje model.
  • Zwraca klasy i prawdopodobieństwa skojarzone z przewidywaniami.

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)

Napiwek

Mimo że obrazy są dostarczane w minisadach przez wdrożenie, ten skrypt oceniania przetwarza jeden obraz naraz. Jest to typowy wzorzec, który próbuje załadować całą partię i wysyłać go naraz do modelu, może spowodować wysokie wykorzystanie pamięci w funkcji wykonawczej wsadowej (przykładowe operacje OOM). Istnieją jednak pewne przypadki, w których umożliwia to wysoką przepływność w zadaniu oceniania. Jest to przypadek na przykład wdrożeń wsadowych na sprzęcie gpu, w którym chcemy osiągnąć wysokie wykorzystanie procesora GPU. Zobacz Wdrożenia o wysokiej przepływności, aby zapoznać się z przykładem skryptu oceniania, który korzysta z niego.

Uwaga

Jeśli próbujesz wdrożyć model generowania (taki, który generuje pliki), przeczytaj, jak utworzyć skrypt oceniania zgodnie z opisem w temacie Wdrażanie modeli tworzących wiele plików.

Tworzenie wdrożenia

Po utworzeniu skryptu oceniania nadszedł czas na utworzenie wdrożenia wsadowego. Wykonaj następujące kroki, aby go utworzyć:

  1. Upewnij się, że masz utworzony klaster obliczeniowy, w którym można utworzyć wdrożenie. W tym przykładzie użyjemy klastra obliczeniowego o nazwie gpu-cluster. Mimo że nie jest to wymagane, używamy procesorów GPU do przyspieszenia przetwarzania.

  2. Musimy wskazać, w którym środowisku będziemy uruchamiać wdrożenie. W naszym przypadku nasz model działa w systemie TensorFlow. Usługa Azure Machine Edukacja ma już środowisko z zainstalowanym wymaganym oprogramowaniem, dzięki czemu możemy ponownie wykorzystać to środowisko. Dodamy tylko kilka zależności w conda.yml pliku.

    Definicja środowiska zostanie uwzględniona w pliku wdrożenia.

    compute: azureml:gpu-cluster
    environment:
      name: tensorflow212-cuda11-gpu
      image: mcr.microsoft.com/azureml/curated/tensorflow-2.12-cuda11:latest
    
  3. Teraz utwórz wdrożenie.

    Aby utworzyć nowe wdrożenie w ramach utworzonego punktu końcowego, utwórz konfigurację podobną YAML do poniższej. Możesz sprawdzić pełny schemat YAML punktu końcowego wsadowego pod kątem dodatkowych właściwości.

    $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
    

    Następnie utwórz wdrożenie za pomocą następującego polecenia:

    az ml batch-deployment create --file deployment-by-file.yml --endpoint-name $ENDPOINT_NAME --set-default
    
  4. Chociaż można wywołać określone wdrożenie wewnątrz punktu końcowego, zazwyczaj chcesz wywołać sam punkt końcowy i pozwolić punktowi końcowemu zdecydować, które wdrożenie ma być używane. Takie wdrożenie nosi nazwę "domyślnego" wdrożenia. Daje to możliwość zmiany domyślnego wdrożenia — a tym samym zmiany modelu obsługującego wdrożenie — bez zmiany umowy z użytkownikiem wywołującym punkt końcowy. Aby zaktualizować wdrożenie domyślne, użyj następującej instrukcji:

    az ml batch-endpoint update --name $ENDPOINT_NAME --set defaults.deployment_name=$DEPLOYMENT_NAME
    
  5. W tym momencie nasz punkt końcowy wsadowy jest gotowy do użycia.

Testowanie wdrożenia

Na potrzeby testowania punktu końcowego użyjemy próbki 1000 obrazów z oryginalnego zestawu danych ImageNet. Punkty końcowe usługi Batch mogą przetwarzać tylko dane znajdujące się w chmurze i dostępne z poziomu obszaru roboczego usługi Azure Machine Edukacja. W tym przykładzie przekażemy go do magazynu danych usługi Azure Machine Edukacja. W szczególności utworzymy zasób danych, który może służyć do wywoływania punktu końcowego na potrzeby oceniania. Należy jednak zauważyć, że punkty końcowe wsadowe akceptują dane, które można umieścić w wielu typach lokalizacji.

  1. Pobierzmy skojarzone przykładowe dane:

    wget https://azuremlexampledata.blob.core.windows.net/data/imagenet/imagenet-1000.zip
    unzip imagenet-1000.zip -d data
    
  2. Teraz utwórzmy zasób danych na podstawie właśnie pobranych danych

    Utwórz definicję zasobu danych w pliku 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
    

    Następnie utwórz zasób danych:

    az ml data create -f imagenet-sample-unlabeled.yml
    
  3. Teraz, gdy dane są przekazywane i gotowe do użycia, wywołajmy punkt końcowy:

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

    Uwaga

    jq Narzędzie może nie być zainstalowane w każdej instalacji. Możesz uzyskać instrukcje w tym linku.

    Napiwek

    Zwróć uwagę, że nie wskazujemy nazwy wdrożenia w operacji wywołania. Dzieje się tak, ponieważ punkt końcowy automatycznie kieruje zadanie do wdrożenia domyślnego. Ponieważ nasz punkt końcowy ma tylko jedno wdrożenie, jest to domyślne. Konkretne wdrożenie można określić, wskazując argument/parametr deployment_name.

  4. Zadanie wsadowe jest uruchamiane natychmiast po powrocie polecenia. Stan zadania można monitorować do momentu jego zakończenia:

    az ml job show -n $JOB_NAME --web
    
  5. Po zakończeniu wdrażania możemy pobrać przewidywania:

    Aby pobrać przewidywania, użyj następującego polecenia:

    az ml job download --name $JOB_NAME --output-name score --download-path ./
    
  6. Przewidywania wyjściowe będą wyglądać podobnie do poniższych. Zwróć uwagę, że przewidywania zostały połączone z etykietami dla wygody czytelnika. Aby dowiedzieć się więcej o tym, jak to osiągnąć, zobacz skojarzony notes.

    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
    
    plik class Prawdopodobieństwa label
    n02088094_Afghan_hound. JPEG 161 0.994745 Afgańscy hound
    n02088238_basset 162 0.999397 Basset
    n02088364_beagle. JPEG 165 0.366914 bluetick
    n02088466_bloodhound. JPEG 164 0.926464 Ogar
    ... ... ... ...

Wdrożenia o wysokiej przepływności

Jak wspomniano wcześniej, wdrożenie, które właśnie utworzyliśmy, przetwarza jeden obraz raz, nawet gdy wdrożenie wsadowe udostępnia partię. W większości przypadków jest to najlepsze podejście, ponieważ upraszcza sposób wykonywania modeli i unika wszelkich możliwych problemów z brakiem pamięci. Jednak w niektórych innych możemy chcieć saturate jak najwięcej wykorzystania bazowego sprzętu. Dotyczy to na przykład procesorów GPU.

W takich przypadkach możemy chcieć przeprowadzić wnioskowanie na całej partii danych. Oznacza to załadowanie całego zestawu obrazów do pamięci i wysłanie ich bezpośrednio do modelu. W poniższym przykładzie użyto TensorFlow metody odczytywania partii obrazów i oceniania ich wszystkich jednocześnie. Używa TensorFlow również operacji do przetwarzania wstępnego danych, więc cały potok będzie występować na tym samym urządzeniu, które jest używane (procesor CPU/GPU).

Ostrzeżenie

Niektóre modele mają nieliniową relację z rozmiarem danych wejściowych pod względem zużycia pamięci. Wsad ponownie (jak pokazano w tym przykładzie) lub zmniejsz rozmiar partii utworzonych przez wdrożenie wsadowe, aby uniknąć wyjątków poza pamięcią.

  1. Tworzenie skryptu oceniania:

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

    Napiwek

    • Zwróć uwagę, że ten skrypt tworzy zestaw danych tensor z mini-partii wysyłanej przez wdrożenie wsadowe. Ten zestaw danych jest wstępnie przetworzony w celu uzyskania oczekiwanych tensorów dla modelu przy użyciu map operacji z funkcją decode_img.
    • Zestaw danych jest ponownie wsadowy (16) wysyła dane do modelu. Użyj tego parametru, aby kontrolować ilość informacji, które można załadować do pamięci i wysyłać do modelu jednocześnie. Jeśli działa na procesorze GPU, należy dokładnie dostosować ten parametr, aby osiągnąć maksymalne wykorzystanie procesora GPU tuż przed uzyskaniem wyjątku OOM.
    • Po obliczeniu przewidywań tensor jest konwertowany na numpy.ndarraywartość .
  2. Teraz utwórz wdrożenie.

    Aby utworzyć nowe wdrożenie w ramach utworzonego punktu końcowego, utwórz konfigurację podobną YAML do poniższej. Możesz sprawdzić pełny schemat YAML punktu końcowego wsadowego pod kątem dodatkowych właściwości.

    $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
    

    Następnie utwórz wdrożenie za pomocą następującego polecenia:

    az ml batch-deployment create --file deployment-by-batch.yml --endpoint-name $ENDPOINT_NAME --set-default
    
  3. Możesz użyć tego nowego wdrożenia z przykładowymi danymi pokazanymi wcześniej. Pamiętaj, że aby wywołać to wdrożenie, należy wskazać nazwę wdrożenia w metodzie wywołania lub ustawić ją jako domyślną.

Zagadnienia dotyczące przetwarzania obrazów modeli MLflow

Modele MLflow w punktach końcowych usługi Batch obsługują odczytywanie obrazów jako danych wejściowych. Ponieważ wdrożenia platformy MLflow nie wymagają skryptu oceniania, podczas korzystania z nich należy wziąć pod uwagę następujące kwestie:

  • Obsługiwane pliki obrazów obejmują: .png, , .jpeg.jpg, .bmp.tiffi .gif.
  • Modele MLflow powinny oczekiwać otrzymania np.ndarray jako danych wejściowych, które będą zgodne z wymiarami obrazu wejściowego. Aby obsługiwać wiele rozmiarów obrazów w każdej partii, funkcja wykonawcza partii wywoła model MLflow raz na plik obrazu.
  • Modele MLflow są zdecydowanie zachęcane do uwzględnienia podpisu i jeśli to zrobić, musi być typu TensorSpec. Dane wejściowe są zmieniane, aby dopasować kształt tensora, jeśli jest dostępny. Jeśli podpis nie jest dostępny, wnioskowane są tensory typu np.uint8 .
  • W przypadku modeli zawierających podpis i oczekuje się, że będą obsługiwać zmienny rozmiar obrazów, dołącz podpis, który może go zagwarantować. Na przykład poniższy przykład podpisu umożliwi partii 3 obrazów kanałowych.
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)

Przykład roboczy można znaleźć w pliku imagenet-classifier-mlflow.ipynb notesu Jupyter Notebook. Aby uzyskać więcej informacji o sposobie używania modeli MLflow we wdrożeniach wsadowych, zobacz Korzystanie z modeli MLflow we wdrożeniach wsadowych.

Następne kroki