Prepare os modelos do PyTorch em escala com o Azure Machine Learning

APLICA-SE A: Python SDK azure-ai-ml v2 (atual)

Neste artigo, você aprenderá a treinar, ajustar hiperparâmetros e implantar um modelo PyTorch usando o SDK do Python do Azure Machine Learning v2.

Você usará scripts de exemplo para classificar imagens de frango e peru para construir uma rede neural de aprendizado profundo (DNN) com base no tutorial de aprendizagem de transferência do PyTorch. A aprendizagem por transferência é uma técnica que aplica o conhecimento adquirido na resolução de um problema a um problema diferente, mas relacionado. A aprendizagem de transferência encurta o processo de treinamento, exigindo menos dados, tempo e recursos de computação do que o treinamento do zero. Para saber mais sobre a aprendizagem por transferência, consulte Aprendizagem profunda vs. aprendizagem automática.

Quer esteja a treinar um modelo PyTorch de aprendizagem profunda desde o início ou a trazer um modelo existente para a nuvem, pode utilizar o Azure Machine Learning para expandir trabalhos de formação de código aberto utilizando recursos de computação em nuvem elástica. Você pode criar, implantar, versionar e monitorar modelos de nível de produção com o Azure Machine Learning.

Pré-requisitos

  • Uma subscrição do Azure. Se ainda não tiver uma, crie uma conta gratuita.
  • Execute o código neste artigo usando uma instância de computação do Azure Machine Learning ou seu próprio bloco de anotações Jupyter.
    • Instância de computação do Azure Machine Learning — sem necessidade de downloads ou instalação:
      • Conclua o Guia de início rápido: introdução ao Aprendizado de Máquina do Azure para criar um servidor de bloco de anotações dedicado pré-carregado com o SDK e o repositório de exemplo.
      • Na guia Exemplos na seção Blocos de Anotações do seu espaço de trabalho, localize um bloco de anotações concluído e expandido navegando até este diretório: SDK v2/sdk/python/jobs/single-step/pytorch/train-hyperparameter-tune-deploy-with-pytorch
    • Seu servidor de notebook Jupyter:

Você também pode encontrar uma versão completa do bloco de anotações Jupyter deste guia na página de exemplos do GitHub.

Antes de executar o código neste artigo para criar um cluster de GPU, você precisará solicitar um aumento de cota para seu espaço de trabalho.

Configurar o trabalho

Esta seção configura o trabalho para treinamento carregando os pacotes Python necessários, conectando-se a um espaço de trabalho, criando um recurso de computação para executar um trabalho de comando e criando um ambiente para executar o trabalho.

Conectar-se ao espaço de trabalho

Primeiro, você precisa se conectar ao seu espaço de trabalho do Azure Machine Learning. O espaço de trabalho é o recurso de nível superior para o serviço. Ele fornece um local centralizado para trabalhar com todos os artefatos criados quando você usa o Aprendizado de Máquina do Azure.

Estamos usando DefaultAzureCredential para ter acesso ao espaço de trabalho. Essa credencial deve ser capaz de lidar com a maioria dos cenários de autenticação do SDK do Azure.

Se DefaultAzureCredential não funcionar para você, consulte azure.identity package ou Configurar autenticação para obter mais credenciais disponíveis.

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

# Authentication package
from azure.identity import DefaultAzureCredential

credential = DefaultAzureCredential()

Se preferir usar um navegador para entrar e autenticar, você deve descomentar o código a seguir e usá-lo em vez disso.

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

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

Em seguida, obtenha um identificador para o espaço de trabalho fornecendo sua ID de assinatura, nome do grupo de recursos e nome do espaço de trabalho. Para encontrar estes parâmetros:

  1. Procure o nome do seu espaço de trabalho no canto superior direito da barra de ferramentas do estúdio do Azure Machine Learning.
  2. Selecione o nome do espaço de trabalho para mostrar o grupo de recursos e a ID da assinatura.
  3. Copie os valores do seu grupo de recursos e ID de assinatura para o código.
