Creare script di assegnazione dei punteggi per le distribuzioni batch

SI APPLICA A:Estensione ML dell'interfaccia della riga di comando di Azure v2 (corrente)Python SDK azure-ai-ml v2 (corrente)

Gli endpoint batch consentono di distribuire modelli che eseguono l'inferenza a esecuzione prolungata su larga scala. Quando si distribuiscono modelli, è necessario creare e specificare uno script di assegnazione dei punteggi (noto anche come script del driver batch) per indicare come usarlo sui dati di input per creare stime. In questo articolo si apprenderà come usare gli script di assegnazione dei punteggi nelle distribuzioni di modelli per diversi scenari. Verranno inoltre illustrate le procedure consigliate per gli endpoint batch.

Suggerimento

I modelli MLflow non richiedono uno script di assegnazione dei punteggi. Viene generato automaticamente per te. Per altre informazioni sul funzionamento degli endpoint batch con i modelli MLflow, vedere l'esercitazione Sull'uso di modelli MLflow nelle distribuzioni batch dedicate.

Avviso

Per distribuire un modello di Machine Learning automatizzato in un endpoint batch, si noti che Machine Learning automatizzato fornisce uno script di assegnazione dei punteggi che funziona solo per gli endpoint online. Lo script di assegnazione dei punteggi non è progettato per l'esecuzione batch. Seguire queste linee guida per altre informazioni su come creare uno script di assegnazione dei punteggi, personalizzato per le operazioni del modello.

Informazioni sullo script di assegnazione dei punteggi

Lo script di assegnazione dei punteggi è un file Python (.py) che specifica come eseguire il modello e legge i dati di input inviati dall'executor di distribuzione batch. Ogni distribuzione del modello fornisce lo script di assegnazione dei punteggi (insieme a tutte le altre dipendenze necessarie) in fase di creazione. Lo script di assegnazione dei punteggi è in genere simile al seguente:

deployment.yml

code_configuration:
  code: code
  scoring_script: batch_driver.py

Lo script di assegnazione dei punteggi deve contenere due metodi:

Metodo init

Usare il metodo init() per le preparazioni dispendiose o comuni. Ad esempio, usarlo per caricare il modello in memoria. L'avvio dell'intero processo batch chiama questa funzione una sola volta. I file del modello sono disponibili in un percorso determinato dalla variabile AZUREML_MODEL_DIRdi ambiente . A seconda della modalità di registrazione del modello, i relativi file potrebbero essere contenuti in una cartella. Nell'esempio seguente il modello include diversi file in una cartella denominata model. Per altre informazioni, vedere come determinare la cartella usata dal modello.

def init():
    global model

    # AZUREML_MODEL_DIR is an environment variable created during deployment
    # The path "model" is the name of the registered model's folder
    model_path = os.path.join(os.environ["AZUREML_MODEL_DIR"], "model")

    # load the model
    model = load_model(model_path)

In questo esempio il modello viene inserito nella variabile modelglobale . Per rendere disponibili gli asset necessari per eseguire l'inferenza nella funzione di assegnazione dei punteggi, usare le variabili globali.

Metodo run

Usare il run(mini_batch: List[str]) -> Union[List[Any], pandas.DataFrame] metodo per gestire l'assegnazione dei punteggi di ogni mini batch generato dalla distribuzione batch. Questo metodo viene chiamato una volta per ogni mini_batch generato per i dati di input. Le distribuzioni batch leggono i dati in batch in base alla configurazione della distribuzione.

import pandas as pd
from typing import List, Any, Union

def run(mini_batch: List[str]) -> Union[List[Any], pd.DataFrame]:
    results = []

    for file in mini_batch:
        (...)

    return pd.DataFrame(results)

Il metodo riceve un elenco di percorsi di file come parametro (mini_batch). È possibile usare questo elenco per scorrere ed elaborare singolarmente ogni file oppure per leggere l'intero batch ed elaborarlo tutti contemporaneamente. L'opzione migliore dipenderà dalla memoria di calcolo e dalla velocità effettiva che è necessario ottenere. Per un esempio che descrive come leggere interi batch di dati contemporaneamente, vedere Distribuzioni a velocità effettiva elevata.

Nota

Come viene distribuito il lavoro?

Le distribuzioni batch distribuiscono il lavoro a livello di file, ovvero una cartella che contiene 100 file, con mini batch di 10 file, genera 10 batch di 10 file ciascuno. Si noti che le dimensioni dei file pertinenti non hanno rilevanza. Per i file troppo grandi per l'elaborazione in mini batch di grandi dimensioni, è consigliabile suddividere i file in file più piccoli per ottenere un livello di parallelismo superiore o ridurre il numero di file per mini batch. Al momento, la distribuzione batch non può tenere conto delle differenze nella distribuzione delle dimensioni del file.

