Esegui il training di modelli di PyTorch su larga scala con Azure Machine Learning

SI APPLICA A: Python SDK azure-ai-ml v2 (corrente)

Questo articolo illustra come eseguire il training, ottimizzare gli iperparametri e distribuire un modello PyTorch usando Azure Machine Learning Python SDK v2.

Si useranno gli script di esempio per classificare le immagini di polli e tacchini per creare una rete neurale di Deep Learning (DNN) basata sull'esercitazione relativa all’ apprendimento induttivo di PyTorch. L'apprendimento induttivo è una tecnica che applica le conoscenze acquisite dalla risoluzione di un problema a un problema diverso ma correlato. L'apprendimento induttivo riduce il processo di training richiedendo meno dati, tempo e risorse di calcolo rispetto al training da zero. Per altre informazioni sull'apprendimento induttivo vedere l'articolo Deep Learning e apprendimento automatico.

Indipendentemente dal fatto che stia eseguendo il training di un modello PyTorch di Deep Learning da zero o che si stia portando un modello esistente nel cloud, è possibile usare Azure Machine Learning per aumentare il numero di processi di training open source usando risorse di calcolo cloud elastiche. Con Azure Machine Learning è possibile compilare, distribuire, controllare la versione e monitorare i modelli negli ambienti di produzione.

Prerequisiti

  • Una sottoscrizione di Azure. Se non si dispone di un account, è possibile creare un account gratuito.
  • Eseguire il codice in questo articolo usando un'istanza di ambiente di calcolo di Azure Machine Learning o un notebook Jupyter.
    • Istanza di ambiente di calcolo di Azure Machine Learning: nessun download o installazione necessaria:
      • Completare l’ Avvio rapido: Introduzione ad Azure Machine Learning per creare un server notebook dedicato precaricato con l'SDK e il repository di esempio.
      • Nella scheda Esempi nella sezione Notebook dell’area di lavoro trovare un notebook completato ed espanso passando alla seguente directory: SDK v2/sdk/python/jobs/single-step/pytorch/train-hyperparameter-tune-deploy-with-pytorch
    • Server del notebook Jupyter:

È anche possibile trovare una versione completata del notebook Jupyter in questa guida nella pagina degli esempi di GitHub.

Prima di poter eseguire il codice riportato in questo articolo per creare un cluster GPU, è necessario richiedere un aumento della quota per l'area di lavoro.

Configurare il processo

Questa sezione consente di configurare il processo di training caricando i pacchetti Python necessari, connettendosi a un'area di lavoro, creando una risorsa di calcolo per eseguire un processo di comando e creando un ambiente per eseguire il processo.

Connettersi all'area di lavoro

Prima di tutto, è necessario connettersi all' area di lavoro di Azure Machine Learning. L'area di lavoro è la risorsa di primo livello per il servizio. Offre una posizione centralizzata per lavorare con tutti gli artefatti creati durante l'uso di Azure Machine Learning.

Si userà DefaultAzureCredential per ottenere l'accesso all'area di lavoro. Questa credenziale deve essere in grado di gestire la maggior parte degli scenari di autenticazione di Azure SDK.

Se DefaultAzureCredential non funziona, vedere il pacchetto azure.identity o Configurare l'autenticazione per altre credenziali disponibili.

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

# Authentication package
from azure.identity import DefaultAzureCredential

credential = DefaultAzureCredential()

Se si preferisce usare un browser per accedere ed eseguire l'autenticazione, usare il codice seguente dopo aver rimosso i commenti.

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

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

Ottenere quindi un handle per l'area di lavoro specificando l'ID sottoscrizione, il nome del gruppo di risorse e il nome dell'area di lavoro. Per trovare questi parametri:

  1. Cercare il nome dell'area di lavoro nell'angolo in alto a destra della barra degli strumenti di Studio di Azure Machine Learning.
  2. Selezionare il nome dell'area di lavoro per visualizzare il gruppo di risorse e l'ID sottoscrizione.
  3. Copiare i valori per il gruppo di risorse e l'ID sottoscrizione nel codice.
