Azure Machine Learning을 사용하여 대규모 PyTorch 모델 학습

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

이 문서에서는 Azure Machine Learning Python SDK v2를 사용하여 PyTorch 모델을 학습, 하이퍼 매개 변수 조정 및 배포하는 방법을 알아봅니다.

예제 스크립트를 사용하여 PyTorch의 전이 학습 자습서에 따라 닭과 칠면조의 이미지를 분류하여 DNN(딥 러닝 신경망)을 빌드합니다. 전이 학습은 한 가지 문제를 해결하는 과정에서 획득한 지식을 다른 관련 문제에 적용하는 기술입니다. 전이 학습으로 처음부터 학습하는 것보다 적은 데이터, 시간 및 컴퓨팅 리소스가 필요하므로 학습 프로세스가 단축됩니다. 전이 학습에 대해 자세히 알아보려면 딥 러닝과 기계 학습 비교를 참조하세요.

처음부터 딥 러닝 PyTorch 모델을 학습시키는지, 아니면 기존 모델을 클라우드로 가져오는지에 관계없이 Azure Machine Learning에서 탄력적 클라우드 컴퓨팅 리소스를 사용하여 오픈 소스 학습 작업을 스케일 아웃할 수 있습니다. Azure Machine Learning을 사용하여 프로덕션 등급 모델을 빌드, 배포, 버전 관리 및 모니터링할 수 있습니다.

필수 구성 요소

  • Azure 구독 아직 계정이 없으면 체험 계정을 만듭니다.
  • Azure Machine Learning 컴퓨팅 인스턴스 또는 사용자 고유의 Jupyter Notebook에서 이 문서의 코드를 실행합니다.
    • Azure Machine Learning 컴퓨팅 인스턴스(다운로드 또는 설치가 필요 없음):
      • 빠른 시작: Azure Machine Learning 시작을 완료하여 SDK 및 샘플 리포지토리가 미리 로드된 전용 Notebook 서버를 만듭니다.
      • 작업 영역의 Notebooks 섹션에 있는 샘플 탭에서 SDK v2/sdk/python/jobs/single-step/pytorch/train-hyperparameter-tune-deploy-with-pytorch 디렉터리로 이동하여 완료된 확장 Notebook을 찾습니다.
    • Jupyter Notebook 서버:

GitHub 샘플 페이지에서 이 가이드의 완료된 Jupyter Notebook 버전을 찾을 수도 있습니다.

이 문서의 코드를 실행하여 GPU 클러스터를 만들려면 먼저 작업 영역에 대한 할당량 증가를 요청해야 합니다.

작업 설정

이 섹션에서는 필요한 Python 패키지를 로드하고, 작업 영역에 연결하고, 명령 작업을 실행할 컴퓨팅 리소스를 만들고, 작업을 실행할 환경을 만들어 학습 작업을 설정합니다.

작업 영역에 연결

먼저, Azure Machine Learning 작업 영역에 연결해야 합니다. 이 작업 영역은 서비스의 최상위 리소스입니다. 작업 영역은 Azure Machine Learning를 사용하는 경우 만드는 모든 아티팩트를 사용할 수 있는 중앙 집중식 위치를 제공합니다.

DefaultAzureCredential을 사용하여 작업 영역에 액세스합니다. 이 자격 증명은 대부분의 Azure SDK 인증 시나리오를 처리할 수 있어야 합니다.

DefaultAzureCredential이 적합하지 않은 경우 사용 가능한 추가 자격 증명은 azure.identity 패키지 또는 인증 설정을 참조하세요.

# Handle to the workspace
from azure.ai.ml import MLClient

# Authentication package
from azure.identity import DefaultAzureCredential

credential = DefaultAzureCredential()

브라우저를 사용하여 로그인하고 인증하려는 경우 다음 코드에서 주석 처리를 제거하고 대신 사용해야 합니다.

# Handle to the workspace
# from azure.ai.ml import MLClient

# Authentication package
# from azure.identity import InteractiveBrowserCredential
# credential = InteractiveBrowserCredential()

