Condividi tramite


Spostamento di dati in e tra i passaggi della pipeline ML (Python)

SI APPLICA A: Python SDK azureml v1

Questo articolo fornisce il codice per l'importazione, la trasformazione e lo spostamento dei dati tra i passaggi in una pipeline di Azure Machine Learning. Per una panoramica del funzionamento dei dati in Azure Machine Learning, vedere Accedere ai dati nei servizi di archiviazione di Azure. Per i vantaggi e la struttura delle pipeline di Azure Machine Learning, vedere Che cosa sono le pipeline di Azure Machine Learning?.

Questo articolo illustra come:

  • Usare oggetti Dataset per dati preesistenti
  • Accedere ai dati all'interno dei passaggi
  • Suddividere i dati di Dataset in subset, ad esempio subset di training e convalida
  • Creare oggetti OutputFileDatasetConfig per trasferire i dati al passaggio successivo della pipeline
  • Usare gli oggetti OutputFileDatasetConfig come input per i passaggi della pipeline
  • Creare nuovi oggetti Dataset di OutputFileDatasetConfig che si vuole rendere persistenti

Prerequisiti

È necessario:

Usare oggetti Dataset per dati preesistenti

Il modo preferito per inserire dati in una pipeline consiste nell'usare un oggetto Dataset. Gli oggetti Dataset rappresentano i dati persistenti disponibili in un'area di lavoro.

Esistono molti modi per creare e registrare oggetti Dataset. I set di dati tabulari si usano per dati delimitati disponibili in uno o più file. I set di dati di file si usano per dati binari (ad esempio immagini) o dati analizzati. Il modo più semplice per creare oggetti Dataset a livello di codice consiste nell'usare BLOB esistenti nello spazio di archiviazione dell'area di lavoro o URL pubblici:

datastore = Datastore.get(workspace, 'training_data')
iris_dataset = Dataset.Tabular.from_delimited_files(DataPath(datastore, 'iris.csv'))

datastore_path = [
    DataPath(datastore, 'animals/dog/1.jpg'),
    DataPath(datastore, 'animals/dog/2.jpg'),
    DataPath(datastore, 'animals/cat/*.jpg')
]
cats_dogs_dataset = Dataset.File.from_files(path=datastore_path)

Per altre opzioni su come creare set di dati con opzioni diverse e da origini diverse, su come registrarli ed esaminarli nell'interfaccia utente di Azure Machine Learning, su come conoscere l'interazione tra dimensioni dei dati e capacità di calcolo e su come implementare il controllo delle versioni, vedere Creare set di dati di Azure Machine Learning.

Passare set di dati allo script

Per passare il percorso del set di dati allo script, usare il metodo as_named_input() dell'oggetto Dataset. È possibile passare l'oggetto DatasetConsumptionConfig risultante allo script come argomento oppure, usando l'argomento inputs dello script della pipeline, è possibile recuperare il set di dati usando Run.get_context().input_datasets[].

Dopo aver creato un input denominato, è possibile sceglierne la modalità di accesso (solo per FileDataset), ovvero as_mount() o as_download(). Se lo script elabora tutti i file nel set di dati e le dimensioni del disco nella risorsa di calcolo sono sufficienti per il set di dati, la modalità di accesso al download è la scelta migliore. La modalità di accesso al download evita il sovraccarico dello streaming dei dati in fase di esecuzione. Se lo script accede a un subset del set di dati o è troppo grande per l'ambiente di calcolo, usare la modalità di accesso al montaggio. Per altre informazioni, vedere Montaggio e download

Per passare un set di dati al passaggio della pipeline:

  1. Usare TabularDataset.as_named_input() o FileDataset.as_named_input() (senza 's' alla fine) per creare un oggetto DatasetConsumptionConfig.
  2. Solo per FileDataset: usare as_mount() o as_download() per impostare la modalità di accesso. TabularDataset non supporta la modalità di accesso impostata.
  3. Passare i set di dati ai passaggi della pipeline usando o l'argomento arguments o inputs.

Il frammento di codice seguente illustra il criterio comune di combinazione di questi passaggi all'interno del costruttore PythonScriptStep, usando iris_dataset (TabularDataset):


train_step = PythonScriptStep(
    name="train_data",
    script_name="train.py",
    compute_target=cluster,
    inputs=[iris_dataset.as_named_input('iris')]
)

Nota

