다음을 통해 공유


일괄 처리 엔드포인트에 언어 모델 배포

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

일괄 처리 엔드포인트를 사용하면 언어 모델과 같은 값비싼 모델을 텍스트 데이터에 배포할 수 있습니다. 이 자습서에서는 HuggingFace의 모델을 사용하여 긴 텍스트 시퀀스의 텍스트 요약을 수행할 수 있는 모델을 배포하는 방법을 알아봅니다. 또한 HuggingFace optimumaccelerate 라이브러리를 사용하여 유추 최적화를 수행하는 방법을 보여 줍니다.

이 샘플 정보

작업할 모델은 HuggingFace의 자주 사용되는 라이브러리 변환기와 BART 아키텍처가 있는 Facebook의 선행 학습된 모델을 사용하여 빌드되었습니다. BART: Denoising Sequence-to-Sequence Pre-training for Natural Language Generation 논문에 소개되었습니다. 이 모델에는 배포 시 염두에 두어야 할 다음과 같은 제약 조건이 있습니다.

  • 최대 1024개의 토큰 시퀀스로 작업할 수 있습니다.
  • 영어로 된 텍스트의 요약을 위해 학습됩니다.
  • Microsoft는 Torch를 백 엔드로 사용할 것입니다.

이 문서의 예는 azureml-examples 리포지토리에 포함된 코드 샘플을 기반으로 합니다. YAML 및 기타 파일을 복사/붙여넣기하지 않고 로컬로 명령을 실행하려면 먼저 리포지토리를 복제한 후 디렉터리를 폴더로 변경합니다.

git clone https://github.com/Azure/azureml-examples --depth 1
cd azureml-examples/cli

이 예의 파일은 다음 위치에 있습니다.

cd endpoints/batch/deploy-models/huggingface-text-summarization

Jupyter Notebooks에서 따라하기

Jupyter Notebook에서 이 샘플을 따를 수 있습니다. 복제된 리포지토리에서 text-summarization-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>

모델 등록

모델의 크기로 인해 이 리포지토리에 포함되지 않았습니다. 대신 HuggingFace 모델 허브에서 복사본을 다운로드할 수 있습니다. 사용 중인 환경에 패키지 transformerstorch가 설치되어 있어야 합니다.

%pip install transformers torch

다음 코드를 사용하여 모델을 폴더 model에 다운로드합니다.

from transformers import pipeline

model = pipeline("summarization", model="facebook/bart-large-cnn")
model_local_path = 'model'
summarizer.save_pretrained(model_local_path)

이제 Azure Machine Learning 레지스트리에 이 모델을 등록할 수 있습니다.

MODEL_NAME='bart-text-summarization'
az ml model create --name $MODEL_NAME --path "model"

엔드포인트 만들기

영어로 된 텍스트 파일에 대한 텍스트 요약을 실행하기 위해 HuggingFace 모델을 배포할 text-summarization-batch라는 일괄 처리 엔드포인트를 만들 예정입니다.

  1. 엔드포인트의 이름을 결정합니다. 엔드포인트의 이름은 엔드포인트와 연결된 URI로 끝납니다. 따라서 일괄 처리 엔드포인트 이름은 Azure 지역 내에서 고유해야 합니다. 예를 들어, westus2에는 이름이 mybatchendpoint인 일괄 처리 엔드포인트가 하나만 있을 수 있습니다.

    이 경우 나중에 쉽게 참조할 수 있도록 엔드포인트의 이름을 변수에 배치해 보겠습니다.

    ENDPOINT_NAME="text-summarization-batch"
    
  2. 일괄 처리 엔드포인트 구성

    다음 YAML 파일은 일괄 처리 엔드포인트를 정의합니다.

    endpoint.yml

    $schema: https://azuremlschemas.azureedge.net/latest/batchEndpoint.schema.json
    name: text-summarization-batch
    description: A batch endpoint for summarizing text using a HuggingFace transformer model.
    auth_mode: aad_token
    
  3. 엔드포인트 만들기:

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

