Share via


Verschieben von Daten in ML-Pipelineschritte und zwischen ML-Pipelineschritten (Python)

GILT FÜR:Python SDK azureml v1

Dieser Artikel enthält Code zum Importieren, Transformieren und Verschieben von Daten zwischen Schritten in einer Azure Machine Learning-Pipeline. Eine Übersicht über die Funktionsweise von Daten in Azure Machine Learning finden Sie unter Zugreifen auf Daten in Azure Storage-Diensten. Zu den Vorteilen und der Struktur von Azure Machine Learning Pipelines siehe Was sind Azure Machine Learning Pipelines?

In diesem Artikel lernen Sie Folgendes:

  • Verwenden von Dataset-Objekten für bereits vorhandene Daten
  • Zugreifen auf Daten in Ihren Schritten
  • Aufteilen von Dataset-Daten in Teilmengen, z. B. Teilmengen für Training und Validierung
  • Erstellen von OutputFileDatasetConfig-Objekten zum Übertragen von Daten in den nächsten Pipelineschritt
  • Verwenden von OutputFileDatasetConfig-Objekten als Eingabe für Pipelineschritte
  • Erstellen neuer Dataset-Objekte aus OutputFileDatasetConfig, die Sie beibehalten möchten

Voraussetzungen

Erforderlich:

Verwenden von Dataset-Objekten für bereits vorhandene Daten

Die bevorzugte Methode zur Erfassung von Daten in einer Pipeline ist die Verwendung eines Dataset-Objekts. Dataset-Objekte stellen persistente Daten dar, die im gesamten Arbeitsbereich verfügbar sind.

Es gibt viele Möglichkeiten, Dataset-Objekte zu erstellen und zu registrieren. Tabellendatasets sind für durch Trennzeichen getrennte Daten verfügbar, die in einer oder mehreren Dateien enthalten sind. Dateidatasets sind für Binärdaten (z. B. Images) oder für zu analysierende Daten verfügbar. Die einfachsten programmgesteuerten Möglichkeiten zum Erstellen von Dataset-Objekte sind die Verwendung vorhandener Blobs im Arbeitsbereichsspeicher oder öffentlicher URLs:

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)

Weitere Optionen zum Erstellen von Datasets mit verschiedenen Optionen und aus unterschiedlichen Quellen, zum Registrieren und Überprüfen der Daten in der Azure Machine Learning-Benutzeroberfläche, zum Verständnis, wie die Datengröße mit der Computekapazität interagiert, und zu deren Versionsverwaltung finden Sie unter Erstellen von Azure Machine Learning-Datasets.

Übergeben von Datasets an Ihr Skript

Verwenden Sie die as_named_input()-Methode des Dataset-Objekts, um den Pfad des Datasets an Ihr Skript zu übergeben. Sie können entweder das resultierende DatasetConsumptionConfig-Objekt als Argument an Ihr Skript übergeben oder durch Verwendung des inputs-Arguments an Ihr Pipelineskript das Dataset mit Run.get_context().input_datasets[] abrufen.

Nachdem Sie eine benannte Eingabe erstellt haben, können Sie ihren Zugriffsmodus (nur für FileDataset) auswählen: as_mount() oder as_download(). Wenn Ihr Skript alle Dateien in Ihrem Dataset verarbeitet und der Datenträger auf Ihrer Compute-Ressource ausreichend groß für das Dataset ist, ist der Zugriffsmodus „Herunterladen“ die bessere Wahl. Der Zugriffsmodus „Herunterladen“ vermeidet den Mehraufwand für das Streaming der Daten zur Laufzeit. Wenn Ihr Skript auf eine Teilmenge des Datasets zugreift oder es zu groß für Ihre Berechnung ist, verwenden Sie den Zugriffsmodus „Einbinden“. Weitere Informationen finden Sie unter Einbinden im Vergleich zum Herunterladen