# 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>",
)

Il risultato dell'esecuzione di questo script è un handle dell'area di lavoro che si può usare per gestire altre risorse e processi.

Nota

La creazione di MLClient non connetterà il client all'area di lavoro. L'inizializzazione del client è differita e attenderà fino a quando sarà necessario effettuare una chiamata. In questo articolo ciò si verifica durante la creazione dell’ambiente di calcolo.

Creare una risorsa di calcolo per eseguire il processo

Azure Machine Learning richiede una risorsa di calcolo per eseguire un processo. La risorsa può essere un computer singolo o multinodo con sistema operativo Linux o Windows oppure un'infrastruttura di calcolo specifica come Spark.

Nello script di esempio seguente viene effettuato il provisioning di un cluster di elaborazione Linux. È possibile visualizzare la pagina dei prezzi di Azure Machine Learning per l'elenco completo delle dimensioni e dei prezzi delle macchine virtuali. Poiché per questo esempio è necessario un cluster GPU, selezionare un modello di STANDARD_NC6 e creare un ambiente di calcolo di 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}"
)

Creare un ambiente di processo

Per eseguire un processo di Azure Machine Learning, è necessario un ambiente. Un ambiente di Azure Machine Learning incapsula le dipendenze (ad esempio il runtime del software e le librerie) necessarie per eseguire lo script di training di apprendimento automatico nella risorsa di calcolo. Questo ambiente è simile a un ambiente Python nel computer locale.

Azure Machine Learning consente di usare un ambiente curato (o pronto) o di creare un ambiente personalizzato usando un'immagine Docker o una configurazione Conda. In questo articolo verrà riutilizzato l'ambiente curato di Azure Machine Learning AzureML-pytorch-1.9-ubuntu18.04-py37-cuda11-gpu. È possibile usare la versione più recente di questo ambiente usando la direttiva @latest.

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

Configurare e inviare un processo di training

Questa sezione introduce i dati per il training. Verrà quindi mostrato come eseguire un processo di training usando uno script di training fornito. Verrà mostrato come compilare il processo di training configurando il comando per l'esecuzione dello script di training. Poi il processo di training sarà inviato per l’esecuzione in Azure Machine Learning.

Ottenere i dati di training

È possibile usare il set di dati in questo file compresso. Questo set di dati è costituito da circa 120 immagini di training ognuna per due classi (tacchini e polli), con 100 immagini di convalida per ogni classe. Le immagini sono un subset del set di dati Open Images v5. Lo script di training pytorch_train.py scarica ed estrae il set di dati.

Preparare lo script di training

Nella sezione Prerequisiti è stato fornito lo script di training pytorch_train.py. In pratica, è necessario poter eseguire qualsiasi script di training personalizzato così come è con Azure Machine Learning senza dover modificare il codice.

Lo script di training fornito scarica i dati, esegue il training di un modello e registra il modello.

Compilare il processo di training

Ora che si dispone di tutti gli asset necessari per eseguire il processo, è possibile compilarlo usando Python SDK per Azure Machine Learning v2. Per questo esempio viene creato un command.

Azure Machine Learning command è una risorsa che specifica tutti i dettagli necessari per eseguire il codice di training nel cloud. Tali dettagli includono gli input e gli output, il tipo di hardware da usare, il software da installare e come eseguire il codice. command contiene informazioni per eseguire un singolo comando.

Configurare il comando