Il metodo run() deve restituire un Pandas DataFrameo una matrice/un elenco. Ogni elemento di output restituito indica un'esecuzione riuscita di un elemento di input nell'input mini_batch. Per gli asset di dati di file o cartelle, ogni riga/elemento restituito rappresenta un singolo file elaborato. Per un asset di dati tabulare, ogni riga/elemento restituito rappresenta una riga in un file elaborato.

Importante

Come scrivere le previsioni

Tutti gli elementi restituiti dalla run() funzione verranno accodati nel file di stime di output generato dal processo batch. È importante restituire il tipo di dati corretto da questa funzione. Restituire matrici quando è necessario eseguire l'output di una singola previsione. Restituire dataframe Pandas quando è necessario restituire più informazioni. Ad esempio, per i dati tabulari, è possibile aggiungere le stime al record originale. Usare un dataframe pandas per eseguire questa operazione. Anche se un dataframe pandas potrebbe contenere nomi di colonna, il file di output non include tali nomi.

per scrivere stime in modo diverso, è possibile personalizzare gli output nelle distribuzioni batch.

Avviso

run Nella funzione non restituire tipi di dati complessi (o elenchi di tipi di dati complessi) anziché pandas.DataFrame. Questi output verranno trasformati in stringhe e diventeranno difficili da leggere.

Il dataframe o la matrice risultante viene aggiunto al file di output indicato. Non è necessario specificare la cardinalità dei risultati. Un file può generare 1 o più righe/elementi nell'output. Tutti gli elementi nel dataframe o nella matrice risultante verranno scritti nel file di output così come sono (considerando che output_action non è summary_only).

Pacchetti Python per l'assegnazione dei punteggi

È necessario indicare qualsiasi libreria necessaria per l'esecuzione dello script di assegnazione dei punteggi nell'ambiente in cui viene eseguita la distribuzione batch. Per gli script di assegnazione dei punteggi, gli ambienti sono indicati per distribuzione. In genere, si indicano i requisiti usando un conda.yml file di dipendenze, che potrebbe essere simile al seguente:

mnist/environment/conda.yaml

name: mnist-env
channels:
  - conda-forge
dependencies:
  - python=3.8.5
  - pip<22.0
  - pip:
    - torch==1.13.0
    - torchvision==0.14.0
    - pytorch-lightning
    - pandas
    - azureml-core
    - azureml-dataset-runtime[fuse]

Per altre informazioni su come indicare l'ambiente per il modello, vedere Creare una distribuzione batch.

Scrivere le previsioni in modo diverso

Per impostazione predefinita, la distribuzione batch scrive le previsioni del modello in un singolo file, come indicato nella distribuzione. In alcuni casi, tuttavia, è necessario scrivere le stime in più file. Ad esempio, per i dati di input partizionati, è probabile che si voglia generare anche l'output partizionato. In questi casi, è possibile personalizzare gli output nelle distribuzioni batch per indicare:

  • Formato di file (CSV, parquet, json e così via) usato per scrivere stime
  • Modalità di partizionamento dei dati nell'output

Per altre informazioni su come ottenerlo, vedere Personalizzare gli output nelle distribuzioni batch.

Controllo del codice sorgente degli script di assegnazione dei punteggi

È consigliabile inserire script di assegnazione dei punteggi sotto il controllo del codice sorgente.

Procedure consigliate per la scrittura di script di assegnazione dei punteggi

Quando si scrivono script di assegnazione dei punteggi che gestiscono grandi quantità di dati, è necessario tenere conto di diversi fattori, tra cui

  • Dimensioni di ogni file
  • Quantità di dati in ogni file
  • Quantità di memoria necessaria per leggere ogni file
  • Quantità di memoria necessaria per leggere un intero batch di file
  • Footprint di memoria del modello
  • Footprint della memoria del modello, durante l'esecuzione sui dati di input
  • Memoria disponibile nel calcolo

Le distribuzioni batch distribuiscono il lavoro a livello di file. Ciò significa che una cartella che contiene 100 file, in mini batch di 10 file, genera 10 batch di 10 file ciascuno (indipendentemente dalle dimensioni dei file coinvolti). Per i file troppo grandi per l'elaborazione in mini batch di grandi dimensioni, è consigliabile suddividere i file in file più piccoli, per ottenere un livello più elevato di parallelismo o ridurre il numero di file per mini batch. Al momento, la distribuzione batch non può tenere conto delle differenze nella distribuzione delle dimensioni del file.

Relazione tra il grado di parallelismo e lo script di assegnazione dei punteggi

La configurazione della distribuzione controlla sia le dimensioni di ogni mini batch che il numero di ruoli di lavoro in ogni nodo. Ciò diventa importante quando si decide se leggere o meno l'intero mini batch per eseguire l'inferenza, per eseguire il file di inferenza in base al file o eseguire la riga di inferenza per riga (per tabulare). Per altre informazioni, vedere Esecuzione dell'inferenza nel mini batch, nel file o nel livello di riga.