다음으로, 구독 ID, 리소스 그룹 이름, 작업 영역 이름을 제공하여 작업 영역에 대한 핸들을 가져옵니다. 이 매개 변수를 찾으려면:

  1. Azure Machine Learning 스튜디오 도구 모음의 오른쪽 위에서 작업 영역 이름을 찾습니다.
  2. 리소스 그룹 및 구독 ID를 표시할 작업 영역 이름을 선택합니다.
  3. 리소스 그룹 및 구독 ID의 값을 코드에 복사합니다.
# Get a handle to the workspace
ml_client = MLClient(
    credential=credential,
    subscription_id="<SUBSCRIPTION_ID>",
    resource_group_name="<RESOURCE_GROUP>",
    workspace_name="<AML_WORKSPACE_NAME>",
)

이 스크립트를 실행한 결과는 다른 리소스 및 작업을 관리하는 데 사용할 수 있는 작업 영역 핸들입니다.

참고 항목

MLClient를 만들어도 클라이언트가 작업 영역에 연결되지 않습니다. 클라이언트 초기화가 지연되며 처음 호출해야 할 때까지 기다립니다. 이 문서에서는 컴퓨팅을 만드는 동안 이 문제가 발생합니다.

작업을 실행할 컴퓨팅 리소스 만들기

Azure Machine Learning에서는 작업을 실행할 컴퓨팅 리소스가 필요합니다. 이 리소스는 Linux 또는 Windows OS를 사용하는 단일 또는 다중 노드 머신 또는 Spark와 같은 특정 컴퓨팅 패브릭입니다.

다음 예제 스크립트에서는 Linux 컴퓨팅 클러스터를 프로비전합니다. VM 크기 및 가격의 전체 목록은 Azure Machine Learning 가격 책정 페이지를 참조하세요. 이 예제에는 GPU 클러스터가 필요하므로 STANDARD_NC6 모델을 선택하고 Azure Machine Learning 컴퓨팅을 만들어 보겠습니다.

from azure.ai.ml.entities import AmlCompute

gpu_compute_target = "gpu-cluster"

try:
    # let's see if the compute target already exists
    gpu_cluster = ml_client.compute.get(gpu_compute_target)
    print(
        f"You already have a cluster named {gpu_compute_target}, we'll reuse it as is."
    )

except Exception:
    print("Creating a new gpu compute target...")

    # Let's create the Azure ML compute object with the intended parameters
    gpu_cluster = AmlCompute(
        # Name assigned to the compute cluster
        name="gpu-cluster",
        # Azure ML Compute is the on-demand VM service
        type="amlcompute",
        # VM Family
        size="STANDARD_NC6s_v3",
        # Minimum running nodes when there is no job running
        min_instances=0,
        # Nodes in cluster
        max_instances=4,
        # How many seconds will the node running after the job termination
        idle_time_before_scale_down=180,
        # Dedicated or LowPriority. The latter is cheaper but there is a chance of job termination
        tier="Dedicated",
    )

    # Now, we pass the object to MLClient's create_or_update method
    gpu_cluster = ml_client.begin_create_or_update(gpu_cluster).result()

print(
    f"AMLCompute with name {gpu_cluster.name} is created, the compute size is {gpu_cluster.size}"
)

작업 환경 만들기

Azure Machine Learning 작업을 실행하려면 환경이 필요합니다. Azure Machine Learning 환경은 컴퓨팅 리소스에서 기계 학습의 학습 스크립트를 실행하는 데 필요한 종속성(예: 소프트웨어 런타임 및 라이브러리)을 캡슐화합니다. 이 환경은 로컬 머신의 Python 환경과 비슷합니다.

Azure Machine Learning을 사용하면 큐레이팅된(또는 즉시 사용 가능한) 환경을 사용하거나 Docker 이미지 또는 Conda 구성을 사용하여 사용자 지정 환경을 만들 수 있습니다. 이 문서에서는 큐레이팅된 Azure Machine Learning 환경인 AzureML-pytorch-1.9-ubuntu18.04-py37-cuda11-gpu를 다시 사용합니다. @latest 지시문을 사용하여 이 환경의 최신 버전을 사용합니다.