È necessario sostituire i valori per tutti questi argomenti (ovvero "train_data", "train.py", cluster e iris_dataset) con i propri dati. Il frammento di codice precedente mostra solo il formato della chiamata e non fa parte di un esempio Microsoft.

È anche possibile usare metodi come random_split() e take_sample() per creare più input o ridurre la quantità di dati passati al passaggio della pipeline:

seed = 42 # PRNG seed
smaller_dataset = iris_dataset.take_sample(0.1, seed=seed) # 10%
train, test = smaller_dataset.random_split(percentage=0.8, seed=seed)

train_step = PythonScriptStep(
    name="train_data",
    script_name="train.py",
    compute_target=cluster,
    inputs=[train.as_named_input('train'), test.as_named_input('test')]
)

Accedere ai set di dati all'interno dello script

Gli input denominati per lo script del passaggio della pipeline sono disponibili come dizionario nell'oggetto Run. Recuperare l'oggetto Run attivo con Run.get_context() e quindi recuperare il dizionario degli input denominati con input_datasets. Se l'oggetto DatasetConsumptionConfig è stato passato con l'argomento arguments invece dell'argomento inputs, accedere ai dati usando il codice ArgParser. Entrambe le tecniche sono illustrate nei frammenti di codice seguenti:

Script di definizione della pipeline

# Code for demonstration only: It would be very confusing to split datasets between `arguments` and `inputs`
train_step = PythonScriptStep(
    name="train_data",
    script_name="train.py",
    compute_target=cluster,
    # datasets passed as arguments
    arguments=['--training-folder', train.as_named_input('train').as_download()],
    # datasets passed as inputs
    inputs=[test.as_named_input('test').as_download()]
)

Script train.py a cui viene fatto riferimento in PythonScriptStep

# In pipeline script
parser = argparse.ArgumentParser()
# Retreive the dataset passed as an argument
parser.add_argument('--training-folder', type=str, dest='train_folder', help='training data folder mounting point')
args = parser.parse_args()
training_data_folder = args.train_folder
# Retrieve the dataset passed as an input
testing_data_folder = Run.get_context().input_datasets['test']

Il valore passato è il percorso dei file del set di dati.

È anche possibile accedere direttamente a un oggetto Dataset registrato. Poiché i set di dati registrati sono persistenti e condivisi in un'area di lavoro, è possibile recuperarli direttamente:

run = Run.get_context()
ws = run.experiment.workspace
ds = Dataset.get_by_name(workspace=ws, name='mnist_opendataset')

Nota

I frammenti di codice precedenti mostrano il formato delle chiamate e non fanno parte di un esempio Microsoft. È necessario sostituire i vari argomenti con i valori del progetto personalizzato.

Usare OutputFileDatasetConfig per i dati intermedi

Mentre gli oggetti Dataset rappresentano solo dati persistenti, gli oggetti OutputFileDatasetConfig possono essere usati per l'output temporaneo dei dati dai passaggi della pipeline e dei dati di output persistenti. OutputFileDatasetConfig supporta la scrittura di dati in Archiviazione BLOB, condivisione file, adlsgen1 o adlsgen2. Supporta sia la modalità di montaggio che la modalità di caricamento. In modalità di montaggio i file scritti nella directory montata vengono archiviati in modo permanente alla chiusura del file. In modalità di caricamento i file scritti nella directory di output vengono caricati alla fine del processo. Se il processo non riesce o viene annullato, la directory di output non verrà caricata.

Il comportamento predefinito dell'oggetto OutputFileDatasetConfig consiste nello scrivere nell'archivio dati predefinito dell'area di lavoro. Passare gli oggetti OutputFileDatasetConfig a oggetto PythonScriptStep con il parametro arguments.

from azureml.data import OutputFileDatasetConfig
dataprep_output = OutputFileDatasetConfig()
input_dataset = Dataset.get_by_name(workspace, 'raw_data')

dataprep_step = PythonScriptStep(
    name="prep_data",
    script_name="dataprep.py",
    compute_target=cluster,
    arguments=[input_dataset.as_named_input('raw_data').as_mount(), dataprep_output]
    )

Nota

Le operazioni di scrittura simultanee in un oggetto OutputFileDatasetConfig avranno esito negativo. Non provare a usare un singolo oggetto OutputFileDatasetConfig simultaneamente. Non condividere un singolo oggetto OutputFileDatasetConfig in una situazione di multielaborazione, ad esempio quando si usa il training distribuito.

