Cómo hacer operativa una canalización de entrenamiento con puntos de conexión por lotes

SE APLICA A:Extensión ML de la CLI de Azure v2 (actual)SDK de Python azure-ai-ml v2 (actual)

En este artículo, aprenderás a poner en funcionamiento una canalización de entrenamiento en un punto de conexión por lotes. La canalización usa varios componentes (o pasos) que incluyen el entrenamiento del modelo, el preprocesamiento de datos y la evaluación del modelo.

Aprenderá lo siguiente:

  • Crear y probar de una canalización de entrenamiento
  • Implementar la canalización en un punto de conexión por lotes
  • Modificar la canalización y creación de una nueva implementación en el mismo punto de conexión
  • Prueba de la nueva implementación y su establecimiento como implementación predeterminada

Acerca de este ejemplo

En este ejemplo se implementa una canalización de entrenamiento que toma datos de entrenamiento de entrada (etiquetados) y genera un modelo predictivo, junto con los resultados de evaluación y las transformaciones aplicadas durante el preprocesamiento. La canalización utilizará datos tabulares del Conjunto de datos de enfermedades cardíacas de UCI para entrenar un modelo XGBoost. Usamos un componente de preprocesamiento de datos para preprocesar los datos antes de enviarlos al componente de capacitación para ajustar y evaluar el modelo.

Una visualización de la canalización es la siguiente:

Captura de pantalla de la canalización que muestra los componentes de preprocesamiento y entrenamiento.

El ejemplo de este artículo se basa en ejemplos de código incluidos en el repositorio azureml-examples. Para ejecutar los comandos de forma local sin tener que copiar/pegar YAML y otros archivos, primero clona el repositorio y luego cambia los directorios a la carpeta:

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

Los archivos de este ejemplo están en:

cd endpoints/batch/deploy-pipelines/training-with-components

Sigue estos pasos en los cuadernos de Jupyter Notebooks

Puedes seguir la versión SDK de Python de este ejemplo abriendo el cuaderno sdk-deploy-and-test.ipynb en el repositorio clonado.

Prerrequisitos