curated_env_name = "AzureML-pytorch-1.9-ubuntu18.04-py37-cuda11-gpu@latest"

학습 작업 구성 및 제출

이 섹션에서는 학습을 위한 데이터를 소개하는 것부터 시작합니다. 그런 다음, 제공된 학습 스크립트를 사용하여 학습 작업을 실행하는 방법을 설명합니다. 학습 스크립트를 실행하기 위한 명령을 구성하여 학습 작업을 빌드합니다. 그런 다음, Azure Machine Learning에서 실행할 학습 작업을 제출합니다.

학습 데이터 가져오기

압축 파일의 데이터 세트를 사용할 수 있습니다. 이 데이터 세트는 두 클래스(칠면조와 닭)에 대한 약 120개의 학습 이미지로 각각 구성되며, 각 클래스마다 100개의 유효성 검사 이미지가 있습니다. 이미지는 Open Images v5 Dataset의 하위 집합입니다. 학습 스크립트 pytorch_train.py는 데이터 세트를 다운로드하고 추출합니다.

학습 스크립트 준비

필수 구성 요소 섹션에서 학습 스크립트 pytorch_train.py를 제공했습니다. 실제로 사용자 지정 학습 스크립트를 있는 그대로 사용하여 코드를 수정하지 않고도 Azure Machine Learning에서 실행할 수 있어야 합니다.

제공된 학습 스크립트는 데이터를 다운로드하고, 모델을 학습시키고, 모델을 등록합니다.

학습 작업 빌드

이제 작업을 실행하는 데 필요한 모든 자산이 있으므로 Azure Machine Learning Python SDK v2를 사용하여 작업을 빌드할 차례입니다. 이 예제에서는 command를 만듭니다.

Azure Machine Learning command는 클라우드에서 학습 코드를 실행하는 데 필요한 모든 세부 정보를 지정하는 리소스입니다. 이 세부 정보에는 입력 및 출력, 사용할 하드웨어 유형, 설치할 소프트웨어, 코드 실행 방법이 포함됩니다. command에는 단일 명령을 실행하기 위한 정보가 포함됩니다.

명령 구성

범용 command를 사용하여 학습 스크립트를 실행하고 원하는 작업을 수행합니다. 학습 작업의 구성 세부 정보를 지정하는 command 개체를 만듭니다.

from azure.ai.ml import command
from azure.ai.ml import Input

job = command(
    inputs=dict(
        num_epochs=30, learning_rate=0.001, momentum=0.9, output_dir="./outputs"
    ),
    compute=gpu_compute_target,
    environment=curated_env_name,
    code="./src/",  # location of source code
    command="python pytorch_train.py --num_epochs ${{inputs.num_epochs}} --output_dir ${{inputs.output_dir}}",
    experiment_name="pytorch-birds",
    display_name="pytorch-birds-image",
)
  • 이 명령의 입력에는 Epoch 수, 학습 속도, 모멘텀, 출력 디렉터리가 포함됩니다.
  • 매개 변수 값의 경우:
    1. 이 명령을 실행하기 위해 만든 컴퓨팅 클러스터 gpu_compute_target = "gpu-cluster"를 제공합니다.
    2. 이전에 초기화한 큐레이팅된 환경 AzureML-pytorch-1.9-ubuntu18.04-py37-cuda11-gpu를 제공합니다.
    3. Samples 폴더에 있는 완료된 Notebook을 사용하지 않는 경우 pytorch_train.py 파일의 위치를 지정합니다.
    4. 명령줄 작업 자체를 구성합니다. 이 경우에는 명령이 python pytorch_train.py입니다. ${{ ... }} 표기법을 통해 명령의 입력 및 출력에 액세스할 수 있습니다.
    5. 표시 이름, 실험 이름 등의 메타데이터를 구성합니다. 여기서 실험은 특정 프로젝트에서 수행하는 모든 반복에 대한 컨테이너입니다. 동일한 실험 이름으로 제출된 모든 작업은 Azure Machine Learning 스튜디오에서 나란히 나열됩니다.

