Entrenamiento de modelos con la CLI (v2) (versión preliminar)

La CLI de Azure Machine Learning (v2) es una extensión de la CLI de Azure que permite acelerar el entrenamiento de modelos durante el escalado vertical y horizontal de un proceso de Azure, así como auditar el ciclo de vida y realizar su seguimiento.

El entrenamiento de un modelo de aprendizaje automático habitualmente es un proceso iterativo. Las herramientas modernas facilitan más que nunca el entrenamiento de modelos mayor en más datos es con más rapidez. Los procesos manuales que anteriormente eran tediosos, como el ajuste de hiperparámetros, e incluso la selección de algoritmos, a menudo se automatizan. Con la CLI de Azure Machine Learning (v2) puede realizar un seguimiento de los trabajos (y modelos) en un área de trabajo con barridos de hiperparámetros, realizar un escalado vertical de proceso de Azure de alto rendimiento y un escalado horizontal mediante el entrenamiento distribuido.

Importante

Esta característica actualmente está en su versión preliminar pública. Esta versión preliminar se ofrece sin Acuerdo de Nivel de Servicio y no se recomienda para cargas de trabajo de producción. Es posible que algunas características no sean compatibles o que tengan sus funcionalidades limitadas. Para más información, consulte Términos de uso complementarios de las Versiones Preliminares de Microsoft Azure.

Prerrequisitos

Sugerencia

Para un entorno de desarrollo completo con validación de esquemas y autocompletar para los YAML de trabajo, use Visual Studio Code y la extensión Azure Machine Learning.

Clonación del repositorio de ejemplos

Para ejecutar los ejemplos de entrenamiento, primero clone el repositorio de ejemplos y cambie al directorio cli:

git clone --depth 1 https://github.com/Azure/azureml-examples
cd azureml-examples/cli

Tenga en cuenta al utilizar --depth 1 solamente se clona la confirmación más reciente en el repositorio, lo cual reduce el tiempo para completar la operación.

Creación del proceso

Puede crear un clúster de proceso de Azure Machine Learning desde la línea de comandos. Por ejemplo, los siguientes comandos crearán un clúster denominado cpu-cluster y otro denominado gpu-cluster.

az ml compute create -n cpu-cluster --type amlcompute --min-instances 0 --max-instances 8
az ml compute create -n gpu-cluster --type amlcompute --min-instances 0 --max-instances 4 --size Standard_NC12

No se le cobrará por el proceso en este momento, ya que cpu-cluster y gpu-cluster permanecerán en 0 nodos hasta que se envíe un trabajo. Más información sobre cómo administrar y optimizar el costo de AmlCompute.

En los siguientes trabajos de ejemplo de este artículo se usa cpu-cluster o gpu-cluster. Ajuste estos nombres en los trabajos de ejemplo de este artículo según sea necesario para el nombre de el clúster o los clústeres. Use az ml compute create -h para más detalles sobre las opciones de creación de proceso.

Hola a todos

En el caso de la CLI de Azure Machine Learning (v2), los trabajos se crean en formato YAML. Un trabajo agrega:

  • Qué ejecutar
  • Cómo ejecutarlo
  • Dónde ejecutarlo

El trabajo "hola mundo" tiene los tres elementos:

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: echo "hello world"
environment:
  image: python:latest
compute: azureml:cpu-cluster

Advertencia

Python debe instalarse en el entorno que se usa para los trabajos. Ejecute apt-get update -y && apt-get install python3 -y en el Dockerfile para instalarlo, si es necesario, o derive desde una imagen base con Python ya instalado.

Sugerencia

Los ejemplos $schema: permiten la validación de esquemas y la función de autocompletar si se han creado archivos YAML en VSCode con la extensión Azure Machine Learning.

Que puede ejecutar:

az ml job create -f jobs/basics/hello-world.yml --web

Sugerencia

El parámetro --web intentará abrir el trabajo en Estudio de Azure Machine Learning mediante el explorador web predeterminado. El parámetro--stream se puede usar para transmitir registros a la consola y bloquear más comandos.

Invalidación de valores al crear o actualizar

Los valores de especificación de trabajo YAML se pueden invalidar mediante --set al crear o actualizar un trabajo. Por ejemplo:

az ml job create -f jobs/basics/hello-world.yml \
  --set environment.image="python:3.8" \
  --web

Nombres de los trabajos