# 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>",
)

O resultado da execução desse script é um identificador de espaço de trabalho que você pode usar para gerenciar outros recursos e trabalhos.

Nota

A criação MLClient não conecta o cliente ao espaço de trabalho. A inicialização do cliente é preguiçosa e aguarda pela primeira vez que precisa fazer uma chamada. Neste artigo, isso acontece durante a criação da computação.

Criar um recurso de computação para executar o trabalho

O Azure Machine Learning precisa de um recurso de computação para executar um trabalho. Esse recurso pode ser máquinas de um ou vários nós com Linux ou sistema operacional Windows, ou uma malha de computação específica, como o Spark.

No script de exemplo a seguir, provisionamos um cluster de computação Linux. Você pode ver a página de preços do Azure Machine Learning para obter a lista completa de tamanhos e preços de VM. Como precisamos de um cluster de GPU para este exemplo, vamos escolher um STANDARD_NC6 modelo e criar uma computação do 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}"
)

Criar um ambiente de trabalho

Para executar um trabalho do Azure Machine Learning, você precisa de um ambiente. Um ambiente do Azure Machine Learning encapsula as dependências (como tempo de execução de software e bibliotecas) necessárias para executar seu script de treinamento de aprendizado de máquina em seu recurso de computação. Esse ambiente é semelhante a um ambiente Python em sua máquina local.

O Azure Machine Learning permite que você use um ambiente com curadoria (ou pronto) ou crie um ambiente personalizado usando uma imagem do Docker ou uma configuração Conda. Neste artigo, você reutiliza o ambiente AzureML-pytorch-1.9-ubuntu18.04-py37-cuda11-gpudo Azure Machine Learning com curadoria. Use a versão mais recente deste ambiente usando a @latest diretiva.

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

Configurar e enviar seu trabalho de treinamento

Nesta seção, começamos apresentando os dados para treinamento. Em seguida, abordamos como executar um trabalho de treinamento, usando um script de treinamento que fornecemos. Você aprenderá a criar o trabalho de treinamento configurando o comando para executar o script de treinamento. Em seguida, você enviará o trabalho de treinamento para ser executado no Azure Machine Learning.

Obter os dados de treinamento

Você pode usar o conjunto de dados neste arquivo compactado. Este conjunto de dados é composto por cerca de 120 imagens de treino cada para duas classes (perus e galinhas), com 100 imagens de validação para cada classe. As imagens são um subconjunto do conjunto de dados Open Images v5. O script de treinamento pytorch_train.py baixa e extrai o conjunto de dados.

Preparar o guião de formação

Na seção de pré-requisitos, fornecemos o roteiro de treinamento pytorch_train.py. Na prática, você deve ser capaz de usar qualquer script de treinamento personalizado como está e executá-lo com o Azure Machine Learning sem precisar modificar seu código.

O script de treinamento fornecido baixa os dados, treina um modelo e registra o modelo.

Construa o trabalho de formação

Agora que você tem todos os ativos necessários para executar seu trabalho, é hora de criá-lo usando o SDK do Python do Azure Machine Learning v2. Para este exemplo, criamos um commandarquivo .

Um Aprendizado command de Máquina do Azure é um recurso que especifica todos os detalhes necessários para executar seu código de treinamento na nuvem. Esses detalhes incluem as entradas e saídas, tipo de hardware a ser usado, software a ser instalado e como executar seu código. O command contém informações para executar um único comando.

Configurar o comando

