共用方式為


使用批次模型部署進行映像處理

適用於:Azure CLI ml 延伸模組 v2 (目前)Python SDK azure-ai-ml v2 (目前)

您可以使用批次模型部署處理表格式資料,也可以處理其他檔案類型,例如映像。 MLflow 和自訂模型都支援這些部署。 在本文中,您會了解如何部署模型,以根據 ImageNet 分類法分類映像。

必要條件

  • Azure 訂用帳戶。 如果您沒有 Azure 訂用帳戶,請在開始前建立免費帳戶

  • Azure Machine Learning 工作區。 若要建立工作區,請參閱 管理 Azure Machine Learning 工作區

  • Azure 機器學習 工作區中的下列許可權:

    • 若要建立或管理批次端點和部署:請使用已指派 Microsoft.MachineLearningServices/workspaces/batchEndpoints/* 許可權的擁有者、參與者或自定義角色。
    • 若要在工作區資源群組中建立 Azure Resource Manager 部署:請使用已指派 Microsoft.Resources/deployments/write 工作區部署之資源群組中許可權的擁有者、參與者或自定義角色。
  • Azure 機器學習 CLI 或適用於 Python 的 Azure 機器學習 SDK:

    執行下列命令來安裝 Azure CLImlAzure Machine Learning 的擴充功能

    az extension add -n ml
    

    批次端點的管線元件部署是在 Azure CLI 的 ml 延伸模組 2.7 版中引進。 使用 az extension update --name ml 命令來取得最新版本。


連線到您的工作區

工作區是 Azure Machine Learning 的最上層資源。 它提供集中的位置,讓您在使用 Azure 機器學習 時使用您建立的所有成品。 在本節中,您會連線到要執行部署工作的工作區。

在下列命令中,輸入您的訂用帳戶識別碼、工作區名稱、資源組名和位置:

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

關於此範例

本文使用透過 TensorFlow 以及 RestNet 架構建置的模型。 如需詳細資訊,請參閱識別深層殘差網路中的對應。 您可以下載此模型樣本。 該模型有下列限制:

  • 其適用於大小為 244x244 的映像 (張量 (224, 224, 3))。
  • 其需要將輸入調整為範圍 [0,1]

本文中的資訊是以 azureml-examples 存放庫中包含的程式碼範例為基礎。 若要在本機執行命令,而不複製/貼上 YAML 和其他檔案,請先複製存放庫。 如果您使用 Azure CLI 或 sdk/python/endpoints/batch/deploy-models/imagenet-classifier,請將目錄變更為 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

在 Jupyter Notebook 中跟著做

您可以在 Jupyter Notebook 中遵循此範例。 在複製的存放庫中,開啟筆記本:imagenet-classifier-batch.ipynb

使用批次部署的影像分類

在此範例中,您會了解如何部署深度學習模型,以根據 ImageNet 的分類法來分類指定的映像。

建立端點

建立裝載模型的端點:

  1. 指定端點名稱。

    ENDPOINT_NAME="imagenet-classifier-batch"
    
  2. 建立下列 YAML 檔案,以定義名為 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
    

    若建立端點,請執行下列程式碼:

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

註冊模型

模型部署只能部署已註冊的模型。 您必須註冊模型。 如果您已註冊您嘗試部署的模型,則可以略過此步驟。

  1. 下載模型的複本。

    wget https://azuremlexampledata.blob.core.windows.net/data/imagenet/model.zip
    unzip model.zip -d .
    
  2. 註冊模型。

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

建立評分指令碼

建立評分指令碼、讀取批次部署所提供的映像,然後傳回模型的分數。

  • init 方法會使用 tensorflow 中的 keras 模組載入模型。
  • run 方法會針對批次部署所提供的每個迷你批次執行。
  • run 方法一次讀取一個檔案映像。
  • run 方法會將映像大小調整為模型的預期大小。
  • run 方法會將映像重新調整為範圍 [0,1] 網域,這是模型預期的情況。
  • 指令碼會傳回與預測相關聯的類別和機率。

此程式碼是 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)

提示

雖然部署是以迷你批次提供映像,但此評分指令碼會一次處理一個映像。 這是很常見的模式,因為嘗試載入整個批次並一次傳送至模型,可能會導致批次執行程式面臨高記憶體壓力 (OOM 例外狀況)。

在某些情況下,這麼做會在評分工作中造成高輸送量。 若您想達到高 GPU 使用率,則這是在 GPU 硬體上批次部署執行個體的情況。 如需採用此方法的評分指令碼,請參閱高輸送量部署

注意

如果您要部署產生檔案的生成式模型,請了解如何撰寫評分指令碼:自訂批次部署中的輸出

建立部署

建立評分指令碼後,請針對該指令碼建立批次部署。 請使用下列程序:

  1. 確定您已建立計算叢集,我們可以在該叢集中建立部署。 在此範例中,使用名為 gpu-cluster 的計算叢集。 雖然不是必須使用 GPU,但這麼做可加速處理。

  2. 指定要執行部署的環境。 在此範例中,模型會在 TensorFlow 上執行。 Azure Machine Learning 已有環境且已安裝必要軟體,因此您可以重新利用這個環境。 您需要在 conda.yml 檔案中新增幾個相依性。

    環境定義會包含在部署檔案中。

    compute: azureml:gpu-cluster
    environment:
      name: tensorflow212-cuda11-gpu
      image: mcr.microsoft.com/azureml/curated/tensorflow-2.12-cuda11:latest
    
  3. 建立部署。

    若要在已建立的端點下建立新部署,請建立 YAML 設定,如下列範例所示。 如需其他屬性,請參閱完整批次端點 YAML 結構描述

    $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
    

    使用下列命令建立部署:

    az ml batch-deployment create --file deployment-by-file.yml --endpoint-name $ENDPOINT_NAME --set-default
    
  4. 雖然您可以在端點內叫用特定部署,但是您通常會想要叫用端點本身,讓端點決定要使用的部署。 這類部署稱為預設部署。

    此方法可變更預設部署並變更提供部署的模型,但不需變更與叫用端點使用者之間的合約。 使用下列程式碼來更新預設部署:

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

您的批次端點已可使用。

測試部署

為了測試端點,使用來自原始 ImageNet 資料集的 1,000 個映像範例。 批次端點只能處理位於雲端且可從 Azure Machine Learning 工作區存取的資料。 將其上傳至 Azure Machine Learning 資料存放區。 建立可用於叫用端點以進行評分的資料資產。

注意

批次端點可接受可放置在多個位置類型的資料。

  1. 下載相關範例資料。

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

    注意

    如果您沒有在本機安裝 wget,請安裝或使用瀏覽器以取得 .zip 檔案。

  2. 用下載的資料建立資料資產。

    1. 在名為 imagenet-sample-unlabeled.ymlYAML 檔案中,建立資料資產定義:

      $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. 建立資料資產。

      az ml data create -f imagenet-sample-unlabeled.yml
      
  3. 請在上傳資料且資料可供使用後,叫用端點。

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

    注意

    如果未安裝公用程式 jq,請參閱 Download jq


提示

您不能在叫用作業中指出部署名稱。 這是因為端點會自動將工作路由至預設部署。 因為端點只有一個部署,所以該部署就是預設部署。 您可以指示引數/參數 deployment_name,以特定部署為目標。

  1. 命令傳回時,會立即啟動批次工作。 工作完成前,您都可以監視工作狀態。

    az ml job show -n $JOB_NAME --web
    
  2. 在部署完成後,可以下載預測。

    若要下載預測,請使用下列命令:

    az ml job download --name $JOB_NAME --output-name score --download-path ./
    
  3. 預測顯示如下輸出。 預測已與標籤結合,方便閱讀程式使用。 若要了解如何達成此效果,請參閱相關筆記本。

    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
    
    檔案 class 機率 label
    n02088094_Afghan_hound.JPEG 161 0.994745 阿富汗獵犬
    n02088238_basset 162 0.999397 巴吉度獵犬
    n02088364_beagle.JPEG 165 0.366914 布魯泰克獵浣熊犬
    n02088466_bloodhound.JPEG 164 0.926464 尋血獵犬
    ... ... ... ...

高輸送量部署

如前所述,部署一次處理一個映像,即使批次部署提供一批映像也是如此。 在大部分情況下,此方法是最佳方法。 它可簡化模型執行的方式,並避免任何可能的記憶體不足問題。 不過,在部分情況下,您可能會想盡可能讓基礎硬體達到飽和。 例如,GPU 就是這種情況。

在這些情況下,您可能會想要對整個批次的資料執行推斷。 此方式會將整個映像集載入記憶體,並將其直接傳送至模型。 下列範例會使用 TensorFlow 來讀取映像批次,並一次為映像評分。 它也會使用 TensorFlow 作業,以執行任何資料前置處理。 整個管線都會發生在使用中的相同裝置 (CPU/GPU) 上。

警告

有些模型與輸入的大小在記憶體耗用量方面,有非線性關聯性。 若要避免記憶體不足的例外狀況,請再次進行批次處理 (如此範例中所執行) 或減少批次部署所建立的批次大小。

  1. 建立評分指令碼 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"]
        )
    
    • 此指令碼會透過批次部署所傳送的迷你批次,建構張量資料集。 此資料集會預先處理,以使用 map 作業搭配 decode_img 函式來取得模型的預期張量。
    • 資料集會再次進行批次處理 (16),以將資料傳送至模型。 使用此參數來控制您可以載入記憶體中多少資訊,並一次傳送至模型。 如果在 GPU 上執行,您必須仔細調整此參數,以在取得 OOM 例外狀況之前,達到 GPU 最大使用率。
    • 計算預測後,張量會轉換成 numpy.ndarray
  2. 建立部署。

    1. 若要在已建立的端點下建立新部署,請建立 YAML 設定,如下列範例所示。 如需其他屬性,請參閱完整批次端點 YAML 結構描述
    $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. 使用下列命令建立部署:
    az ml batch-deployment create --file deployment-by-batch.yml --endpoint-name $ENDPOINT_NAME --set-default
    
  3. 您可以使用這個新的部署搭配先前所示的範例資料。 請記得,若要叫用此部署,請在叫用方法中指出部署的名稱,或將它設定為預設部署的名稱。

MLflow 模型處理映像的注意事項

Batch 端點中的 MLflow 模型支援將映像讀取為輸入資料。 由於 MLflow 部署不需要評分指令碼,因此使用時請考慮下列事項:

  • 支援的映像檔包括:.png.jpg.jpeg.tiff.bmp.gif
  • MLflow 模型應該會收到 np.ndarray 作為輸入,其符合輸入映像的維度。 為了支援每個批次上的多個映像大小,批次執行程式會針對每個映像檔叫用 MLflow 模型一次。
  • 強烈建議將 MLflow 模型加入簽章。 若要加入,必須為 TensorSpec 類型。 如果有的話,輸入會重新調整以符合張量圖形。 如果沒有可用的簽章,則會推斷類型 np.uint8 的張量。
  • 對包含簽章且預期會處理不同大小映像的模型,加入可加以保證的簽章。 例如,下列簽章範例允許 3 個通道映像的批次。
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)

您可以在 Jupyter 筆記本中 imagenet-classifier-mlflow.ipynb 找到工作範例。 如需如何在批次部署中使用 MLflow 模型的詳細資訊,請參閱在批次部署中使用 MLflow 模型

下一步