Обучение моделей PyTorch в большом масштабе с помощью Машинного обучения Azure

ОБЛАСТЬ ПРИМЕНЕНИЯ: Пакет SDK для Python azure-ai-ml версии 2 (current)

В этой статье вы узнаете, как обучить, настроить гиперпараметр и развернуть модель PyTorch с помощью пакета SDK для Python версии 1 Машинное обучение Azure.

Вы будете использовать примеры скриптов для классификации изображений курицы и индейки для создания нейронной сети глубокого обучения (DNN) на основе руководства по передаче обучения PyTorch. Передача обучения — это метод, при котором знания, полученные в результате решения одной задачи, переносятся на другую задачу, связанную с первой. Передача обучения упрощает процесс обучения, так как требуется меньше данных, времени и вычислительных ресурсов, чем при обучении с нуля. Дополнительные сведения о передаче обучения см. в статье "Глубокое обучение" и "Машинное обучение".

Обучаете ли вы модель PyTorch для глубокого обучения с нуля или переносите существующую модель в облако, вы можете использовать Машинное обучение Azure для горизонтального масштабирования заданий обучения с открытым кодом с помощью эластичных облачных вычислительных ресурсов. Вы можете создавать, развертывать, версионировать и отслеживать модели производственного уровня с помощью Машинного обучения Azure.

Необходимые компоненты

  • Подписка Azure. Если у вас еще нет учетной записи, создайте бесплатную учетную запись.
  • Запустите код в этой статье с помощью Машинное обучение Azure вычислительного экземпляра или собственной записной книжки Jupyter.

Вы также можете найти завершенную версию записной книжки Jupyter в этом руководстве на странице примеров GitHub.

Перед запуском кода в этой статье для создания кластера GPU необходимо запросить увеличение квоты для рабочей области.

Настройка задания

Этот раздел настраивает задание для обучения, загружая необходимые пакеты Python, подключаясь к рабочей области, создавая вычислительный ресурс для выполнения задания команды и создавая среду для запуска задания.

Подключение к рабочей области

Сначала необходимо подключиться к рабочей области Машинное обучение Azure. Рабочая область — это ресурс верхнего уровня для службы. Он предоставляет централизованное место для работы со всеми артефактами, создаваемыми при использовании Машинное обучение Azure.

Мы используем DefaultAzureCredential для получения доступа к рабочей области. Эти учетные данные должны быть способны обрабатывать большинство сценариев проверки подлинности пакета SDK Для Azure.

Если 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()

Затем получите дескриптор рабочей области, указав идентификатор подписки, имя группы ресурсов и имя рабочей области. Чтобы найти следующие параметры, выполните следующие действия.

  1. Найдите имя рабочей области в правом верхнем углу панели инструментов Студия машинного обучения Azure.
  2. Выберите имя рабочей области, чтобы отобразить группу ресурсов и идентификатор подписки.
  3. Скопируйте значения для группы ресурсов и идентификатора подписки в код.
# 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 требуется вычислительный ресурс для запуска задания. Этот ресурс может быть одним или несколькими узлами с ОС Linux или Windows или определенной вычислительной структурой, такой как Spark.

В следующем примере скрипта мы подготавливаем вычислительный кластер Linux. Вы можете просмотреть страницу цен на Машинное обучение Azure для полного списка размеров и цен на виртуальные машины. Так как нам нужен кластер GPU для этого примера, давайте выберите STANDARD_NC6 модель и создадим Машинное обучение Azure вычислений.

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, требуется среда. Среда Машинное обучение Azure инкапсулирует зависимости (такие как среда выполнения программного обеспечения и библиотеки), необходимые для запуска скрипта обучения машинного обучения на вычислительном ресурсе. Эта среда похожа на среду Python на локальном компьютере.

Машинное обучение Azure позволяет использовать курированную (или готовую) среду или создать настраиваемую среду с помощью образа Docker или конфигурации Conda. В этой статье вы повторно используете курированную среду Машинное обучение AzureAzureML-pytorch-1.9-ubuntu18.04-py37-cuda11-gpu. Используйте последнюю версию этой среды с помощью директивы @latest .

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

Настройка и отправка задания обучения

В этом разделе мы начнем с представления данных для обучения. Затем мы рассмотрим, как запустить задание обучения с помощью предоставленного скрипта обучения. Вы узнаете, как создать задание обучения, настроив команду для запуска скрипта обучения. Затем вы отправите задание обучения для запуска в Машинное обучение Azure.

Получение обучающих данных

Набор данных можно использовать в этом архивном файле. Этот набор данных состоит из около 120 обучающих образов для двух классов (индейки и кур), с 100 образами проверки для каждого класса. Изображения являются подмножеством набора данных Open Images V5. Скрипт обучения pytorch_train.py скачивает и извлекает набор данных.