Você usará o propósito command geral para executar o script de treinamento e executar as tarefas desejadas. Crie um command objeto para especificar os detalhes de configuração do seu trabalho de treinamento.

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",
)
  • As entradas para este comando incluem o número de épocas, taxa de aprendizagem, momento e diretório de saída.
  • Para os valores dos parâmetros:
    1. Forneça o cluster gpu_compute_target = "gpu-cluster" de computação que você criou para executar este comando.
    2. Forneça o ambiente AzureML-pytorch-1.9-ubuntu18.04-py37-cuda11-gpu com curadoria que você inicializou anteriormente.
    3. Se você não estiver usando o bloco de anotações concluído na pasta Exemplos, especifique o local do arquivo pytorch_train.py .
    4. Configure a própria ação da linha de comando — nesse caso, o comando é python pytorch_train.py. Você pode acessar as entradas e saídas no comando através da ${{ ... }} notação.
    5. Configure metadados, como o nome para exibição e o nome do experimento, onde um experimento é um contêiner para todas as iterações que se faz em um determinado projeto. Todos os trabalhos enviados com o mesmo nome de experimento seriam listados um ao lado do outro no estúdio do Azure Machine Learning.

Submeter o trabalho

Agora é hora de enviar o trabalho para ser executado no Azure Machine Learning. Desta vez, você usa create_or_update em ml_client.jobs.

ml_client.jobs.create_or_update(job)

Depois de concluído, o trabalho registra um modelo em seu espaço de trabalho (como resultado do treinamento) e gera um link para exibir o trabalho no estúdio do Azure Machine Learning.

Aviso

O Azure Machine Learning executa scripts de treinamento copiando todo o diretório de origem. Se você tiver dados confidenciais que não deseja carregar, use um arquivo .ignore ou não o inclua no diretório de origem.

O que acontece durante a execução do trabalho

À medida que o trabalho é executado, ele passa pelas seguintes etapas:

  • Preparação: Uma imagem docker é criada de acordo com o ambiente definido. A imagem é carregada no registro de contêiner do espaço de trabalho e armazenada em cache para execuções posteriores. Os logs também são transmitidos para o histórico de trabalhos e podem ser visualizados para monitorar o progresso. Se um ambiente com curadoria for especificado, a imagem armazenada em cache que faz o backup desse ambiente curado será usada.

  • Dimensionamento: o cluster tenta aumentar a escala se precisar de mais nós para executar a execução do que os disponíveis no momento.

  • Em execução: Todos os scripts na pasta de script src são carregados no destino de computação, os armazenamentos de dados são montados ou copiados e o script é executado. As saídas do stdout e da pasta ./logs são transmitidas para o histórico do trabalho e podem ser usadas para monitorar o trabalho.

Ajustar hiperparâmetros do modelo

Você treinou o modelo com um conjunto de parâmetros, vamos agora ver se você pode melhorar ainda mais a precisão do seu modelo. Você pode ajustar e otimizar os hiperparâmetros do seu modelo usando os sweep recursos do Azure Machine Learning.

Para ajustar os hiperparâmetros do modelo, defina o espaço de parâmetros no qual pesquisar durante o treinamento. Você faz isso substituindo alguns dos parâmetros passados para o trabalho de treinamento por entradas especiais do azure.ml.sweep pacote.

Como o script de treinamento usa um cronograma de taxa de aprendizagem para decair a taxa de aprendizagem a cada várias épocas, você pode ajustar a taxa de aprendizado inicial e os parâmetros de momento.

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),
)

Em seguida, você pode configurar a varredura no trabalho de comando, usando alguns parâmetros específicos da varredura, como a métrica primária a ser observada e o algoritmo de amostragem a ser usado.

No código a seguir, usamos amostragem aleatória para tentar diferentes conjuntos de configuração de hiperparâmetros na tentativa de maximizar nossa métrica primária, best_val_acc.

Também definimos uma política de rescisão antecipada, a BanditPolicy, para encerrar execuções com baixo desempenho antecipadamente. O BanditPolicy encerra qualquer execução que não se enquadre no fator de folga de nossa métrica de avaliação primária. Você aplica esta política a cada época (uma vez que relatamos nossa best_val_acc métrica a cada época e evaluation_interval=1). Observe que adiamos a primeira avaliação da política para depois das primeiras 10 épocas (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
    ),
)