La mayoría de los comandos az ml job, exceptocreate y list requieren --name/-n, que es el nombre de un trabajo o "Id. de ejecución" en Studio. No debe establecer directamente la propiedadnamede un trabajo durante la creación, ya que debe ser única por área de trabajo. Azure Machine Learning genera un GUID aleatorio para el nombre del trabajo si no se establece, que se puede obtener a partir de la salida de la creación del trabajo en la CLI o copiando la propiedad "Id. de ejecución" en las API de Studio y MLflow.

Para automatizar trabajos en scripts y flujos de CI/CD, puede capturar el nombre de un trabajo cuando se crea consultando y quitando la salida agregando --query name -o tsv. Los detalles variarán según el shell, pero para Bash:

run_id=$(az ml job create -f jobs/basics/hello-world.yml --query name -o tsv)

A continuación, utilice $run_id en comandos posteriores comoupdate, show, o stream:

az ml job show -n $run_id --web

Organizar los trabajos

Para organizar los trabajos, puede establecer un nombre para mostrar, un nombre de experimento, una descripción y etiquetas. Las descripciones admiten la sintaxis de Markdown en Studio. Estas propiedades se pueden modificar después de crear un trabajo. Un ejemplo completo:

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: echo "hello world"
environment:
  image: python:latest
compute: azureml:cpu-cluster
tags:
  hello: world
display_name: hello-world-example
experiment_name: hello-world-example
description: |
  # Azure Machine Learning "hello world" job

  This is a "hello world" job running in the cloud via Azure Machine Learning!

  ## Description

  Markdown is supported in the studio for job descriptions! You can edit the description there or via CLI.

Puede ejecutar este trabajo, donde estas propiedades estarán visibles inmediatamente en Studio:

az ml job create -f jobs/basics/hello-world-org.yml --web

Puede utilizar --set para actualizar los valores que se pueden modificar después de crear el trabajo:

az ml job update -n $run_id --set \
  display_name="updated display name" \
  experiment_name="updated experiment name" \
  description="updated description"  \
  tags.hello="updated tag"

Variables de entorno

Puede establecer variables de entorno para utilizarlas en el trabajo:

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: echo $hello_env_var
environment:
  image: python:latest
compute: azureml:cpu-cluster
environment_variables:
  hello_env_var: "hello world"

Puede ejecutar este trabajo:

az ml job create -f jobs/basics/hello-world-env-var.yml --web

Advertencia

Debería utilizar inputs para parametrizar los argumentos en command. Consulte entradas y salidas.

Seguimiento de modelos y código fuente

Los modelos de aprendizaje automático de producción deben ser auditables (si no se pueden reproducir). Es fundamental realizar un seguimiento del código fuente de un modelo determinado. Azure Machine Learning toma una instantánea del código fuente y la mantiene con el trabajo. Además, el repositorio de origen y la confirmación se mantienen si está ejecutando trabajos desde un repositorio Git.

Sugerencia

Si sigue y ejecuta desde el repositorio de ejemplos, puede ver el repositorio de origen y confirmar en Studio en cualquiera de los trabajos ejecutados hasta ahora.

Puede especificar la code.local_pathclave en un trabajo con el valor como ruta de acceso a un directorio de código fuente. Se toma y carga una instantánea del directorio con el trabajo. El contenido del directorio está disponible directamente desde el directorio de trabajo del trabajo.

Advertencia

El código fuente no debe incluir entradas de datos grandes para el entrenamiento del modelo. En su lugar, utilice las entradas de datos. Puede usar un .gitignorearchivo en el directorio de código fuente para excluir archivos de la instantánea. Los límites para el tamaño de instantánea son 300 MB o 2000 archivos.

Echemos un vistazo a un trabajo que especifica código:

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: >-
  pip install mlflow azureml-mlflow
  &&
  python hello-mlflow.py
code:
  local_path: src
environment:
  image: python:3.8
compute: azureml:cpu-cluster

El script de Python está en el directorio de código fuente local. A continuación, el comando python invoca para ejecutar el script. S puede aplicar el mismo patrón a otros lenguajes de programación.

Advertencia

La familia de trabajos "hello" que se muestra en este artículo tiene fines de demostración y no sigue necesariamente los procedimientos recomendados. No se recomienda usar &&o similar para ejecutar muchos comandos en una secuencia; en su lugar, considere la posibilidad de escribir los comandos en un archivo de script en el directorio de código fuente e invocar el script en su command. No se recomienda instalar dependencias en command, como se muestra anteriormente a través de pip install; en su lugar, todas las dependencias de trabajo deben especificarse como parte del entorno. Consulte Cómo administrar de entornos con la CLI (v2) para obtener información adicional.