Si imposterà l'utilizzo generico command per eseguire lo script di training e le attività desiderate. Creare un oggetto command per specificare i dettagli di configurazione del processo di training.

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",
)
  • Gli input per questo comando includono numero di periodi, frequenza di apprendimento, momentum e directory di output.
  • Per i valori dei parametri:
    1. Specificare il cluster di elaborazione gpu_compute_target = "gpu-cluster" creato per l'esecuzione di questo comando.
    2. Specificare l'ambiente curato AzureML-pytorch-1.9-ubuntu18.04-py37-cuda11-gpu inizializzato in precedenza.
    3. Se non si usa il notebook completato, nella cartella Esempi specificare il percorso del file pytorch_train.py.
    4. Configurare l'azione della riga di comando stessa; in questo caso, il comando è python pytorch_train.py. È possibile accedere agli input e agli output nel comando tramite la notazione ${{ ... }}.
    5. Configurare i metadati (ad esempio, il nome visualizzato e il nome dell'esperimento) dove un esperimento è un contenitore di tutte le iterazioni eseguite in un determinato progetto. Tutti i processi inviati con lo stesso nome dell'esperimento verranno elencati uno accanto all'altro in Studio di Azure Machine Learning.

Inviare il processo

È ora possibile inviare il processo per l'esecuzione in Azure Machine Learning. Questa volta si userà create_or_update in ml_client.jobs.

ml_client.jobs.create_or_update(job)

Al termine, il processo registra un modello nell'area di lavoro (come risultato del training) e restituisce un collegamento per visualizzare il processo in Studio di Azure Machine Learning.

Avviso

Azure Machine Learning esegue gli script di training copiando l'intera directory di origine. Se sono presenti dati sensibili che non si intende caricare, usare un file .ignore oppure non includerli nella directory di origine.

Ciò che accade durante l'esecuzione del processo

Il processo di esecuzione si articola nelle fasi seguenti:

  • Preparazione: viene creata un'immagine Docker in base all'ambiente definito. L'immagine viene caricata nel registro contenitori dell'area di lavoro e memorizzata nella cache per le esecuzioni successive. I log vengono trasmessi anche alla cronologia dei processi e possono essere visualizzati per monitorare lo stato di avanzamento. Se viene specificato un ambiente curato, verrà usata l'immagine memorizzata nella cache in cui è stato eseguito il backup dell'ambiente curato.

  • Ridimensionamento: il cluster tenta di aumentare il numero di nodi, se per l'esecuzione il cluster richiede più nodi di quelli attualmente disponibili.

  • Esecuzione: tutti gli script nella cartella degli script src vengono caricati nella destinazione di calcolo, gli archivi dati vengono montati o copiati e viene eseguito lo script. Gli output di stdout e la cartella ./logs vengono trasmessi alla cronologia dei processi e possono essere usati per monitorare il processo.

Ottimizzare gli iperparametri del modello

È stato eseguito il training del modello con un set di parametri; provare ora a migliorare ulteriormente l'accuratezza del modello. È possibile affinare e ottimizzare gli iperparametri del modello usando le funzionalità di sweep Azure Machine Learning.

Per ottimizzare gli iperparametri del modello definire lo spazio dei parametri in cui eseguire la ricerca durante il training. A tale scopo, sostituire alcuni dei parametri passati al processo di training con input specifici del pacchetto azure.ml.sweep.

Poiché lo script di training usa una pianificazione della velocità di apprendimento per il decadimento della velocità di apprendimento in diversi periodi, è possibile ottimizzare i parametri della velocità di apprendimento iniziale e del momentum.

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

Si configurerà quindi lo sweep nel processo di comando, usando alcuni parametri specifici dello sweep, ad esempio la metrica primaria da controllare e l'algoritmo di campionamento da usare.

Nel codice seguente viene usato il campionamento casuale per provare diversi set di configurazioni di iperparametri nel tentativo di ottimizzare la metrica primaria best_val_acc.

Viene definito anche il criterio di terminazione anticipata BanditPolicyper terminare in anticipo le esecuzioni con prestazioni scarse. Il BanditPolicy termina qualsiasi esecuzione che non rientra nel fattore margine di flessibilità della metrica di valutazione primaria. Questo criterio viene applicato a ogni periodo (poiché la metrica viene riportata in best_val_acc ogni periodo e evaluation_interval=1). Si noti che la prima valutazione dei criteri viene ritardata dei primi 10 periodi (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
    ),
)