Agora, você pode enviar este trabalho como antes. Desta vez, você está executando um trabalho de varredura que varre seu trabalho de trem.

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)

Você pode monitorar o trabalho usando o link da interface do usuário do estúdio que é apresentado durante a execução do trabalho.

Encontre o melhor modelo

Uma vez concluídas todas as execuções, você pode encontrar a execução que produziu o modelo com a mais alta precisão.

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

Implantar o modelo como um ponto de extremidade online

Agora você pode implantar seu modelo como um ponto de extremidade online, ou seja, como um serviço Web na nuvem do Azure.

Para implantar um serviço de aprendizado de máquina, você normalmente precisa:

  • Os ativos de modelo que você deseja implantar. Esses ativos incluem o arquivo do modelo e metadados que você já registrou em seu trabalho de treinamento.
  • Algum código para ser executado como um serviço. O código executa o modelo em uma determinada solicitação de entrada (um script de entrada). Esse script de entrada recebe dados enviados a um serviço Web implantado e os passa para o modelo. Depois que o modelo processa os dados, o script retorna a resposta do modelo ao cliente. O script é específico para seu modelo e deve entender os dados que o modelo espera e retorna. Quando você usa um modelo MLFlow, o Aprendizado de Máquina do Azure cria automaticamente esse script para você.

Para obter mais informações sobre implantação, consulte Implantar e pontuar um modelo de aprendizado de máquina com ponto de extremidade online gerenciado usando o Python SDK v2.

Criar um novo ponto de extremidade online

Como primeira etapa para implantar seu modelo, você precisa criar seu endpoint online. O nome do ponto de extremidade deve ser exclusivo em toda a região do Azure. Para este artigo, você cria um nome exclusivo usando um identificador universalmente exclusivo (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}")

Depois de criar o ponto de extremidade, você pode recuperá-lo da seguinte maneira:

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

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

Implantar o modelo no ponto de extremidade

Agora você pode implantar o modelo com o script de entrada. Um ponto de extremidade pode ter várias implantações. Usando regras, o ponto de extremidade pode direcionar o tráfego para essas implantações.

No código a seguir, você criará uma única implantação que lida com 100% do tráfego de entrada. Especificamos um nome de cor arbitrário aci-blue para a implantação. Você também pode usar qualquer outro nome, como aci-green ou aci-red para a implantação.

O código para implantar o modelo no ponto de extremidade:

  • Implanta a melhor versão do modelo que você registrou anteriormente.
  • Pontua o modelo, usando o arquivo score.py .
  • Usa o ambiente curado (que você especificou anteriormente) para executar a inferência.
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()

Nota

Espere que essa implantação leve um pouco de tempo para ser concluída.

Testar o modelo implementado

Agora que você implantou o modelo no ponto de extremidade, você pode prever a saída do modelo implantado, usando o invoke método no ponto de extremidade.

Para testar o ponto de extremidade, vamos usar uma imagem de exemplo para previsão. Primeiro, vamos exibir a imagem.

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

Crie uma função para formatar e redimensionar a imagem.

# 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()

Formate a imagem e converta-a em um arquivo 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)

Em seguida, você pode invocar o ponto de extremidade com esse JSON e imprimir o resultado.

# 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)

Clean up resources (Limpar recursos)

Se você não precisar mais do ponto de extremidade, exclua-o para parar de usar o recurso. Certifique-se de que nenhuma outra implantação esteja usando o ponto de extremidade antes de excluí-lo.

ml_client.online_endpoints.begin_delete(name=online_endpoint_name)

Nota

Espere que essa limpeza leve um pouco de tempo para terminar.

Próximos passos

Neste artigo, você treinou e registrou uma rede neural de aprendizado profundo usando o PyTorch no Azure Machine Learning. Você também implantou o modelo em um ponto de extremidade online. Consulte estes outros artigos para saber mais sobre o Azure Machine Learning.