배포 만들기

모델을 호스팅하는 배포를 만들어 보겠습니다.

  1. 일괄 처리 배포에서 제공하는 CSV 파일을 읽고 요약과 함께 모델의 점수를 반환할 수 있는 채점 스크립트를 만들어야 합니다. 다음 스크립트는 다음 작업을 수행합니다.

    • 하드웨어 구성(CPU 및 GPU)을 검색하고 그에 따라 모델을 로드하는 init 함수를 나타냅니다. 모델과 토크나이저 모두 전역 변수에 로드됩니다. 현재 사용 중인 모델의 시퀀스 길이 제한 사항을 설명하기 위해 HuggingFace의 pipeline 개체를 사용하지 않습니다.
    • optimumaccelerate 라이브러리를 사용하여 성능을 개선하기 위해 모델 최적화를 수행하고 있습니다. 모델이나 하드웨어가 이를 지원하지 않는 경우 이러한 최적화 없이 배포를 실행합니다.
    • 일괄 처리 배포가 제공하는 각 미니 일괄 처리에 대해 실행되는 run 함수를 나타냅니다.
    • run 함수는 datasets 라이브러리를 사용하여 전체 일괄 처리를 읽습니다. 요약해야 하는 텍스트는 text 열에 있습니다.
    • run 메서드는 텍스트의 각 행을 반복하고 예측을 실행합니다. 이는 매우 비용이 많이 드는 모델이므로 전체 파일에 대해 예측을 실행하면 메모리 부족 예외가 발생합니다. 모델은 transformerspipeline 개체로 실행되지 않습니다. 이 작업은 긴 텍스트 시퀀스와 사용 중인 기본 모델에서 1024개의 토큰 제한 사항을 설명하기 위해 수행됩니다.
    • 제공된 텍스트의 요약을 반환합니다.

    code/batch_driver.py

    import os
    import time
    import torch
    import subprocess
    import mlflow
    from pprint import pprint
    from transformers import AutoTokenizer, BartForConditionalGeneration
    from optimum.bettertransformer import BetterTransformer
    from datasets import load_dataset
    
    
    def init():
        global model
        global tokenizer
        global device
    
        cuda_available = torch.cuda.is_available()
        device = "cuda" if cuda_available else "cpu"
    
        if cuda_available:
            print(f"[INFO] CUDA version: {torch.version.cuda}")
            print(f"[INFO] ID of current CUDA device: {torch.cuda.current_device()}")
            print("[INFO] nvidia-smi output:")
            pprint(
                subprocess.run(["nvidia-smi"], stdout=subprocess.PIPE).stdout.decode(
                    "utf-8"
                )
            )
        else:
            print(
                "[WARN] CUDA acceleration is not available. This model takes hours to run on medium size data."
            )
    
        # AZUREML_MODEL_DIR is an environment variable created during deployment
        model_path = os.path.join(os.environ["AZUREML_MODEL_DIR"], "model")
    
        # load the tokenizer
        tokenizer = AutoTokenizer.from_pretrained(
            model_path, truncation=True, max_length=1024
        )
    
        # Load the model
        try:
            model = BartForConditionalGeneration.from_pretrained(
                model_path, device_map="auto"
            )
        except Exception as e:
            print(
                f"[ERROR] Error happened when loading the model on GPU or the default device. Error: {e}"
            )
            print("[INFO] Trying on CPU.")
            model = BartForConditionalGeneration.from_pretrained(model_path)
            device = "cpu"
    
        # Optimize the model
        if device != "cpu":
            try:
                model = BetterTransformer.transform(model, keep_original_model=False)
                print("[INFO] BetterTransformer loaded.")
            except Exception as e:
                print(
                    f"[ERROR] Error when converting to BetterTransformer. An unoptimized version of the model will be used.\n\t> {e}"
                )
    
        mlflow.log_param("device", device)
        mlflow.log_param("model", type(model).__name__)
    
    
    def run(mini_batch):
        resultList = []
    
        print(f"[INFO] Reading new mini-batch of {len(mini_batch)} file(s).")
        ds = load_dataset("csv", data_files={"score": mini_batch})
    
        start_time = time.perf_counter()
        for idx, text in enumerate(ds["score"]["text"]):
            # perform inference
            inputs = tokenizer.batch_encode_plus(
                [text], truncation=True, padding=True, max_length=1024, return_tensors="pt"
            )
            input_ids = inputs["input_ids"].to(device)
            summary_ids = model.generate(
                input_ids, max_length=130, min_length=30, do_sample=False
            )
            summaries = tokenizer.batch_decode(
                summary_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False
            )
    
            # Get results:
            resultList.append(summaries[0])
            rps = idx / (time.perf_counter() - start_time + 00000.1)
            print("Rows per second:", rps)
    
        mlflow.log_metric("rows_per_second", rps)
        return resultList
    

    배포 시 파일이 미니 일괄 처리로 제공되지만 이 채점 스크립트는 한 번에 한 행씩 처리합니다. 전체 일괄 처리를 로드하고 한 번에 모델로 보내려고 하면 일괄 처리 실행기(OOM 예외)에 높은 메모리 압력이 발생할 수 있으므로 비용이 많이 드는 모델(예: 변환기)을 처리할 때 일반적인 패턴입니다.

  2. 배포를 실행할 환경을 지정해야 합니다. Microsoft의 경우 모델은 Torch에서 실행되며 HuggingFace의 라이브러리 transformers, accelerateoptimum이 필요합니다. Azure Machine Learning에는 이미 Torch 및 GPU 지원이 가능한 환경이 있습니다. conda.yaml 파일에 몇 가지 종속성을 추가할 것입니다.

    environment/torch200-conda.yaml

    name: huggingface-env
    channels:
      - conda-forge
    dependencies:
      - python=3.8.5
      - pip
      - pip:
        - torch==2.0
        - transformers
        - accelerate
        - optimum
        - datasets
        - mlflow
        - azureml-mlflow
        - azureml-core
        - azureml-dataset-runtime[fuse]
    
  3. 앞서 언급한 conda 파일을 다음과 같이 사용할 수 있습니다.

    환경 정의는 배포 파일에 포함됩니다.

    deployment.yml

    compute: azureml:gpu-cluster
    environment:
      name: torch200-transformers-gpu
      image: mcr.microsoft.com/azureml/openmpi4.1.0-cuda11.8-cudnn8-ubuntu22.04:latest
    

    Important

    우리가 만든 환경 torch200-transformers-gpu에는 Torch 2.0 및 Ubuntu 20.04를 실행하려면 CUDA 11.8 호환 하드웨어 디바이스가 필요합니다. GPU 디바이스가 이 버전의 CUDA를 지원하지 않는 경우 CUDA 10.1을 사용하여 Ubuntu 18.04에서 Torch 1.3을 실행하는 대체 torch113-conda.yaml conda 환경(리포지토리에서도 사용 가능)을 확인할 수 있습니다. 그러나 이 구성에서는 optimumaccelerate 라이브러리를 사용한 가속이 지원되지 않습니다.

  4. 각 배포는 컴퓨팅 클러스터에서 실행됩니다. Azure Machine Learning 컴퓨팅 클러스터(AmlCompute) 또는 Kubernetes 클러스터를 모두 지원합니다. 이 예에서 Microsoft 모델은 GPU 가속의 이점을 누릴 수 있으므로 GPU 클러스터를 사용합니다.

    az ml compute create -n gpu-cluster --type amlcompute --size STANDARD_NV6 --min-instances 0 --max-instances 2
    

    참고 항목

    일괄 처리 엔드포인트가 호출되고 일괄 처리 채점 작업이 제출될 때까지 클러스터가 0개 노드로 유지되기 때문에 이 시점에는 컴퓨팅에 대한 요금이 청구되지 않습니다. AmlCompute의 비용을 관리하고 최적화하는 방법에 대해 자세히 알아보세요.

  5. 이제 배포를 만들어 보겠습니다.

    만들어진 엔드포인트에서 새 배포를 만들려면 다음과 같이 YAML 구성을 만듭니다. 추가 속성은 전체 일괄 처리 엔드포인트 YAML 스키마를 확인합니다.

    deployment.yml

    $schema: https://azuremlschemas.azureedge.net/latest/modelBatchDeployment.schema.json
    endpoint_name: text-summarization-batch
    name: text-summarization-optimum
    description: A text summarization deployment implemented with HuggingFace and BART architecture with GPU optimization using Optimum.
    type: model
    model: azureml:bart-text-summarization@latest
    compute: azureml:gpu-cluster
    environment:
      name: torch200-transformers-gpu
      image: mcr.microsoft.com/azureml/openmpi4.1.0-cuda11.8-cudnn8-ubuntu22.04:latest
      conda_file: environment/torch200-conda.yaml
    code_configuration:
      code: code
      scoring_script: batch_driver.py
    resources:
      instance_count: 2
    settings:
      max_concurrency_per_instance: 1
      mini_batch_size: 1
      output_action: append_row
      output_file_name: predictions.csv
      retry_settings:
        max_retries: 1
        timeout: 3000
      error_threshold: -1
      logging_level: info
    

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

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

    Important

    이 배포에서 매개 변수 retry_settingstimeout에 높은 값이 있음을 알 수 있습니다. 그 이유는 실행하고 있는 모델의 특성 때문입니다. 이는 매우 비용이 많이 드는 모델이며 단일 행에 대한 유추는 최대 60초가 걸릴 수 있습니다. timeout 매개 변수는 채점 스크립트가 각 미니 Batch 처리를 완료할 때까지 일괄 처리 배포가 기다려야 하는 시간을 제어합니다. 모델이 행별로 예측을 실행하므로 긴 파일을 처리하는 데 시간이 걸릴 수 있습니다. 또한 일괄 처리당 파일 수가 1(mini_batch_size=1)로 설정되어 있습니다. 이는 진행 중인 작업의 본질과 관련이 있습니다. 일괄 처리당 한 번에 하나의 파일을 처리하는 것은 정당화할 만큼 비용이 많이 듭니다. 이는 NLP 처리의 패턴임을 알 수 있습니다.

  6. 엔드포인트 내에서 특정 배포를 호출할 수 있지만 일반적으로 엔드포인트 자체를 호출하고 엔드포인트에서 사용할 배포를 결정하도록 합니다. 이러한 배포를 "기본" 배포라고 합니다. 이렇게 하면 기본 배포를 변경할 수 있으므로 엔드포인트를 호출하는 사용자와의 계약을 변경하지 않고도 배포를 제공하는 모델을 변경할 수 있습니다. 다음 지침을 사용하여 기본 배포를 업데이트합니다.

    DEPLOYMENT_NAME="text-summarization-hfbart"
    az ml batch-endpoint update --name $ENDPOINT_NAME --set defaults.deployment_name=$DEPLOYMENT_NAME
    
  7. 이제 일괄 처리 엔드포인트를 사용할 준비가 되었습니다.