È ora possibile inviare questo processo come indicato in precedenza. Questa volta si eseguirà un processo di sweep che esegue tale operazione sul processo di training.

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)

È possibile monitorare il processo usando il collegamento all'interfaccia utente di Studio presentato durante l'esecuzione del processo.

Individuare il modello migliore

Al termine di tutte le esecuzioni è possibile trovare l'esecuzione che ha prodotto il modello con la massima accuratezza.

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

Distribuire il modello come endpoint online

È ora possibile distribuire il modello come endpoint online, ovvero come un servizio Web nel cloud di Azure.

Per distribuire un servizio di apprendimento automatico, in genere sono necessari:

  • Gli asset del modello da distribuire. Questi asset includono il file e i metadati del modello già registrati nel processo di training.
  • Codice da eseguire come un servizio. Il codice esegue il modello su una determinata richiesta di input (uno script di immissione). Lo script di immissione riceve i dati inviati a un servizio Web distribuito e li passa al modello. Dopo che il modello elabora i dati, lo script restituisce la risposta del modello al client. Lo script è specifico del modello e deve riconoscere i dati previsti e restituiti dal modello. Azure Machine Learning crea automaticamente questo script quando si usa un modello MLFlow.

Per altre informazioni sulla distribuzione, vedere Distribuire e assegnare punteggi a un modello di apprendimento automatico con un endpoint online gestito usando Python SDK v2.

Creare un nuovo endpoint online

Innanzitutto, per distribuire il modello è necessario creare un endpoint online. Il nome dell'endpoint deve essere univoco nell’intera area di Azure. In questo articolo si creerà un nome univoco usando un identificatore univoco universale (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}")

Dopo aver creato l'endpoint, è possibile recuperarlo come segue:

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

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

Distribuire il modello nell'endpoint

È ora possibile distribuire il modello con lo script di immissione. Un endpoint può avere più distribuzioni. Usando le regole l'endpoint può quindi indirizzare il traffico a queste distribuzioni.

In questo caso verrà creata una singola distribuzione che gestisce tutto il traffico in ingresso. Per la distribuzione è stato scelto un nome di colore arbitrario (tff-blue). Per la distribuzione è anche possibile usare qualsiasi altro nome, ad esempio tff-green o tff-red.

Codice per distribuire il modello nell'endpoint:

  • Distribuisce la versione migliore del modello registrato in precedenza.
  • Assegna un punteggio al modello usando il file score.py.
  • Usa l'ambiente curato (specificato in precedenza) per eseguire l'inferenza.
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

Il completamento di questa distribuzione impiegherà un po' di tempo.

Testare il modello distribuito

Dopo aver distribuito il modello nell'endpoint, è possibile stimare l'output del modello distribuito usando il metodo invoke nell'endpoint.

Per testare l'endpoint si userà un'immagine di esempio per la stima. Innanzitutto, visualizzare l’immagine.

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

Creare una funzione per formattare e ridimensionare l'immagine.

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

Formattare l'immagine e convertirla in un file 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)

È quindi possibile richiamare l'endpoint con questo file JSON e stampare il risultato.

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

Pulire le risorse

Se l'endpoint non è più necessario, eliminarlo per interrompere l'uso della risorsa. Assicurarsi che nessun'altra distribuzione usi l'endpoint prima di eliminarlo.

ml_client.online_endpoints.begin_delete(name=online_endpoint_name)

Nota

Il completamento di questa pulizia impiegherà un po' di tempo.

Passaggi successivi

In questo articolo è stato eseguito il training e la registrazione di una rete neurale di Deep Learning con PyTorch in Azure Machine Learning. Il modello è stato distribuito anche in un endpoint online. Per altre informazioni su Azure Machine Learning, vedere i seguenti altri articoli.