작업 제출

이제 Azure Machine Learning에서 실행할 작업을 제출할 차례입니다. 이번에는 ml_client.jobs에서 create_or_update를 사용합니다.

ml_client.jobs.create_or_update(job)

완료되면 작업은 학습의 결과로 모델을 작업 영역에 등록하고 Azure Machine Learning 스튜디오에서 작업을 보기 위한 링크를 출력합니다.

Warning

Azure Machine Learning는 전체 원본 디렉터리를 복사하여 학습 스크립트를 실행합니다. 업로드를 원하지 않는 중요한 데이터가 있다면 .ignore 파일을 사용하거나 데이터를 원본 디렉터리에 포함하지 마세요.

작업을 실행하는 동안 수행되는 작업

작업이 실행되면 다음 단계를 거칩니다.

  • 준비: 정의된 환경에 따라 Docker 이미지가 생성됩니다. 이미지는 작업 영역의 컨테이너 레지스트리에 업로드되고 나중에 실행될 수 있도록 캐시됩니다. 또한 로그는 작업 기록으로 스트리밍되며 진행 상황을 모니터링할 수 있도록 표시됩니다. 큐레이팅된 환경이 지정되면 해당 큐레이팅된 환경을 지원하는 캐시된 이미지가 사용됩니다.

  • 스케일링: 실행하는 데 현재 사용 가능한 것보다 더 많은 노드가 필요한 경우 클러스터가 스케일 업을 시도합니다.

  • 실행: 스크립트 폴더 src의 모든 스크립트가 컴퓨팅 대상으로 업로드되고, 데이터 저장소가 탑재되거나 복사되며, 스크립트가 실행됩니다. stdout./logs 폴더의 출력은 작업 기록으로 스트리밍되며 작업을 모니터링하는 데 사용될 수 있습니다.

모델 하이퍼 매개 변수 튜닝

하나의 매개 변수 집합으로 모델을 학습시켰습니다. 이제 모델의 정확도를 더 향상시킬 수 있는지 알아보겠습니다. Azure Machine Learning의 sweep 기능을 사용하여 모델의 하이퍼 매개 변수를 튜닝하고 최적화할 수 있습니다.

모델의 하이퍼 매개 변수를 튜닝하려면 학습 중에 검색할 매개 변수 공간을 정의합니다. 이 작업을 수행하려면 학습 작업에 전달된 일부 매개 변수를 azure.ml.sweep 패키지의 특수 입력으로 바꿉니다.

학습 스크립트는 학습 속도 일정을 사용하여 여러 Epoch마다 학습 속도를 감소시키므로 초기 학습 속도 및 모멘텀 매개 변수를 조정할 수 있습니다.

from azure.ai.ml.sweep import Uniform

# we will reuse the command_job created before. we call it as a function so that we can apply inputs
job_for_sweep = job(
    learning_rate=Uniform(min_value=0.0005, max_value=0.005),
    momentum=Uniform(min_value=0.9, max_value=0.99),
)

그런 다음, 감시할 기본 메트릭, 사용할 샘플링 알고리즘 등의 일부 스윕 관련 매개 변수를 사용하여 명령 작업에 대한 스윕을 구성할 수 있습니다.

다음 코드에서는 임의 샘플링을 사용하여 기본 메트릭 best_val_acc를 최대화하기 위해 하이퍼 매개 변수의 다양한 구성 세트를 시도합니다.

또한 성능이 저하된 실행을 조기에 종료하기 위해 조기 종료 정책인 BanditPolicy를 정의합니다. BanditPolicy는 기본 평가 메트릭의 slack 요소에 속하지 않는 모든 실행을 종료합니다. 각 Epoch에 이 정책을 적용합니다(각 Epoch 및 evaluation_interval=1마다 best_val_acc 메트릭을 보고하기 때문). 첫 번째 정책 평가는 처음 10개 Epoch(delay_evaluation=10) 이후까지 지연됩니다.

from azure.ai.ml.sweep import BanditPolicy