배포 테스트

엔드포인트를 테스트하기 위해 데이터 세트 BillSum: 미국 법률의 자동 요약을 위한 모음의 샘플을 사용할 예정입니다. 이 샘플은 data 폴더의 리포지토리에 포함되어 있습니다. 데이터 형식은 CSV이고 요약할 콘텐츠는 모델에서 예상한 대로 text 열 아래에 있습니다.

  1. 엔드포인트를 호출해 보겠습니다.

    JOB_NAME=$(az ml batch-endpoint invoke --name $ENDPOINT_NAME --input data --input-type uri_folder --query name -o tsv)
    

    참고 항목

    설치 버전에 따라 jq 유틸리티가 설치되지 않을 수도 있습니다. 이 링크에서 지침을 가져올 수 있습니다.

    로컬 경로를 입력으로 지정하면 데이터가 Azure Machine Learning 기본 스토리지 계정에 업로드됩니다.

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

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

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

    az ml job download --name $JOB_NAME --output-name score --download-path .
    

텍스트를 처리하는 모델 배포 시 고려 사항

이 자습서의 일부 참고 사항에서 언급했듯이 텍스트 처리에는 일괄 처리 배포를 위한 특정 구성이 필요한 몇 가지 특성이 있을 수 있습니다. 일괄 처리 배포를 설계할 때 다음 사항을 고려합니다.

  • 일부 NLP 모델은 메모리 및 컴퓨팅 시간 측면에서 매우 비용이 많이 들 수 있습니다. 이 경우 각 미니 일괄 처리에 포함된 파일 수를 줄이는 것이 좋습니다. 위의 예에서 숫자는 일괄 처리당 1개의 파일로 최솟값으로 사용되었습니다. 그렇지 않을 수도 있지만 모델이 매번 채점할 수 있는 파일 수를 고려합니다. 딥 러닝 모델의 경우 입력 크기와 모델의 메모리 공간 사이의 관계가 선형적이지 않을 수 있음을 염두에 두세요.
  • 모델이 한 번에 하나의 파일도 처리할 수 없는 경우(예: 이 예) 행/청크에서 입력 데이터를 읽는 것이 좋습니다. 더 높은 처리량 또는 하드웨어 사용률을 달성해야 하는 경우 행 수준에서 일괄 처리를 구현합니다.
  • 모델의 비용과 처리할 데이터의 양에 따라 배포의 timeout 값을 적절하게 설정합니다. timeout은 지정된 일괄 처리에 대해 채점 스크립트가 실행될 때까지 일괄 처리 배포가 대기하는 시간을 나타냅니다. 일괄 처리에 파일이 많거나 행이 많은 파일이 있는 경우 이는 이 매개 변수의 올바른 값에 영향을 미칩니다.