Seguimiento de modelos con MLflow

Al iterar en modelos, los científicos de datos deben poder realizar un seguimiento de los parámetros del modelo y las métricas de entrenamiento. Azure Machine Learning se integra con el seguimiento de MLflow para habilitar el registro de modelos, artefactos, métricas y parámetros en un trabajo. Para usar MLflow en los scripts de Python, agregue y import mlflow llame a mlflow.log_*o las API mlflow.autolog()en el código de entrenamiento.

Advertencia

Los paquetes mlflowy azureml-mlflowdeben instalarse en el entorno de Python para las características de seguimiento de MLflow.

Sugerencia

La llamada mlflow.autolog() es compatible con muchos marcos populares y se encarga de la mayoría del registro.

Echemos un vistazo al script de Python invocado en el trabajo anterior que usa mlflowpara registrar un parámetro, una métrica y un artefacto:

# imports
import os
import mlflow

from random import random

# define functions
def main():
    mlflow.log_param("hello_param", "world")
    mlflow.log_metric("hello_metric", random())
    os.system(f"echo 'hello world' > helloworld.txt")
    mlflow.log_artifact("helloworld.txt")


# run functions
if __name__ == "__main__":
    # run main function
    main()

Puede ejecutar este trabajo en la nube a través de Azure Machine Learning, donde se realiza un seguimiento y se puede auditar:

az ml job create -f jobs/basics/hello-mlflow.yml --web

Consulta de métricas con MLflow

Después de ejecutar trabajos, es posible que quiera consultar los resultados de ejecución de los trabajos y sus métricas registradas. Python es más adecuado para esta tarea que una CLI. Puede consultar las ejecuciones y sus métricas a través de mlflow y cargar en objetos conocidos como Dataframes de Pandas para su análisis.

En primer lugar, recupere el URI de seguimiento de MLflow para el área de trabajo Azure Machine Learning:

az ml workspace show --query mlflow_tracking_uri -o tsv

Use la salida de este comando en mlflow.set_tracking_uri(<YOUR_TRACKING_URI>)desde un entorno de Python con MLflow importado. Las llamadas de MLflow ahora se corresponderán con los trabajos del área de trabajo de Azure Machine Learning.

Entradas y salidas

Los trabajos suelen tener entradas y salidas. Las entradas pueden ser parámetros de modelo, que se pueden volver a calcular para la optimización de hiperparámetros, o entradas de datos en la nube que se montan o descargan en el destino de proceso. Las salidas (omitiendo las métricas) son artefactos que se pueden escribir o copiar en las salidas predeterminadas o en una salida de datos con nombre.

Entradas literales

Las entradas literales se resuelven directamente en el comando. Puede modificar nuestro trabajo "hola mundo" para usar entradas literales:

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: >-
  echo ${{inputs.hello_string}}
  &&
  echo ${{inputs.hello_number}}
environment:
  image: python:latest
inputs:
  hello_string: "hello world"
  hello_number: 42
compute: azureml:cpu-cluster

Puede ejecutar este trabajo:

az ml job create -f jobs/basics/hello-world-input.yml --web

Puede usar --set para invalidar las entradas:

az ml job create -f jobs/basics/hello-world-input.yml --set \
  inputs.hello_string="hello there" \
  inputs.hello_number=24 \
  --web

Las entradas literales a los trabajos se pueden convertir en entradas de espacio de búsqueda para realizar barridos de hiperparámetros en el entrenamiento del modelo.

Entradas de espacio de búsqueda

Para un trabajo de barrido, puede especificar un espacio de búsqueda para las entradas literales entre las que elegir. Para obtener toda la gama de opciones para las entradas de espacio de búsqueda, consulte la referencia de sintaxis de YAML del trabajo de barrido.

Advertencia

Los trabajos de barrido no se admiten actualmente en los trabajos de canalización.

Vamos a demostrar el concepto con un script de Python simple que toma argumentos y registra una métrica aleatoria:

# imports
import os
import mlflow
import argparse

from random import random

# define functions
def main(args):
    # print inputs
    print(f"A: {args.A}")
    print(f"B: {args.B}")
    print(f"C: {args.C}")

    # log inputs as parameters
    mlflow.log_param("A", args.A)
    mlflow.log_param("B", args.B)
    mlflow.log_param("C", args.C)

    # log a random metric
    mlflow.log_metric("random_metric", random())