sweep_job = job_for_sweep.sweep(
    compute="gpu-cluster",
    sampling_algorithm="random",
    primary_metric="best_val_acc",
    goal="Maximize",
    max_total_trials=8,
    max_concurrent_trials=4,
    early_termination_policy=BanditPolicy(
        slack_factor=0.15, evaluation_interval=1, delay_evaluation=10
    ),
)

이제 이전과 같이 이 작업을 제출할 수 있습니다. 이번에는 학습 작업을 스윕하는 스윕 작업을 실행합니다.

returned_sweep_job = ml_client.create_or_update(sweep_job)

# stream the output and wait until the job is finished
ml_client.jobs.stream(returned_sweep_job.name)

# refresh the latest status of the job after streaming
returned_sweep_job = ml_client.jobs.get(name=returned_sweep_job.name)

작업 실행 중에 표시되는 스튜디오 사용자 인터페이스 링크를 사용하여 작업을 모니터링할 수 있습니다.

최적 모델 찾기

모든 실행이 완료되면 정확도가 가장 높은 모델을 생성한 실행을 찾을 수 있습니다.

from azure.ai.ml.entities import Model

if returned_sweep_job.status == "Completed":

    # First let us get the run which gave us the best result
    best_run = returned_sweep_job.properties["best_child_run_id"]

    # lets get the model from this run
    model = Model(
        # the script stores the model as "outputs"
        path="azureml://jobs/{}/outputs/artifacts/paths/outputs/".format(best_run),
        name="run-model-example",
        description="Model created from run.",
        type="custom_model",
    )

else:
    print(
        "Sweep job status: {}. Please wait until it completes".format(
            returned_sweep_job.status
        )
    )

모델을 온라인 엔드포인트로 배포

이제 모델을 온라인 엔드포인트, 즉 Azure 클라우드의 웹 서비스로 배포할 수 있습니다.

기계 학습 서비스를 배포하려면 일반적으로 다음이 필요합니다.

  • 배포할 모델 자산. 이러한 자산에는 학습 작업에 이미 등록한 모델의 파일 및 메타데이터가 포함됩니다.
  • 서비스로 실행할 일부 코드입니다. 이 코드는 지정된 입력 요청(항목 스크립트)에서 모델을 실행합니다. 항목 스크립트는 배포된 웹 서비스에 전송된 데이터를 받아서 모델에 전달합니다. 모델이 데이터를 처리한 후 스크립트는 모델의 응답을 클라이언트에 반환합니다. 이 스크립트는 모델마다 다르므로, 모델이 예상하고 반환하는 데이터를 이해해야 합니다. MLFlow 모델을 사용하면 Azure Machine Learning에서 자동으로 이 스크립트를 만듭니다.

배포에 대한 자세한 내용은 Python SDK v2를 사용하여 관리형 온라인 엔드포인트를 통해 기계 학습 모델 배포 및 점수 매기기를 참조하세요.

새 온라인 엔드포인트 만들기

모델을 배포하는 첫 번째 단계로 온라인 엔드포인트를 만들어야 합니다. 엔드포인트 이름은 전체 Azure 지역에서 고유해야 합니다. 이 문서에서는 UUID(범용 고유 식별자)를 사용하여 고유한 이름을 만듭니다.

import uuid

# Creating a unique name for the endpoint
online_endpoint_name = "aci-birds-endpoint-" + str(uuid.uuid4())[:8]
from azure.ai.ml.entities import ManagedOnlineEndpoint

# create an online endpoint
endpoint = ManagedOnlineEndpoint(
    name=online_endpoint_name,
    description="Classify turkey/chickens using transfer learning with PyTorch",
    auth_mode="key",
    tags={"data": "birds", "method": "transfer learning", "framework": "pytorch"},
)

endpoint = ml_client.begin_create_or_update(endpoint).result()

print(f"Endpoint {endpoint.name} provisioning state: {endpoint.provisioning_state}")

엔드포인트를 만든 후 다음과 같이 검색할 수 있습니다.

endpoint = ml_client.online_endpoints.get(name=online_endpoint_name)

print(
    f'Endpint "{endpoint.name}" with provisioning state "{endpoint.provisioning_state}" is retrieved'
)