텍스트를 처리하는 MLflow 모델에 대한 고려 사항

위에서 언급한 것과 동일한 고려 사항이 MLflow 모델에 적용됩니다. 그러나 MLflow 모델 배포에 대한 채점 스크립트를 제공할 필요가 없으므로 언급된 권장 사항 중 일부에는 다른 방식이 필요할 수 있습니다.

  • 일괄 처리 엔드포인트의 MLflow 모델은 긴 텍스트 시퀀스를 포함할 수 있는 입력 데이터로 표 형식 데이터 읽기를 지원합니다. 지원되는 파일 형식에 대한 자세한 내용은 파일 형식 지원을 참조하세요.
  • 일괄 처리 배포는 전체 파일의 콘텐츠를 Pandas 데이터 프레임으로 사용하여 MLflow 모델의 예측 함수를 호출합니다. 입력 데이터에 많은 행이 포함된 경우 복잡한 모델(이 자습서에 제시된 것과 같은)을 실행하면 메모리 부족 예외가 발생할 가능성이 있습니다. 이 경우 다음을 고려할 수 있습니다.
    • 모델이 예측을 실행하고 일괄 처리를 구현하는 방법을 사용자 지정합니다. MLflow 모델의 유추를 사용자 지정하는 방법을 알아보려면 사용자 지정 모델 로깅을 참조하세요.
    • 채점 스크립트를 작성하고 mlflow.<flavor>.load_model()을 사용하여 모델을 로드합니다. 자세한 내용은 채점 스크립트와 함께 MLflow 모델 사용을 참조하세요.