def parse_args():
    # setup arg parser
    parser = argparse.ArgumentParser()

    # add arguments
    parser.add_argument("--A", type=float, default=0.5)
    parser.add_argument("--B", type=str, default="hello world")
    parser.add_argument("--C", type=float, default=1.0)

    # parse args
    args = parser.parse_args()

    # return args
    return args


# run script
if __name__ == "__main__":
    # parse args
    args = parse_args()

    # run main function
    main(args)

Y crear un trabajo de barrido correspondiente:

$schema: https://azuremlschemas.azureedge.net/latest/sweepJob.schema.json
type: sweep
trial:
  command: >-
    pip install mlflow azureml-mlflow
    &&
    python hello-sweep.py
    --A ${{inputs.A}}
    --B ${{search_space.B}}
    --C ${{search_space.C}}
  code:
    local_path: src
  environment:
    image: python:3.8
inputs:
  A: 0.5
compute: azureml:cpu-cluster
sampling_algorithm: random
search_space:
  B:
    type: choice
    values: ["hello", "world", "hello world"]
  C:
    type: uniform
    min_value: 0.1
    max_value: 1.0
objective:
  goal: minimize
  primary_metric: random_metric
limits:
  max_total_trials: 4
  max_concurrent_trials: 2
  timeout: 3600
display_name: hello-sweep-example
experiment_name: hello-sweep-example
description: Hello sweep job example.

Y ejecutarlo:

az ml job create -f jobs/basics/hello-sweep.yml --web

Entradas de datos

Las entradas de datos se resuelven en una ruta de acceso en el sistema de archivos local del proceso de trabajo. Vamos a demostrar con el conjunto de datos iris clásico, que se hospeda públicamente en un contenedor de blobs en https://azuremlexamples.blob.core.windows.net/datasets/iris.csv.

Puede crear un script de Python que tome la ruta de acceso al archivo CSV iris como argumento, lo lea en un dataframe, imprima las cinco primeras líneas y lo guarde en el directorio outputs.

# imports
import os
import argparse

import pandas as pd

# define functions
def main(args):
    # read in data
    df = pd.read_csv(args.iris_csv)

    # print first 5 lines
    print(df.head())

    # ensure outputs directory exists
    os.makedirs("outputs", exist_ok=True)

    # save data to outputs
    df.to_csv("outputs/iris.csv", index=False)


def parse_args():
    # setup arg parser
    parser = argparse.ArgumentParser()

    # add arguments
    parser.add_argument("--iris-csv", type=str)

    # parse args
    args = parser.parse_args()

    # return args
    return args


# run script
if __name__ == "__main__":
    # parse args
    args = parse_args()

    # run main function
    main(args)

Se pueden especificar entradas de URI de almacenamiento de Azure, que montarán o descargarán datos en el sistema de archivos local. Puede especificar un único archivo:

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: >-
  echo "--iris-csv: ${{inputs.iris_csv}}"
  &&
  pip install pandas
  &&
  python hello-iris.py
  --iris-csv ${{inputs.iris_csv}}
code:
  local_path: src
inputs:
  iris_csv: 
    file: https://azuremlexamples.blob.core.windows.net/datasets/iris.csv
environment:
  image: python:latest
compute: azureml:cpu-cluster

Y ejecute:

az ml job create -f jobs/basics/hello-iris-file.yml --web

O bien especifique una carpeta completa:

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: >-
  ls ${{inputs.data_dir}}
  &&
  echo "--iris-csv: ${{inputs.data_dir}}/iris.csv"
  &&
  pip install pandas
  &&
  python hello-iris.py
  --iris-csv ${{inputs.data_dir}}/iris.csv
code:
  local_path: src
inputs:
  data_dir: 
    folder: wasbs://datasets@azuremlexamples.blob.core.windows.net/
environment:
  image: python:latest
compute: azureml:cpu-cluster

Y ejecute:

az ml job create -f jobs/basics/hello-iris-folder.yml --web

Datos privados

Para los datos privados de Azure Blob Storage o Azure Data Lake Storage conectados a Azure Machine Learning a través de un almacén de datos, puede usar las URI de Azure Machine Learning del formato azureml://datastores/<DATASTORE_NAME>/paths/<PATH_TO_DATA>para introducir los datos. Por ejemplo, si carga iris CSV en un directorio denominado /example-data/en el contenedor de blobs correspondiente al almacén de datos denominado workspaceblobstore, puede modificar un trabajo anterior para usar el archivo en el almacén de datos:

Advertencia

Si no ha copiado iris CSV en la misma ubicación de workspaceblobstore, se producirá un error al ejecutar estos trabajos.

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: >-
  echo "--iris-csv: ${{inputs.iris_csv}}"
  &&
  pip install pandas
  &&
  python hello-iris.py
  --iris-csv ${{inputs.iris_csv}}
code:
  local_path: src
inputs:
  iris_csv: 
    file: azureml://datastores/workspaceblobstore/paths/example-data/iris.csv
environment:
  image: python:latest
compute: azureml:cpu-cluster

O todo el directorio:

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: >-
  ls ${{inputs.data_dir}}
  &&
  echo "--iris-csv: ${{inputs.data_dir}}/iris.csv"
  &&
  pip install pandas
  &&
  python hello-iris.py
  --iris-csv ${{inputs.data_dir}}/iris.csv
code:
  local_path: src
inputs:
  data_dir: 
    folder: azureml://datastores/workspaceblobstore/paths/example-data/
    mode: rw_mount
environment:
  image: python:latest
compute: azureml:cpu-cluster

Salidas predeterminadas

Los directorios ./outputs y ./logs reciben un tratamiento especial por parte de Azure Machine Learning. Si escribe archivos en estos directorios durante el trabajo, dichos archivos se cargarán en el historial de ejecución del trabajo, con el fin de que pueda seguir accediendo a ellos una vez completado el trabajo. La carpeta ./outputs se carga al final del trabajo, mientras que los archivos escritos en ./logs se cargan en tiempo real. Use la última opción si desea hacer streaming de los registros durante el trabajo, como por ejemplo los registros de TensorBoard.

Puede modificar el trabajo "hola mundo" para que se pueda generar en un archivo en el directorio de salidas predeterminado en lugar de imprimir en stdout:

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: echo "hello world" > ./outputs/helloworld.txt
environment:
  image: python:latest
compute: azureml:cpu-cluster

Puede ejecutar este trabajo:

az ml job create -f jobs/basics/hello-world-output.yml --web

Y descargue los registros, donde helloworld.txt estarán presentes en el directorio<RUN_ID>/outputs/:

az ml job download -n $run_id

Salidas de datos

Puede especificar salidas de datos con nombre. Esto creará un directorio en el almacén de datos predeterminado que se montará como lectura o escritura de forma predeterminada.

Puede modificar el trabajo "hola mundo" anterior para escribir en una salida de datos con nombre:

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: echo "hello world" > ${{outputs.hello_output}}/helloworld.txt
outputs:
  hello_output:
environment:
  image: python
compute: azureml:cpu-cluster

Canalizaciones «Hola»

Los trabajos de canalización pueden ejecutar varios trabajos en paralelo o en secuencia. Si hay dependencias de entrada y salida entre los pasos de una canalización, el paso dependiente se ejecutará una vez completado el otro.

Puede dividir un trabajo de "hola mundo" en dos trabajos:

$schema: https://azuremlschemas.azureedge.net/latest/pipelineJob.schema.json
type: pipeline
jobs:
  hello_job:
    command: echo "hello"
    environment:
      image: python:latest
    compute: azureml:cpu-cluster
  world_job:
    command: echo "world"
    environment:
      image: python
    compute: azureml:cpu-cluster

Y ejecutarlo:

az ml job create -f jobs/basics/hello-pipeline.yml --web

Los trabajos «hola» y «mundo» respectivamente se ejecutarán en paralelo si el destino de proceso tiene los recursos disponibles para hacerlo.

Para pasar datos entre los pasos de una canalización, defina una salida de datos en el trabajo «hola» y una entrada correspondiente en el trabajo «mundo», que hace referencia a la salida del anterior:

$schema: https://azuremlschemas.azureedge.net/latest/pipelineJob.schema.json
type: pipeline
jobs:
  hello_job:
    command: echo "hello" && echo "world" > ${{outputs.world_output}}/world.txt
    environment:
      image: python:latest
    compute: azureml:cpu-cluster
    outputs:
      world_output:
  world_job:
    command: cat ${{inputs.world_input}}/world.txt
    environment:
      image: python:latest
    compute: azureml:cpu-cluster
    inputs:
      world_input: ${{jobs.hello_job.outputs.world_output}}