엔드포인트에 모델 배포

이제 항목 스크립트를 사용하여 모델을 배포할 수 있습니다. 하나의 엔드포인트에 여러 배포가 있을 수 있습니다. 그러면 엔드포인트에서 규칙을 사용하여 트래픽을 이러한 배포로 보낼 수 있습니다.

다음 코드에서 들어오는 트래픽의 100%를 처리하는 단일 배포를 만듭니다. 배포에 대해 임의의 색 이름 aci-blue를 지정했습니다. 배포에 aci-green 또는 aci-red와 같은 다른 이름을 사용할 수도 있습니다.

엔드포인트에 모델을 배포하는 코드:

  • 이전에 등록한 모델의 가장 적합한 버전을 배포합니다.
  • score.py 파일을 사용하여 모델을 채점합니다.
  • 이전에 지정한 큐레이팅된 환경을 사용하여 추론을 수행합니다.
from azure.ai.ml.entities import (
    ManagedOnlineDeployment,
    Model,
    Environment,
    CodeConfiguration,
)

online_deployment_name = "aci-blue"

# create an online deployment.
blue_deployment = ManagedOnlineDeployment(
    name=online_deployment_name,
    endpoint_name=online_endpoint_name,
    model=model,
    environment=curated_env_name,
    code_configuration=CodeConfiguration(code="./score/", scoring_script="score.py"),
    instance_type="Standard_NC6s_v3",
    instance_count=1,
)

blue_deployment = ml_client.begin_create_or_update(blue_deployment).result()

참고 항목

이 배포를 완료하는 데 다소 시간이 걸립니다.

배포된 모델 테스트

이제 엔드포인트에 모델을 배포했으므로 엔드포인트에서 invoke 메서드를 사용하여 배포된 모델의 출력을 예측할 수 있습니다.

엔드포인트를 테스트하기 위해 예측용 샘플 이미지를 사용하겠습니다. 먼저 이미지를 표시해 보겠습니다.

# install pillow if PIL cannot imported
%pip install pillow
import json
from PIL import Image
import matplotlib.pyplot as plt

%matplotlib inline
plt.imshow(Image.open("test_img.jpg"))

이미지의 서식을 지정하고 크기를 조정하는 함수를 만듭니다.

# install torch and torchvision if needed
%pip install torch
%pip install torchvision

import torch
from torchvision import transforms


def preprocess(image_file):
    """Preprocess the input image."""
    data_transforms = transforms.Compose(
        [
            transforms.Resize(256),
            transforms.CenterCrop(224),
            transforms.ToTensor(),
            transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),
        ]
    )

    image = Image.open(image_file)
    image = data_transforms(image).float()
    image = torch.tensor(image)
    image = image.unsqueeze(0)
    return image.numpy()

이미지의 서식을 지정하고 JSON 파일로 변환합니다.

image_data = preprocess("test_img.jpg")
input_data = json.dumps({"data": image_data.tolist()})
with open("request.json", "w") as outfile:
    outfile.write(input_data)

그러면 이 JSON을 사용하여 엔드포인트를 호출하고 결과를 인쇄할 수 있습니다.

# test the blue deployment
result = ml_client.online_endpoints.invoke(
    endpoint_name=online_endpoint_name,
    request_file="request.json",
    deployment_name=online_deployment_name,
)

print(result)

리소스 정리

더 이상 엔드포인트가 필요하지 않은 경우 삭제하여 리소스 사용을 중지합니다. 엔드포인트를 삭제하기 전에 다른 배포에서 엔드포인트를 사용하고 있지 않은지 확인합니다.

ml_client.online_endpoints.begin_delete(name=online_endpoint_name)

참고 항목

이 정리를 완료하는 데 약간의 시간이 걸릴 것입니다.

다음 단계

이 문서에서는 Azure Machine Learning에서 PyTorch를 사용하여 딥 러닝 신경망을 학습시키고 등록했습니다. 또한 모델을 온라인 엔드포인트에 배포했습니다. Azure Machine Learning에 대한 자세한 내용은 다음 문서를 참조하세요.