Antes de seguir los pasos de este artículo, asegúrese de que tiene los siguientes requisitos previos:

  • Suscripción a Azure. Si no tiene una suscripción de Azure, cree una cuenta gratuita antes de empezar. Pruebe la versión gratuita o de pago de Azure Machine Learning.

  • Un área de trabajo de Azure Machine Learning. Si no tiene una, siga los pasos descritos en el artículo Administración de áreas de trabajo de Azure Machine Learning para crear una.

  • Asegúrese de tener los permisos siguientes en el área de trabajo:

    • Creación o administración de implementaciones y puntos de conexión por lotes: usar un rol de Propietario, Colaborador o Personalizado que permita Microsoft.MachineLearningServices/workspaces/batchEndpoints/*.

    • Creación de implementaciones de ARM en el grupo de recursos del área de trabajo: use un rol Propietario, Colaborador o Personalizado que permita Microsoft.Resources/deployments/write en el grupo de recursos donde se implemente el área de trabajo.

  • Debe instalar el siguiente software para trabajar con Azure Machine Learning:

    La CLI de Azure y la mlextensión para Azure Machine Learning.

    az extension add -n ml
    

    Nota

    Las implementaciones de componentes de canalización para puntos de conexión de Batch se introdujeron en la versión 2.7 de la extensión ml para la CLI de Azure. Use az extension update --name ml para obtener la última versión.

Conexión con su área de trabajo

El área de trabajo es el recurso de nivel superior para Azure Machine Learning, que proporciona un lugar centralizado para trabajar con todos los artefactos que crea al usar Azure Machine Learning. En esta sección, nos conectaremos al área de trabajo en la que realizará las tareas de implementación.

Pasa los valores del id. de suscripción, el área de trabajo, la ubicación y el grupo de recursos en el código siguiente:

az account set --subscription <subscription>
az configure --defaults workspace=<workspace> group=<resource-group> location=<location>

Crear el componente de canalización de entrenamiento

En esta sección, crearemos todos los recursos necesarios para nuestra canalización de entrenamiento. Comenzaremos creando un entorno que incluya las bibliotecas necesarias para entrenar el modelo. Después, crearemos un clúster de proceso en el que se ejecutará la implementación por lotes y, por último, registraremos los datos de entrada como un recurso de datos.

Creación del entorno

Los componentes de este ejemplo utilizarán un entorno con las bibliotecas XGBoost y scikit-learn. El archivo environment/conda.yml contiene la configuración de la implementación:

environment/conda.yml

channels:
- conda-forge
dependencies:
- python=3.8.5
- pip
- pip:
  - mlflow
  - azureml-mlflow
  - datasets
  - jobtools
  - cloudpickle==1.6.0
  - dask==2023.2.0
  - scikit-learn==1.1.2
  - xgboost==1.3.3
  - pandas==1.4
name: mlflow-env

Crear el entorno de la siguiente manera:

  1. Definir el entorno:

    environment/xgboost-sklearn-py38.yml

    $schema: https://azuremlschemas.azureedge.net/latest/environment.schema.json
    name: xgboost-sklearn-py38
    image: mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu20.04:latest
    conda_file: conda.yml
    description: An environment for models built with XGBoost and Scikit-learn.
    
  2. Crear el entorno:

    az ml environment create -f environment/xgboost-sklearn-py38.yml
    

Creación de un clúster de proceso

Las implementaciones y puntos de conexión por lotes se ejecutan en clústeres de computación. Pueden ejecutarse en cualquier clúster de proceso de Azure Machine Learning que ya exista en el área de trabajo. Por lo tanto, varias implementaciones por lotes pueden compartir la misma infraestructura de proceso. En este ejemplo, trabajaremos en un clúster de proceso de Azure Machine Learning denominado batch-cluster. Verifiquemos que el cálculo exista en el área de trabajo o creémoslo de otra manera.

az ml compute create -n batch-cluster --type amlcompute --min-instances 0 --max-instances 5

Registrar los datos de entrenamiento como un activo de datos

Nuestros datos de entrenamiento están representados en archivos CSV. Para imitar una carga de trabajo más a nivel de producción, vamos a registrar los datos de entrenamiento en el archivo heart.csv como un activo de datos en el área de trabajo. Este recurso de datos se indicará posteriormente como entrada al punto de conexión.

az ml data create --name heart-classifier-train --type uri_folder --path data/train

Creación de la canalización

La canalización que queremos poner en funcionamiento toma una entrada, los datos de entrenamiento y genera tres salidas: el modelo entrenado, los resultados de evaluación y las transformaciones de datos aplicadas como preprocesamiento. La canalización consta de dos componentes:

  • preprocess_job: este paso lee los datos de entrada y devuelve los datos preparados y las transformaciones aplicadas. El paso recibe tres entradas:
    • data: una carpeta que contiene los datos de entrada que se van a transformar y puntuar
    • transformations: (opcional) ruta de acceso a las transformaciones que se aplicarán, si están disponibles. Si no se proporciona la ruta de acceso, las transformaciones se aprenderán de los datos de entrada. Dado que la entrada transformations es opcional, el componente preprocess_job se puede utilizar durante el entrenamiento y la puntuación.
    • categorical_encoding: la estrategia de codificación para las características categóricas (ordinal o onehot).
  • train_job: este paso entrenará un modelo XGBoost basado en los datos preparados y devolverá los resultados de evaluación y el modelo entrenado. El paso recibe tres entradas:
    • data: los datos preprocesados.
    • target_column: la columna que se quiere predecir.
    • eval_size: indica la proporción de los datos de entrada utilizados para la evaluación.

La configuración de la canalización se define en el archivo deployment-ordinal/pipeline.yml:

deployment-ordinal/pipeline.yml

$schema: https://azuremlschemas.azureedge.net/latest/pipelineComponent.schema.json
type: pipeline

name: uci-heart-train-pipeline
display_name: uci-heart-train
description: This pipeline demonstrates how to train a machine learning classifier over the UCI heart dataset.

inputs:
  input_data:
    type: uri_folder

outputs: 
  model:
    type: mlflow_model
    mode: upload
  evaluation_results:
    type: uri_folder
    mode: upload
  prepare_transformations:
    type: uri_folder
    mode: upload

jobs:
  preprocess_job:
    type: command
    component: ../components/prepare/prepare.yml
    inputs:
      data: ${{parent.inputs.input_data}}
      categorical_encoding: ordinal
    outputs:
      prepared_data:
      transformations_output: ${{parent.outputs.prepare_transformations}}
  
  train_job:
    type: command
    component: ../components/train_xgb/train_xgb.yml
    inputs:
      data: ${{parent.jobs.preprocess_job.outputs.prepared_data}}
      target_column: target
      register_best_model: false
      eval_size: 0.3
    outputs:
      model: 
        mode: upload
        type: mlflow_model
        path: ${{parent.outputs.model}}
      evaluation_results:
        mode: upload
        type: uri_folder
        path: ${{parent.outputs.evaluation_results}}

Nota

En el archivo pipeline.yml, falta la entrada transformations del preprocess_job; por lo tanto, el script aprenderá los parámetros de transformación de los datos de entrada.

Una visualización de la canalización es la siguiente:

Una imagen de la canalización que muestra la entrada del trabajo, los componentes de la canalización y las salidas en cada paso de la canalización.

Prueba de la canalización

Probemos la canalización con algunos datos de ejemplo. Para ello, se creará un trabajo mediante la canalización y el clúster de proceso batch-cluster creados anteriormente.

El siguiente archivo pipeline-job.yml contiene la configuración del trabajo de canalización:

deployment-ordinal/pipeline-job.yml

$schema: https://azuremlschemas.azureedge.net/latest/pipelineJob.schema.json
type: pipeline

experiment_name: uci-heart-train-pipeline
display_name: uci-heart-train-job
description: This pipeline demonstrates how to train a machine learning classifier over the UCI heart dataset.

compute: batch-cluster
component: pipeline.yml
inputs:
  input_data:
    type: uri_folder
outputs: 
  model:
    type: mlflow_model
    mode: upload
  evaluation_results:
    type: uri_folder
    mode: upload
  prepare_transformations:
    mode: upload

Crear el trabajo de prueba:

az ml job create -f deployment-ordinal/pipeline-job.yml --set inputs.input_data.path=azureml:heart-classifier-train@latest

Creación de un punto de conexión por lotes

  1. Proporcione un nombre para el punto de conexión. El nombre de un punto de conexión por lotes debe ser único en cada región, ya que el nombre se usa para construir el URI de invocación. Para garantizar la unicidad, anexa los caracteres finales al nombre especificado en el código siguiente.

    ENDPOINT_NAME="uci-classifier-train"
    
  2. Configuración del punto de conexión:

    El archivo endpoint.yml contiene la configuración del punto de conexión.

    endpoint.yml

    $schema: https://azuremlschemas.azureedge.net/latest/batchEndpoint.schema.json
    name: uci-classifier-train
    description: An endpoint to perform training of the Heart Disease Data Set prediction task.
    auth_mode: aad_token
    
  3. Creación del punto de conexión:

    az ml batch-endpoint create --name $ENDPOINT_NAME -f endpoint.yml
    
  4. Consulta del URI del punto de conexión:

    az ml batch-endpoint show --name $ENDPOINT_NAME
    

Implementar el componente de canalización

Para implementar el componente de canalización, tendremos que crear una implementación por lotes. Una implementación es un conjunto de recursos necesarios para hospedar el recurso que realiza el trabajo real.

  1. Configurar la implementación:

    El archivo deployment-ordinal/deployment.yml contiene la configuración de la implementación. Puede comprobar el esquema YAML del punto de conexión por lotes completo para obtener propiedades adicionales.

    deployment-ordinal/deployment.yml

    $schema: https://azuremlschemas.azureedge.net/latest/pipelineComponentBatchDeployment.schema.json
    name: uci-classifier-train-xgb
    description: A sample deployment that trains an XGBoost model for the UCI dataset.
    endpoint_name: uci-classifier-train
    type: pipeline
    component: pipeline.yml
    settings:
        continue_on_step_failure: false
        default_compute: batch-cluster
    
  2. Creación de la implementación:

    Ejecute el código siguiente para crear una implementación por lotes en el punto de conexión por lotes y establézcala como la implementación predeterminada.

    az ml batch-deployment create --endpoint $ENDPOINT_NAME -f deployment-ordinal/deployment.yml --set-default
    

    Sugerencia

    Observa el uso de la marca --set-default para indicar que esta nueva implementación es ahora el valor predeterminado.

  3. La implementación está lista para su uso.

Prueba de la implementación

Una vez creada la implementación, está lista para recibir trabajos. Sigue estos pasos para probar lo siguiente:

  1. Nuestra implementación requiere que indiquemos una entrada de datos.

    El archivo inputs.yml contiene la definición del recurso de datos de entrada:

    inputs.yml

    inputs:
      input_data:
        type: uri_folder
        path: azureml:heart-classifier-train@latest
    

    Sugerencia

    Para más información sobre cómo indicar entradas, consulta Crear trabajos y datos de entrada para puntos de conexión por lotes.

  2. Puedes invocar la implementación determinada de la siguiente manera:

    JOB_NAME=$(az ml batch-endpoint invoke -n $ENDPOINT_NAME --f inputs.yml --query name -o tsv)
    
  3. Puedes supervisar el progreso de la presentación y transmitir los registros mediante:

    az ml job stream -n $JOB_NAME
    

Cabe mencionar que solo las entradas de la canalización se publican como entradas en el punto de conexión por lotes. Por ejemplo, categorical_encoding es una entrada de un paso de la canalización, pero no una entrada en la propia canalización. Usa este hecho para controlar qué entradas deseas exponer a los clientes y cuáles deseas ocultar.

Obtener acceso a las salidas del trabajo

Una vez completado el trabajo, podemos acceder a algunas de sus salidas. Esta canalización genera las siguientes salidas para sus componentes:

  • preprocess job: la salida es transformations_output
  • train job: las salidas son model y evaluation_results

Puedes descargar los resultados asociados mediante:

az ml job download --name $JOB_NAME --output-name transformations
az ml job download --name $JOB_NAME --output-name model
az ml job download --name $JOB_NAME --output-name evaluation_results

Crear una nueva implementación en el punto de conexión

Los puntos de conexión pueden hospedar varias implementaciones a la vez, al tiempo que mantienen una sola implementación como valor predeterminado. Por lo tanto, puedes iterar en los distintos modelos, implementar los distintos modelos en el punto de conexión y probarlos y, por último, cambiar la implementación predeterminada a la implementación de modelo que funciona mejor para ti.

Vamos a cambiar la forma en que se realiza el preprocesamiento en la canalización para ver si se obtiene un modelo que funciona mejor.

Cambio de un parámetro en el componente de preprocesamiento de la canalización

El componente de preprocesamiento tiene una entrada que se llama categorical_encoding, que puede tener valores ordinal o onehot. Estos valores corresponden a dos formas diferentes de codificar características de categorías.

  • ordinal: codifica los valores de características con valores numéricos (ordinal) de [1:n], donde n es el número de categorías de la característica. La codificación ordinal implica que hay un orden de clasificación natural entre las categorías de características.
  • onehot: no implica una relación ordenada de clasificación natural, pero presenta un problema de dimensionalidad si el número de categorías es grande.

De forma predeterminada, usamos ordinal anteriormente. Ahora vamos a cambiar la codificación categórica para usar onehot y ver cómo funciona el modelo.

Sugerencia

Como alternativa, podríamos haber expuesto la entrada categorial_encoding a los clientes como entrada para el propio trabajo de canalización. Sin embargo, decidimos cambiar el valor del parámetro en el paso de preprocesamiento para que podamos ocultar y controlar el parámetro dentro de la implementación y aprovechar la oportunidad de tener varias implementaciones en el mismo punto de conexión.

  1. Modificar la canalización. Tiene el siguiente aspecto:

    La configuración de la canalización se define en el archivo deployment-onehot/pipeline.yml:

    deployment-onehot/pipeline.yml

    $schema: https://azuremlschemas.azureedge.net/latest/pipelineComponent.schema.json
    type: pipeline
    
    name: uci-heart-train-pipeline
    display_name: uci-heart-train
    description: This pipeline demonstrates how to train a machine learning classifier over the UCI heart dataset.
    
    inputs:
      input_data:
        type: uri_folder
    
    outputs: 
      model:
        type: mlflow_model
        mode: upload
      evaluation_results:
        type: uri_folder
        mode: upload
      prepare_transformations:
        type: uri_folder
        mode: upload
    
    jobs:
      preprocess_job:
        type: command
        component: ../components/prepare/prepare.yml
        inputs:
          data: ${{parent.inputs.input_data}}
          categorical_encoding: onehot
        outputs:
          prepared_data:
          transformations_output: ${{parent.outputs.prepare_transformations}}
      
      train_job:
        type: command
        component: ../components/train_xgb/train_xgb.yml
        inputs:
          data: ${{parent.jobs.preprocess_job.outputs.prepared_data}}
          target_column: target
          eval_size: 0.3
        outputs:
          model: 
            type: mlflow_model
            path: ${{parent.outputs.model}}
          evaluation_results:
            type: uri_folder
            path: ${{parent.outputs.evaluation_results}}
    
  2. Configurar la implementación:

    El archivo deployment-onehot/deployment.yml contiene la configuración de la implementación. Puede comprobar el esquema YAML del punto de conexión por lotes completo para obtener propiedades adicionales.

    deployment-onehot/deployment.yml

    $schema: https://azuremlschemas.azureedge.net/latest/pipelineComponentBatchDeployment.schema.json
    name: uci-classifier-train-onehot
    description: A sample deployment that trains an XGBoost model for the UCI dataset using onehot encoding for variables.
    endpoint_name: uci-classifier-train
    type: pipeline
    component: pipeline.yml
    settings:
        continue_on_step_failure: false
        default_compute: batch-cluster
    
  3. Creación de la implementación:

    Ejecute el código siguiente para crear una implementación por lotes en el punto de conexión por lotes y establézcala como la implementación predeterminada.

    az ml batch-deployment create --endpoint $ENDPOINT_NAME -f deployment-onehot/deployment.yml
    

    La implementación está lista para su uso.

  4. La implementación está lista para su uso.

Prueba de una implementación no predeterminada

Una vez creada la implementación, está lista para recibir trabajos. Podemos probarlo de la misma manera que hicimos antes, pero ahora invocaremos una implementación específica:

  1. Invoca la implementación de la siguiente manera, especificando el parámetro de implementación para desencadenar la implementación específica uci-classifier-train-onehot:

    DEPLOYMENT_NAME="uci-classifier-train-onehot"
    JOB_NAME=$(az ml batch-endpoint invoke -n $ENDPOINT_NAME -d $DEPLOYMENT_NAME --f inputs.yml --query name -o tsv)
    
  2. Puedes supervisar el progreso de la presentación y transmitir los registros mediante:

    az ml job stream -n $JOB_NAME
    

Configurar la nueva implementación como la predeterminada

Una vez satisfechos con el rendimiento de la nueva implementación, podemos establecer este nuevo como predeterminado:

az ml batch-endpoint update --name $ENDPOINT_NAME --set defaults.deployment_name=$DEPLOYMENT_NAME

Eliminar la implementación antigua

Una vez que hayas terminado, podrás eliminar la implementación anterior si ya no la necesitas:

az ml batch-deployment delete --name uci-classifier-train-xgb --endpoint-name $ENDPOINT_NAME --yes

Limpieza de recursos

Una vez que hayas terminado, elimina los recursos asociados del área de trabajo:

Ejecuta el código siguiente para eliminar el punto de conexión por lotes y la implementación subyacente. --yes se usa para confirmar la eliminación.

az ml batch-endpoint delete -n $ENDPOINT_NAME --yes

(Opcional) elimina el proceso, a menos que planees reutilizar el clúster de proceso con implementaciones posteriores.

az ml compute delete -n batch-cluster

Pasos siguientes