Y ejecutarlo:

az ml job create -f jobs/basics/hello-pipeline-io.yml --web

Esta vez, el trabajo «mundo» se ejecutará después de que se complete el trabajo «hola».

Para evitar la duplicación de la configuración común entre los trabajos de una canalización, puede establecerlos fuera de los trabajos:

$schema: https://azuremlschemas.azureedge.net/latest/pipelineJob.schema.json
type: pipeline
compute: azureml:cpu-cluster
settings:
  environment:
    image: python:latest
jobs:
  hello_job:
    command: echo "hello"
  world_job:
    command: echo "world"

Puede ejecutar este trabajo:

az ml job create -f jobs/basics/hello-pipeline-settings.yml --web

La configuración correspondiente en un trabajo individual invalidará la configuración común de un trabajo de canalización. Los conceptos hasta ahora se pueden combinar en un trabajo de canalización de tres pasos con los trabajos «A», «B» y «C». El trabajo «C» tiene una dependencia de datos en el trabajo «B», mientras que el trabajo «A» se puede ejecutar de forma independiente. El trabajo «A» también usará un entorno establecido individualmente y enlazará una de sus entradas a una entrada de trabajo de canalización de nivel superior:

$schema: https://azuremlschemas.azureedge.net/latest/pipelineJob.schema.json
type: pipeline
compute: azureml:cpu-cluster
settings:
  environment:
    image: python:latest
inputs:
  hello_string_top_level_input: "hello world"
jobs:
  A:
    command: echo hello ${{inputs.hello_string}}
    environment:
      image: python:3.9
    inputs:
      hello_string: ${{inputs.hello_string_top_level_input}}
  B:
    command: echo "world" >> ${{outputs.world_output}}/world.txt
    outputs:
      world_output:
  C:
    command: echo ${{inputs.world_input}}/world.txt
    inputs:
      world_input: ${{jobs.B.outputs.world_output}}

Puede ejecutar este trabajo:

az ml job create -f jobs/basics/hello-pipeline-abc.yml --web

Entrenamiento de un modelo

En este momento, todavía no se ha entrenado un modelo. Vamos a agregar código sklearna un script de Python con seguimiento de MLflow para entrenar un modelo en iris CSV:

# imports
import os
import mlflow
import argparse

import pandas as pd

from sklearn.svm import SVC
from sklearn.model_selection import train_test_split

# define functions
def main(args):
    # enable auto logging
    mlflow.autolog()

    # setup parameters
    params = {
        "C": args.C,
        "kernel": args.kernel,
        "degree": args.degree,
        "gamma": args.gamma,
        "coef0": args.coef0,
        "shrinking": args.shrinking,
        "probability": args.probability,
        "tol": args.tol,
        "cache_size": args.cache_size,
        "class_weight": args.class_weight,
        "verbose": args.verbose,
        "max_iter": args.max_iter,
        "decision_function_shape": args.decision_function_shape,
        "break_ties": args.break_ties,
        "random_state": args.random_state,
    }

    # read in data
    df = pd.read_csv(args.iris_csv)

    # process data
    X_train, X_test, y_train, y_test = process_data(df, args.random_state)

    # train model
    model = train_model(params, X_train, X_test, y_train, y_test)


def process_data(df, random_state):
    # split dataframe into X and y
    X = df.drop(["species"], axis=1)
    y = df["species"]

    # train/test split
    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.2, random_state=random_state
    )

    # return split data
    return X_train, X_test, y_train, y_test


def train_model(params, X_train, X_test, y_train, y_test):
    # train model
    model = SVC(**params)
    model = model.fit(X_train, y_train)

    # return model
    return model


def parse_args():
    # setup arg parser
    parser = argparse.ArgumentParser()

    # add arguments
    parser.add_argument("--iris-csv", type=str)
    parser.add_argument("--C", type=float, default=1.0)
    parser.add_argument("--kernel", type=str, default="rbf")
    parser.add_argument("--degree", type=int, default=3)
    parser.add_argument("--gamma", type=str, default="scale")
    parser.add_argument("--coef0", type=float, default=0)
    parser.add_argument("--shrinking", type=bool, default=False)
    parser.add_argument("--probability", type=bool, default=False)
    parser.add_argument("--tol", type=float, default=1e-3)
    parser.add_argument("--cache_size", type=float, default=1024)
    parser.add_argument("--class_weight", type=dict, default=None)
    parser.add_argument("--verbose", type=bool, default=False)
    parser.add_argument("--max_iter", type=int, default=-1)
    parser.add_argument("--decision_function_shape", type=str, default="ovr")
    parser.add_argument("--break_ties", type=bool, default=False)
    parser.add_argument("--random_state", type=int, default=42)

    # parse args
    args = parser.parse_args()

    # return args
    return args