Подготовка скрипта обучения

В разделе предварительных требований мы предоставили скрипт обучения pytorch_train.py. На практике вы должны иметь возможность принимать любой настраиваемый скрипт обучения как есть и запускать его с Машинное обучение Azure без необходимости изменять код.

Предоставленный скрипт обучения загружает данные, обучает модель и регистрирует модель.

Создание задания обучения

Теперь, когда у вас есть все ресурсы, необходимые для выполнения задания, пришло время создать его с помощью пакета SDK для Python версии 2 Машинное обучение Azure. В этом примере мы создадим command.

Машинное обучение Azure 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",
)
  • Входные данные для этой команды включают количество эпох, скорость обучения, импульс и выходной каталог.
  • Для значений параметров:
    1. Укажите вычислительный кластер gpu_compute_target = "gpu-cluster" , созданный для выполнения этой команды.
    2. Укажите курированную среду AzureML-pytorch-1.9-ubuntu18.04-py37-cuda11-gpu , которую вы инициализировали ранее.
    3. Если вы не используете завершенную записную книжку в папке "Примеры", укажите расположение файла pytorch_train.py .
    4. Настройте само действие командной строки. В этом случае команда выполняется python pytorch_train.py. Доступ к входным и выходным данным в команде можно получить с помощью ${{ ... }} нотации.
    5. Настройте метаданные, такие как отображаемое имя и имя эксперимента, где эксперимент является контейнером для всех итераций, которые выполняется в определенном проекте. Все задания, отправленные под тем же именем эксперимента, будут перечислены рядом друг с другом в Студия машинного обучения Azure.

отправить задание.

Теперь пришло время отправить задание для выполнения в Машинное обучение Azure. На этот раз вы используете create_or_updateml_client.jobs.

ml_client.jobs.create_or_update(job)

После завершения задание регистрирует модель в рабочей области (в результате обучения) и выводит ссылку для просмотра задания в Студия машинного обучения Azure.

Предупреждение

Машинное обучение Azure запускает сценарии обучения, копируя весь исходный каталог. Если у вас есть конфиденциальные данные, которые вы не хотите отправлять, используйте файл .ignore или не включайте их в исходный каталог.

Что происходит во время выполнения задания

По мере выполнения задания он проходит через следующие этапы:

  • Подготовка. Создается образ Docker в соответствии с определенной средой. Образ отправляется в реестр контейнеров рабочей области и кэшируется для последующего выполнения. Журналы также передаются в журнал заданий и можно просматривать для мониторинга хода выполнения. Если указана курированная среда, используется кэшированный образ, который поддерживается курированной средой.

  • Масштабирование: кластер пытается увеличить масштаб, если для выполнения выполнения запуска требуется больше узлов, чем сейчас доступно.

  • Выполняется: все скрипты в папке скрипта передаются в целевой объект вычислений, хранилища данных подключены или копируются, а скрипт выполняется. Выходные данные из stdout и папки ./logs передаются в журнал заданий и могут использоваться для мониторинга задания.

Настройка гиперпараметров модели

Вы обучили модель с одним набором параметров, давайте посмотрим, можно ли улучшить точность модели. Вы можете настраивать и оптимизировать гиперпараметры модели с помощью возможностей Машинное обучение Azuresweep.

Чтобы настроить гиперпараметры модели, определите пространство параметров, в котором выполняется поиск во время обучения. Это можно сделать, заменив некоторые параметры, переданные в задание обучения специальными входными данными из azure.ml.sweep пакета.

Так как сценарий обучения использует расписание обучения для распада скорости обучения каждые несколько эпох, можно настроить начальную скорость обучения и параметры импульса.

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 нашей первичной оценки метрики. Вы применяете эту политику каждую эпоху (так как мы сообщаем о нашей best_val_acc метрии каждую эпоху и evaluation_interval=1). Обратите внимание, что мы отложим первую оценку политики до первых 10 эпох (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 автоматически создает этот скрипт.

Дополнительные сведения о развертывании см. в статье "Развертывание и оценка модели машинного обучения с управляемой веб-конечной точкой с помощью пакета SDK для Python версии 2".

Создание подключенной конечной точки

В качестве первого шага по развертыванию модели необходимо создать конечную точку в Сети. Имя конечной точки должно быть уникальным в целом регионе 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)

Примечание.

Ожидайте, что эта очистка займет немного времени.

Следующие шаги

В этой статье вы обучили и зарегистрировали нейронную сеть глубокого обучения с помощью PyTorch на Машинное обучение Azure. Вы также развернули модель в сетевой конечной точке. Подробные сведения о Машинном обучении Azure см. в следующих статьях.