So übergeben Sie ein Dataset an den Pipelineschritt:

  1. Verwenden Sie TabularDataset.as_named_input() oder FileDataset.as_named_input() (kein „s“ am Ende) zum Erstellen eines DatasetConsumptionConfig-Objekts.
  2. Nur FileDatasetfür:. Verwenden Sie as_mount() oder as_download(), um den Zugriffsmodus festzulegen. TabularDataset bietet keinen Suppport-Set-Zugriffsmodus.
  3. Übergeben Sie die Datasets mithilfe des Arguments arguments oder inputs an ihre Pipelineschritte.

Der folgende Ausschnitt zeigt das übliche Muster der Kombination dieser Schritte innerhalb des PythonScriptStep-Konstruktors unter Verwendung von iris_dataset (TabularDataset):


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

Hinweis

Sie müssen die Werte aller dieser Argumente (d. h. "train_data", "train.py", cluster und iris_dataset) durch eigene Daten ersetzen. Der obige Ausschnitt zeigt nur die Form des Aufrufs und ist nicht Teil eines Microsoft-Beispiels.

Sie können auch Methoden wie random_split() und take_sample() verwenden, um mehrere Eingaben zu erstellen oder die Menge der an Ihren Pipelineschritt übergebenen Daten zu reduzieren:

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

Zugreifen auf Datasets in Ihrem Skript

Benannte Eingaben für Ihr Pipelineschrittskript sind als Wörterbuch innerhalb des Run-Objekts verfügbar. Rufen Sie das aktive Run-Objekt mit Run.get_context() und anschließend das Wörterbuch der benannten Eingaben mit input_datasets ab. Wenn Sie das DatasetConsumptionConfig-Objekt mit dem arguments-Argument statt mit dem inputs-Argument übergeben haben, greifen Sie auf die Daten mit ArgParser-Code zu. Beide Verfahren werden in den folgenden Codeschnipseln veranschaulicht:

Skript zur Pipelinedefinition

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

Das train.py-Skript, auf das über PythonScriptStep verwiesen wird

# 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']

Der übergebene Wert ist der Pfad zu der/den Datasetdatei(en).

Es ist auch möglich, direkt auf ein registriertes Dataset zuzugreifen. Da registrierte Datasets persistent sind und in einem Arbeitsbereich freigegeben werden, können Sie sie direkt abrufen:

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

Hinweis

Die vorherigen Ausschnitte zeigen nur die Form der Aufrufe und sind nicht Teil eines Microsoft-Beispiels. Sie müssen die verschiedenen Argumente durch Werte aus Ihrem eigenen Projekt ersetzen.

Verwenden von OutputFileDatasetConfig für Zwischendaten

Während Dataset-Objekte nur persistente Daten darstellen, können OutputFileDatasetConfig-Objekte zur temporären Datenausgabe von Pipelineschritten und für persistente Ausgabedaten verwendet werden. OutputFileDatasetConfig unterstützt das Schreiben von Daten in Blob-Speicher, Dateifreigaben, adlsgen1 oder adlsgen2. Sowohl der Einbindungsmodus als auch der Hochlademodus werden unterstützt. Im Einbindungsmodus werden Dateien, die in das eingebundene Verzeichnis geschrieben werden, beim Schließen der Datei dauerhaft gespeichert. Im Uploadmodus werden Dateien, die in das Ausgabeverzeichnis geschrieben werden, am Ende des Auftrags hochgeladen. Wenn beim Auftrag ein Fehler auftritt oder er abgebrochen wird, wird das Ausgabeverzeichnis nicht hochgeladen.

Das Standardverhalten des OutputFileDatasetConfig-Objekts besteht darin, in den Standarddatenspeicher des Arbeitsbereichs zu schreiben. Übergeben Sie die OutputFileDatasetConfig-Objekte mit dem arguments-Parameter an Ihren PythonScriptStep.

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

Hinweis

Beim gleichzeitigen Schreiben in eine OutputFileDatasetConfig tritt ein Fehler auf. Versuchen Sie nicht, eine einzelne OutputFileDatasetConfig parallel zu verwenden. Verwenden Sie keine einzelne, gemeinsam genutzte OutputFileDatasetConfig in einem Szenario mit Multiprocessing, etwa für ein verteiltes Training.