# run script
if __name__ == "__main__":
    # parse args
    args = parse_args()

    # run main function
    main(args)

El marco scikit-learn es compatible con MLflow para el registro automático, por lo que una sola llamada mlflow.autolog()en el script registrará todos los parámetros del modelo, las métricas de entrenamiento, los artefactos del modelo y algunos artefactos adicionales (en este caso, una imagen de matriz de confusión).

Para ejecutar esto en la nube, especifique como un trabajo:

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
code: 
  local_path: src
command: >-
  python main.py 
  --iris-csv ${{inputs.iris_csv}}
  --C ${{inputs.C}}
  --kernel ${{inputs.kernel}}
  --coef0 ${{inputs.coef0}}
inputs:
  iris_csv: 
    file: wasbs://datasets@azuremlexamples.blob.core.windows.net/iris.csv
  C: 0.8
  kernel: "rbf"
  coef0: 0.1
environment: azureml:AzureML-sklearn-0.24-ubuntu18.04-py37-cpu:9
compute: azureml:cpu-cluster
display_name: sklearn-iris-example
experiment_name: sklearn-iris-example
description: Train a scikit-learn SVM on the Iris dataset.

Y ejecutarlo:

az ml job create -f jobs/single-step/scikit-learn/iris/job.yml --web

Para registrar un modelo, puede descargar las salidas y crear un modelo desde el directorio local:

az ml job download -n $run_id
az ml model create -n sklearn-iris-example -l $run_id/model/

Hiperparámetros de barrido

Puede modificar el trabajo previo para barrer los hiperparámetros:

$schema: https://azuremlschemas.azureedge.net/latest/sweepJob.schema.json
type: sweep
trial:
  code: 
    local_path: src
  command: >-
    python main.py 
    --iris-csv ${{inputs.iris_csv}}
    --C ${{search_space.C}}
    --kernel ${{search_space.kernel}}
    --coef0 ${{search_space.coef0}}
  environment: azureml:AzureML-sklearn-0.24-ubuntu18.04-py37-cpu:9
inputs:
  iris_csv: 
    file: wasbs://datasets@azuremlexamples.blob.core.windows.net/iris.csv
compute: azureml:cpu-cluster
sampling_algorithm: random
search_space:
  C:
    type: uniform
    min_value: 0.5
    max_value: 0.9
  kernel:
    type: choice
    values: ["rbf", "linear", "poly"]
  coef0:
    type: uniform
    min_value: 0.1
    max_value: 1
objective:
  goal: minimize
  primary_metric: training_f1_score
limits:
  max_total_trials: 20
  max_concurrent_trials: 10
  timeout: 7200
display_name: sklearn-iris-sweep-example
experiment_name: sklearn-iris-sweep-example
description: Sweep hyperparemeters for training a scikit-learn SVM on the Iris dataset.

Y ejecutarlo:

az ml job create -f jobs/single-step/scikit-learn/iris/job-sweep.yml --web

Sugerencia

Compruebe la pestaña «Ejecuciones secundarias» en Studio para supervisar el progreso y ver los gráficos de parámetros.

Para obtener más opciones de barrido, consulte la referencia de sintaxis DE YAML del trabajo de barrido.

Entrenamiento distribuido

Azure Machine Learning admite el entrenamiento distribuido basado en PyTorch, TensorFlow y MPI. Consulte la sección distribuida de la referencia de sintaxis DE YAML del trabajo de comandos para obtener más información.

Por ejemplo, puede entrenar una red neuronal convolucional (CNN) en el conjunto de datos CIFAR-10 mediante PyTorch distribuido. El script completo está disponible en el repositorio de ejemplos.

El conjunto de datos CIFAR-10 en torchvision espera como entrada un directorio que contiene el directorio cifar-10-batches-py. Puede descargar el origen comprimido y extraerlo en un directorio local:

mkdir data
wget "https://azuremlexamples.blob.core.windows.net/datasets/cifar-10-python.tar.gz"
tar -xvzf cifar-10-python.tar.gz -C data