Usare OutputFileDatasetConfig come output di un passaggio di training

All'interno di PythonScriptStep della pipeline è possibile recuperare i percorsi di output disponibili usando gli argomenti del programma. Se questo passaggio è il primo e inizializza i dati di output, sarà necessario creare la directory al percorso specificato. È quindi possibile scrivere tutti i file che si vogliono includere in OutputFileDatasetConfig.

parser = argparse.ArgumentParser()
parser.add_argument('--output_path', dest='output_path', required=True)
args = parser.parse_args()

# Make directory for file
os.makedirs(os.path.dirname(args.output_path), exist_ok=True)
with open(args.output_path, 'w') as f:
    f.write("Step 1's output")

Leggere OutputFileDatasetConfig come input per i passaggi non iniziali

Dopo che il passaggio iniziale della pipeline scrive alcuni dati nel percorso di OutputFileDatasetConfig e diventa un output di tale passaggio iniziale, può essere usato come input in un passaggio successivo.

Nel codice seguente:

  • step1_output_data indica che l'output di PythonScriptStep, ovvero step1, viene scritto nell'archivio dati di ADLS Gen 2, my_adlsgen2 in modalità di accesso di caricamento. Altre informazioni su come configurare le autorizzazioni dei ruoli per scrivere di nuovo i dati negli archivi dati di ADLS Gen 2.

  • Una volta completata l'esecuzione di step1, l'output viene scritto nella destinazione indicata da step1_output_data e step2 può usare step1_output_data come input.

# get adls gen 2 datastore already registered with the workspace
datastore = workspace.datastores['my_adlsgen2']
step1_output_data = OutputFileDatasetConfig(name="processed_data", destination=(datastore, "mypath/{run-id}/{output-name}")).as_upload()

step1 = PythonScriptStep(
    name="generate_data",
    script_name="step1.py",
    runconfig = aml_run_config,
    arguments = ["--output_path", step1_output_data]
)

step2 = PythonScriptStep(
    name="read_pipeline_data",
    script_name="step2.py",
    compute_target=compute,
    runconfig = aml_run_config,
    arguments = ["--pd", step1_output_data.as_input()]

)

pipeline = Pipeline(workspace=ws, steps=[step1, step2])

Suggerimento

La lettura dei dati nello script Python step2.py è identica a quella descritta in precedenza in Accedere ai set di dati all'interno dello script. Usare ArgumentParser per aggiungere un argomento --pd nello script per accedere ai dati.

Registrare oggetti OutputFileDatasetConfig per il riutilizzo

Se si vuole rendere OutputFileDatasetConfig disponibile per più tempo rispetto alla durata dell'esperimento, registrarlo nell'area di lavoro per condividerlo e riutilizzarlo in più esperimenti.

step1_output_ds = step1_output_data.register_on_complete(
    name='processed_data', 
    description = 'files from step1'
)

Eliminare il contenuto di OutputFileDatasetConfig quando non è più necessario

Azure non elimina automaticamente i dati intermedi scritti con OutputFileDatasetConfig. Per evitare addebiti di archiviazione per grandi quantità di dati non necessari, è consigliabile:

Attenzione

Eliminare i dati intermedi solo dopo 30 giorni dalla data dell'ultima modifica dei dati. L'eliminazione dei dati prima di tale data potrebbe impedire la corretta esecuzione della pipeline perché la pipeline presuppone che i dati intermedi rimangano disponibili per 30 giorni per essere riutilizzati.

  • Eliminare i dati intermedi a livello di codice alla fine di un processo della pipeline, quando non sono più necessari.
  • Usare l'archiviazione BLOB con criteri di archiviazione a breve termine per i dati intermedi (vedere Ottimizzare i costi automatizzando i livelli di accesso di Archiviazione BLOB di Azure). Questo criterio può essere impostato solo su un archivio dati non predefinito di un'area di lavoro. Usare OutputFileDatasetConfig per esportare i dati intermedi in un altro archivio dati che non è quello predefinito.
    # Get adls gen 2 datastore already registered with the workspace
    datastore = workspace.datastores['my_adlsgen2']
    step1_output_data = OutputFileDatasetConfig(name="processed_data", destination=(datastore, "mypath/{run-id}/{output-name}")).as_upload()
    
  • Esaminare ed eliminare regolarmente i dati non più necessari.

Per altre informazioni, vedere Pianificare e gestire i costi per Azure Machine Learning.

Passaggi successivi