Quando si eseguono più ruoli di lavoro nella stessa istanza, è necessario tenere conto del fatto che la memoria è condivisa tra tutti i ruoli di lavoro. Un aumento del numero di ruoli di lavoro per nodo dovrebbe in genere accompagnare una diminuzione delle dimensioni del mini batch o da una modifica della strategia di assegnazione dei punteggi se le dimensioni dei dati e lo SKU di calcolo rimangono invariati.

Esecuzione dell'inferenza a livello di mini batch, file o riga

Gli endpoint batch chiamano la run() funzione in uno script di assegnazione dei punteggi una volta per mini-batch. Tuttavia, è possibile decidere se si vuole eseguire l'inferenza sull'intero batch, su un file alla volta o su una riga alla volta per i dati tabulari.

Livello mini batch

In genere si vuole eseguire l'inferenza sul batch contemporaneamente per ottenere una velocità effettiva elevata nel processo di assegnazione dei punteggi batch. Ciò si verifica se si esegue l'inferenza su una GPU, in cui si vuole ottenere la saturazione del dispositivo di inferenza. È anche possibile fare affidamento su un caricatore di dati in grado di gestire l'invio in batch se i dati non si adattano alla memoria, ad esempio TensorFlow o PyTorch ai caricatori di dati. In questi casi, potrebbe essere necessario eseguire l'inferenza nell'intero batch.

Avviso

L'esecuzione dell'inferenza a livello di batch potrebbe richiedere un controllo stretto sulle dimensioni dei dati di input, per tenere in considerazione correttamente i requisiti di memoria e per evitare eccezioni di memoria insufficiente. Se è possibile caricare o meno l'intero mini batch in memoria dipende dalle dimensioni del mini batch, dalle dimensioni delle istanze del cluster, dal numero di ruoli di lavoro in ogni nodo e dalle dimensioni del mini batch.

Per informazioni su come ottenere questo risultato, vedere Distribuzioni a velocità effettiva elevata. In questo esempio viene elaborato un intero batch di file alla volta.

Livello file

Uno dei modi più semplici per eseguire l'inferenza è l'iterazione su tutti i file nel mini batch e quindi eseguire il modello su di esso. In alcuni casi, ad esempio l'elaborazione di immagini, potrebbe essere una buona idea. Per i dati tabulari, potrebbe essere necessario eseguire una stima valida sul numero di righe in ogni file. Questa stima può indicare se il modello può gestire o meno i requisiti di memoria per caricare l'intero dato in memoria e per eseguirne l'inferenza. Alcuni modelli (in particolare quelli basati su reti neurali ricorrenti) si svolgono e presentano un footprint di memoria con un numero di righe potenzialmente non lineare. Per un modello con spese di memoria elevate, prendere in considerazione l'esecuzione dell'inferenza a livello di riga.

Suggerimento

Prendere in considerazione la possibilità di suddividere i file troppo grandi per leggere contemporaneamente in più file più piccoli, per tenere conto di una migliore parallelizzazione.

Per informazioni su come eseguire questa operazione, vedere Elaborazione di immagini con distribuzioni batch. Questo esempio elabora un file alla volta.

Livello riga (tabulare)

Per i modelli che presentano problemi con le dimensioni di input, è possibile eseguire l'inferenza a livello di riga. La distribuzione batch fornisce comunque lo script di assegnazione dei punteggi con un mini batch di file. Tuttavia, si leggerà un file, una riga alla volta. Questo potrebbe sembrare inefficiente, ma per alcuni modelli di Deep Learning potrebbe essere l'unico modo per eseguire l'inferenza senza aumentare le risorse hardware.

Per informazioni su come eseguire questa operazione, vedere Elaborazione del testo con distribuzioni batch. In questo esempio viene elaborata una riga alla volta.

Uso di modelli che sono cartelle

La AZUREML_MODEL_DIR variabile di ambiente contiene il percorso del modello selezionato e la init() funzione lo usa in genere per caricare il modello in memoria. Tuttavia, alcuni modelli potrebbero contenere i relativi file in una cartella e potrebbe essere necessario tenere conto di questo durante il caricamento. È possibile identificare la struttura di cartelle del modello, come illustrato di seguito:

  1. Andare al portale di Azure Machine Learning.

  2. Andare alla sezione Modelli.

  3. Selezionare il modello da distribuire e selezionare la scheda Artefatti .

  4. Prendere nota della cartella visualizzata. Tale cartella è stata specificata al momento della registrazione del modello.

    Screenshot che mostra la cartella in cui sono posizionati gli artefatti del modello.

Usare questo percorso per caricare il modello:

def init():
    global model

    # AZUREML_MODEL_DIR is an environment variable created during deployment
    # The path "model" is the name of the registered model's folder
    model_path = os.path.join(os.environ["AZUREML_MODEL_DIR"], "model")

    model = load_model(model_path)

Passaggi successivi