A continuación, cree un conjunto de datos de Azure Machine Learning desde el directorio local, que se cargará en el almacén de datos predeterminado:

az ml dataset create --name cifar-10-example --version 1 --set local_path=data

Opcionalmente, quite el archivo y el directorio local:

rm cifar-10-python.tar.gz
rm -r data

Se puede hacer referencia a conjuntos de datos (solo archivo) en un trabajo mediante la datasetclave de una entrada de datos. El formato es azureml:<DATASET_NAME>:<DATASET_VERSION>, por lo que para el conjunto de datos CIFAR-10 que acaba de crear, es azureml:cifar-10-example:1.

Con el conjunto de datos en su lugar, puede crear un trabajo de PyTorch distribuido para entrenar nuestro modelo:

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
code: 
  local_path: src
command: >-
  python train.py 
  --epochs ${{inputs.epochs}}
  --learning-rate ${{inputs.learning_rate}}
  --data-dir ${{inputs.cifar}}
inputs:
  epochs: 1
  learning_rate: 0.2
  cifar:
    dataset: azureml:cifar-10-example:1
environment: azureml:AzureML-pytorch-1.9-ubuntu18.04-py37-cuda11-gpu:6
compute: azureml:gpu-cluster
distribution:
  type: pytorch 
  process_count_per_instance: 2
resources:
  instance_count: 2
display_name: pytorch-cifar-distributed-example
experiment_name: pytorch-cifar-distributed-example
description: Train a basic convolutional neural network (CNN) with PyTorch on the CIFAR-10 dataset, distributed via PyTorch.

Y ejecutarlo:

az ml job create -f jobs/single-step/pytorch/cifar-distributed/job.yml --web

Creación de una canalización de entrenamiento

El ejemplo CIFAR-10 anterior se traduce bien en un trabajo de canalización. El trabajo anterior se puede dividir en tres trabajos para la orquestación en una canalización:

  • «get-data» para ejecutar un script de Bash para descargar y extraer cifar-10-batches-py
  • «train-model» para tomar los datos y entrenar un modelo con PyTorch distribuido
  • «eval-model» para tomar los datos y el modelo entrenado y evaluar la precisión

Tanto «train-model» como «eval-model» tendrán una dependencia en la salida del trabajo «get-data». Además, «eval-model» tendrá una dependencia en la salida del trabajo «train-model». Por lo tanto, los tres trabajos se ejecutarán secuencialmente.

Puede organizar estos tres trabajos dentro de un trabajo de canalización:

$schema: https://azuremlschemas.azureedge.net/latest/pipelineJob.schema.json
type: pipeline
display_name: cifar-10-pipeline-example
experiment_name: cifar-10-pipeline-example
jobs:
  get-data:
    command: bash main.sh ${{outputs.cifar}}
    code:
      local_path: src/get-data
    environment:
      image: python:latest
    compute: azureml:cpu-cluster
    outputs:
      cifar:
  train-model:
    command: >-
      python main.py
      --data-dir ${{inputs.cifar}}
      --epochs ${{inputs.epochs}}
      --model-dir ${{outputs.model_dir}}
    code:
      local_path: src/train-model
    inputs:
      epochs: 1
      cifar: ${{jobs.get-data.outputs.cifar}}
    outputs:
      model_dir:
    environment: azureml:AzureML-pytorch-1.9-ubuntu18.04-py37-cuda11-gpu:6
    compute: azureml:gpu-cluster
    distribution:
      type: pytorch
      process_count_per_instance: 2
    resources:
      instance_count: 2
  eval-model:
    command: >-
      python main.py
      --data-dir ${{inputs.cifar}}
      --model-dir ${{inputs.model_dir}}/model
    code:
      local_path: src/eval-model
    environment: azureml:AzureML-pytorch-1.9-ubuntu18.04-py37-cuda11-gpu:6
    compute: azureml:gpu-cluster
    distribution:
      type: pytorch
      process_count_per_instance: 2
    resources:
      instance_count: 1
    inputs:
      cifar: ${{jobs.get-data.outputs.cifar}}
      model_dir: ${{jobs.train-model.outputs.model_dir}}

Y ejecute:

az ml job create -f jobs/pipelines/cifar-10/job.yml --web

Las canalizaciones también se pueden escribir mediante componentes reutilizables. Para obtener información adicional, consulte Creación y ejecución de canalizaciones de aprendizaje automático mediante componentes con la CLI de Azure Machine Learning (versión preliminar).

Pasos siguientes