Verwenden von OutputFileDatasetConfig als Ausgaben eines Trainingsschritts

Innerhalb der PythonScriptStep Ihrer Pipeline können Sie die verfügbaren Ausgabepfade mit den Argumenten des Programms abrufen. Wenn dieser Schritt der erste ist und die Ausgabedaten initialisieren soll, müssen Sie das Verzeichnis unter dem angegebenen Pfad erstellen. Sie können dann die Dateien schreiben, die Sie in OutputFileDatasetConfig aufnehmen möchten.

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

Lesen von OutputFileDatasetConfig als Eingaben für nachfolgende Schritte

Nachdem der anfängliche Pipelineschritt einige Daten in den OutputFileDatasetConfig-Pfad geschrieben hat und sie als Ausgabe dieses anfänglichen Schritts dienen, können die Daten als Eingabe für einen späteren Schritt verwendet werden.

Im folgenden Code wird Folgendes ausgeführt:

  • gibt step1_output_data an, dass die Ausgabe von PythonScriptStep, step1, im Uploadzugriffsmodus in den ADLS Gen 2-Datenspeicher my_adlsgen2 geschrieben wird. Erfahren Sie mehr über das Einrichten von Rollenberechtigungen, um Daten in ADLS Gen 2-Datenspeicher zurückzuschreiben.

  • Nachdem step1 abgeschlossen und die Ausgabe in das durch step1_output_data angegebene Ziel geschrieben wurde, ist step2 bereit, step1_output_data als Eingabe zu verwenden.

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

Tipp

Das Lesen der Daten im Python-Skript step2.py ist dasselbe wie unter Zugreifen auf Datasets in Ihrem Skript beschrieben. Fügen Sie mit ArgumentParser in Ihrem Skript ein Argument von --pd hinzu, um auf die Daten zuzugreifen.

Registrieren von OutputFileDatasetConfig-Objekten für die Wiederverwendung

Wenn Sie Ihre OutputFileDatasetConfig-Objekte über die Dauer Ihres Experiments hinaus verfügbar machen möchten, registrieren Sie sie in Ihrem Arbeitsbereich, um sie Experimente übergreifend freizugeben und wiederzuverwenden.

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

Löschen des Inhalts von OutputFileDatasetConfig, wenn er nicht mehr benötigt wird

Zwischendaten, die mit OutputFileDatasetConfig geschrieben werden, werden von Azure nicht automatisch gelöscht. Um Speichergebühren für große Mengen nicht benötigter Daten zu vermeiden, empfiehlt es sich, einen der folgenden Schritte auszuführen:

Achtung

Löschen Sie Zwischendaten erst 30 Tage nach dem letzten Änderungsdatum der Daten. Werden die Daten früher gelöscht, kann dies dazu führen, dass die Pipeline fehlschlägt, da die Pipeline davon ausgeht, dass die Zwischendaten in einem Zeitraum von 30 Tagen für die Wiederverwendung zur Verfügung stehen.

  • Programmgesteuertes Löschen von Zwischendaten am Ende eines Pipelineauftrags, wenn sie nicht mehr benötigt werden
  • Verwenden von Blobspeicher mit einer kurzfristigen Speicherrichtlinie für Zwischendaten (siehe Optimieren der Kosten durch Automatisieren der Azure Blob Storage-Zugriffsebenen). Diese Richtlinie kann nur auf den nicht standardmäßigen Datenspeicher eines Arbeitsbereichs festgelegt werden. Verwenden Sie OutputFileDatasetConfig zum Exportieren von Zwischendaten in einen anderen Datenspeicher, der nicht der Standardspeicher ist.
    # 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()
    
  • Regelmäßiges Überprüfen und Löschen nicht mehr benötigter Daten

Weitere Informationen finden Sie unter Planen und Verwalten von Kosten für Azure Machine Learning.

Nächste Schritte