다음을 통해 공유


일괄 처리 모델 배포를 통한 이미지 처리

적용 대상:Azure CLI ml 확장 v2(현재)Python SDK azure-ai-ml v2(현재)

일괄 처리 모델 배포는 표 형식 데이터를 처리하는 데 사용할 수 있지만 이미지와 같은 다른 파일 형식에도 사용할 수 있습니다. 이러한 배포는 MLflow 및 사용자 지정 모델 모두에서 지원됩니다. 이 자습서에서는 ImageNet 분류법에 따라 이미지를 분류하는 모델을 배포하는 방법을 알아봅니다.

이 샘플 정보

작업할 모델은 RestNet 아키텍처(딥 잔류 네트워크의 ID 매핑)와 함께 TensorFlow를 사용하여 빌드되었습니다. 이 모델의 샘플은 여기에서 다운로드할 수 있습니다. 이 모델에는 배포 시 염두에 두어야 할 다음과 같은 제약 조건이 있습니다.

  • 크기가 244x244인 이미지((224, 224, 3)의 텐서)에서 작동합니다.
  • 입력을 [0,1] 범위로 조정해야 합니다.

이 문서의 정보는 azureml-examples 리포지토리에 포함된 코드 샘플을 기반으로 합니다. YAML 및 기타 파일을 복사/붙여넣기하지 않고 로컬에서 명령을 실행하려면 리포지토리를 복제한 다음 Azure CLI를 사용하는 경우 cli/endpoints/batch/deploy-models/imagenet-classifier로, Python용 SDK를 사용하는 경우 sdk/python/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 Notebooks에서 따라하기

Jupyter Notebook에서 이 샘플을 따를 수 있습니다. 복제된 리포지토리에서 imagenet-classifier-batch.ipynb Notebook을 엽니다.

필수 조건

이 문서의 단계를 수행하기 전에 다음과 같은 필수 구성 요소가 있는지 확인합니다.

  • Azure 구독 Azure 구독이 아직 없는 경우 시작하기 전에 체험 계정을 만듭니다. Azure Machine Learning 평가판 또는 유료 버전을 사용해 보세요.

  • Azure Machine Learning 작업 영역 작업 영역이 없으면 Azure Machine Learning 작업 영역 관리 문서의 단계에서 새로 만듭니다.

  • 작업 영역에 다음 권한이 있는지 확인합니다.

    • 일괄 처리 엔드포인트 및 배포 만들기 또는 관리: Microsoft.MachineLearningServices/workspaces/batchEndpoints/*를 허용하는 소유자, 기여자 또는 사용자 지정 역할을 사용합니다.

    • 작업 영역 리소스 그룹에서 ARM 배포 만들기: 작업 영역이 배포된 리소스 그룹에서 Microsoft.Resources/deployments/write를 허용하는 소유자, 기여자 또는 사용자 지정 역할을 사용합니다.

  • Azure Machine Learning을 사용하려면 다음 소프트웨어를 설치해야 합니다.

    Azure CLImlAzure Machine Learning용 확장.

    az extension add -n ml
    

    참고 항목

    일괄 처리 엔드포인트에 대한 파이프라인 구성 요소 배포는 Azure CLI용 ml 확장 버전 2.7에 도입되었습니다. 최신 버전을 가져오려면 az extension update --name ml을 사용합니다.

작업 영역에 연결

작업 영역은 Azure Machine Learning의 최상위 리소스로, Azure Machine Learning을 사용할 때 만든 모든 아티팩트를 사용할 수 있는 중앙 집중식 환경을 제공합니다. 이 섹션에서는 배포 작업을 수행할 작업 영역에 연결합니다.

다음 코드에서 구독 ID, 작업 영역, 위치 및 리소스 그룹에 대한 값을 전달합니다.

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

일괄 처리 배포를 통한 이미지 분류

이 예에서는 ImageNet의 분류에 따라 지정된 이미지를 분류할 수 있는 딥 러닝 모델을 배포하는 방법을 배우려고 합니다.

엔드포인트 만들기

먼저 모델을 호스팅할 엔드포인트를 만들어 보겠습니다.

엔드포인트의 이름을 결정합니다.

ENDPOINT_NAME="imagenet-classifier-batch"

다음 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"
    

채점 스크립트 만들기

일괄 처리 배포에서 제공하는 이미지를 읽고 모델의 점수를 반환할 수 있는 채점 스크립트를 만들어야 합니다. 다음 스크립트는

  • tensorflowkeras 모듈을 사용하여 모델을 로드하는 init 함수를 나타냅니다.
  • 일괄 처리 배포가 제공하는 각 미니 일괄 처리에 대해 실행되는 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. 배포를 실행할 환경을 지정해야 합니다. Microsoft의 경우 모델은 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
    
  5. 이제 일괄 처리 엔드포인트를 사용할 준비가 되었습니다.

배포 테스트

엔드포인트를 테스트하기 위해 원본 ImageNet 데이터 세트에서 1000개의 이미지 샘플을 사용할 것입니다. 일괄 처리 엔드포인트는 클라우드에 있고 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
    
  2. 이제 방금 다운로드한 데이터에서 데이터 자산을 만들어 보겠습니다.

    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
    

    그런 다음, 데이터 자산을 만듭니다.

    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 유틸리티가 설치되지 않을 수도 있습니다. 이 링크에서 지침을 가져올 수 있습니다.

    호출 작업에서 배포 이름을 표시하지 않는 방법에 유의합니다. 엔드포인트가 자동으로 작업을 기본 배포로 라우팅하기 때문입니다. 엔드포인트에는 배포가 하나만 있으므로 해당 배포가 기본 배포입니다. 인수/매개 변수 deployment_name을 표시하여 특정 배포를 대상으로 지정할 수 있습니다.

  4. 명령이 반환되는 즉시 일괄 작업이 시작됩니다. 완료될 때까지 작업 상태를 모니터링할 수 있습니다.

    az ml job show -n $JOB_NAME --web
    
  5. 배포가 완료되면 예측을 다운로드할 수 있습니다.

    예측을 다운로드하려면 다음 명령을 사용합니다.

    az ml job download --name $JOB_NAME --output-name score --download-path ./
    
  6. 출력 예측은 다음과 같습니다. 읽기 권한자의 편의를 위해 예측이 레이블과 결합되었음을 알 수 있습니다. 이를 달성하는 방법에 대한 자세한 내용은 관련 Notebook을 참조하세요.

    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 Afghan hound
    n02088238_basset 162 0.999397 basset
    n02088364_beagle.JPEG 165 0.366914 bluetick
    n02088466_bloodhound.JPEG 164 0.926464 bloodhound
    ... ... ... ...

높은 처리량 배포

앞에서 언급했듯이 방금 만든 배포는 일괄 처리 배포가 일괄 처리를 제공하는 경우에도 한 번에 하나의 이미지를 처리합니다. 대부분의 경우 모델이 실행되는 방식을 단순화하고 가능한 메모리 부족 문제를 방지하므로 이것이 최선의 방식입니다. 그러나 일부 다른 하드웨어에서는 기본 하드웨어의 사용률을 가능한 한 많이 포화시킬 수 있습니다. 예를 들어, GPU의 경우입니다.

이러한 경우 전체 데이터 일괄 처리에 대해 유추를 수행할 수 있습니다. 이는 전체 이미지 집합을 메모리에 로드하고 모델에 직접 보내는 것을 의미합니다. 다음 예에서는 TensorFlow를 사용하여 이미지 일괄 처리를 읽고 한 번에 점수를 매깁니다. 또한 TensorFlow 작업을 사용하여 데이터 전처리를 수행하므로 전체 파이프라인이 사용 중인 동일한 디바이스(CPU/GPU)에서 발생합니다.

Warning

일부 모델은 메모리 사용량 측면에서 입력 크기와 비선형 관계가 있습니다. 메모리 부족 예외를 방지하려면 일괄 처리를 다시 수행하거나(이 예에서 수행한 대로) 일괄 처리 배포로 만들어진 일괄 처리의 크기를 줄입니다.

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

    • 이 스크립트는 일괄 처리 배포에서 보낸 미니 일괄 처리에서 텐서 데이터 세트를 생성합니다. 이 데이터 세트는 decode_img 함수와 함께 map 작업을 사용하여 모델에 대한 예상 텐서를 가져오기 위해 전처리됩니다.
    • 데이터 세트는 다시 일괄 처리됩니다(16). 데이터를 모델로 보냅니다. 이 매개 변수를 사용하여 한 번에 메모리에 로드하고 모델로 보낼 수 있는 정보의 양을 제어합니다. GPU에서 실행 중인 경우 OOM 예외가 발생하기 직전에 GPU를 최대한 활용하도록 이 매개 변수를 신중하게 조정해야 합니다.
    • 예측이 계산되면 텐서는 numpy.ndarray로 변환됩니다.
  2. 이제 배포를 만들겠습니다.

    만들어진 엔드포인트에서 새 배포를 만들려면 다음과 같이 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
    

    그런 후 다음 명령을 사용하여 배포를 만듭니다.

    az ml batch-deployment create --file deployment-by-batch.yml --endpoint-name $ENDPOINT_NAME --set-default
    
  3. 이전에 표시된 샘플 데이터와 함께 이 새 배포를 사용할 수 있습니다. 이 배포를 호출하려면 호출 방법에 배포 이름을 표시하거나 기본 이름으로 설정해야 합니다.

이미지를 처리하는 MLflow 모델에 대한 고려 사항

일괄 처리 엔드포인트의 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 Notebook imagenet-classifier-mlflow.ipynb에서 작업 예를 찾을 수 있습니다. 일괄 처리 배포에서 MLflow 모델을 사용하는 방법에 대한 자세한 내용은 일괄 처리 배포에서 MLflow 모델 사용을 참조하세요.

다음 단계