Compartir a través de


Implementar modelos de MLflow en implementaciones 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á a implementar modelos MLflow en Azure Machine Learning para la inferencia por lotes mediante puntos de conexión por lotes. Al implementar modelos MLflow en puntos de conexión por lotes, Azure Machine Learning:

  • Proporciona una imagen base de MLflow o un entorno mantenido que contiene las dependencias necesarias para ejecutar un trabajo por lotes de Azure Machine Learning.
  • Crea una canalización de trabajo por lotes con un script de puntuación que se puede usar para procesar los datos mediante la paralelización.

Nota:

Para obtener más información sobre los tipos de archivo de entrada admitidos y detalles sobre cómo funciona el modelo de MLflow, consulte Consideraciones para la implementación con fines de inferencia por lotes.

Acerca de este ejemplo

En este ejemplo se muestra cómo puede implementar un modelo de MLflow en un punto de conexión por lotes para realizar predicciones por lotes. En este ejemplo se usa un modelo de MLflow basado en el conjunto de datos de enfermedades cardíacas de UCI. La base de datos contiene 76 atributos, pero se usa un subconjunto de 14 de ellos. El modelo intenta predecir la presencia de enfermedades cardíacas en un paciente. Es un entero cuyo valor es 0 (sin presencia) o 1 (presencia).

El modelo se ha entrenado mediante un clasificador de XGBBoost y todos los preprocesamientos necesarios se han empaquetado como una canalización de scikit-learn, lo que convierte este modelo en una canalización de un extremo a otro que pasa de datos sin procesar a predicciones.

El ejemplo de este artículo se basa en ejemplos de código contenidos 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-models/heart-classifier-mlflow

Siga estos pasos en Jupyter Notebooks

Puede seguir este ejemplo en los cuadernos siguientes. En el repositorio clonado, abra el cuaderno: mlflow-for-batch-tabular.ipynb.

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:

    • Crear o administrar puntos de conexión e implementaciones por lotes: use un rol 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 implementa 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>

Pasos

Siga estos pasos para implementar un modelo de MLflow en un punto de conexión por lotes para ejecutar la inferencia por lotes a través de nuevos datos:

  1. El punto de conexión por lotes solo puede implementar modelos registrados. En este caso, ya tenemos una copia local del modelo en el repositorio, por lo que solo es necesario publicar el modelo en el registro en el área de trabajo. Puede omitir este paso si el modelo que está intentando implementar ya está registrado.

    MODEL_NAME='heart-classifier-mlflow'
    az ml model create --name $MODEL_NAME --type "mlflow_model" --path "model"
    
  2. Antes de continuar, es necesario asegurarnos de que las implementaciones por lotes que estamos a punto de crear se pueden ejecutar en alguna infraestructura (proceso). Las implementaciones por lotes se pueden ejecutar en cualquier proceso de Azure Machine Learning que ya exista en el área de trabajo. Esto significa que varias implementaciones por lotes pueden compartir la misma infraestructura de proceso. En este ejemplo, vamos a trabajar en un clúster de proceso de Azure Machine Learning denominado cpu-cluster. Vamos a comprobar que el proceso existe en el área de trabajo o crearlo en caso contrario.

    Cree un clúster de proceso de la siguiente manera:

    az ml compute create -n batch-cluster --type amlcompute --min-instances 0 --max-instances 5
    
  3. Ahora es el momento de crear el punto de conexión y la implementación por lotes. Comencemos primero con el punto de conexión. Los puntos de conexión solo requieren que se cree un nombre y una descripción. El nombre del punto de conexión terminará en el URI asociado al punto de conexión. Por este motivo, los nombres de punto de conexión por lotes deben ser únicos dentro de una región de Azure. Por ejemplo, solo puede haber un punto de conexión por lotes con el nombre mybatchendpoint en westus2.

    En este caso, vamos a colocar el nombre del punto de conexión en una variable para que podamos hacer referencia a él más adelante.

    ENDPOINT_NAME="heart-classifier"
    
  4. Creación del punto de conexión:

    Para crear un nuevo punto de conexión, cree una configuración de YAML como la siguiente:

    endpoint.yml

    $schema: https://azuremlschemas.azureedge.net/latest/batchEndpoint.schema.json
    name: heart-classifier-batch
    description: A heart condition classifier for batch inference
    auth_mode: aad_token
    

    A continuación, cree el punto de conexión con el siguiente comando:

    az ml batch-endpoint create -n $ENDPOINT_NAME -f endpoint.yml
    
  5. Ahora, vamos a crear la implementación. Los modelos de MLflow no requieren que indique un entorno o un script de puntuación al crear las implementaciones, ya que se crean automáticamente. Sin embargo, puede especificarlos si quiere personalizar cómo la implementación realiza la inferencia.

    Para crear una nueva implementación en el punto de conexión creado, cree una configuración de YAML como la siguiente. Puede comprobar el esquema YAML del punto de conexión por lotes completo para obtener más propiedades.

    deployment-simple/deployment.yml

    $schema: https://azuremlschemas.azureedge.net/latest/modelBatchDeployment.schema.json
    endpoint_name: heart-classifier-batch
    name: classifier-xgboost-mlflow
    description: A heart condition classifier based on XGBoost
    type: model
    model: azureml:heart-classifier-mlflow@latest
    compute: azureml:batch-cluster
    resources:
      instance_count: 2
    settings:
      max_concurrency_per_instance: 2
      mini_batch_size: 2
      output_action: append_row
      output_file_name: predictions.csv
      retry_settings:
        max_retries: 3
        timeout: 300
      error_threshold: -1
      logging_level: info
    

    Después, cree la implementación con el siguiente comando:

    az ml batch-deployment create --file deployment-simple/deployment.yml --endpoint-name $ENDPOINT_NAME --set-default
    

    Importante

    Configure timeout en la implementación en función del tiempo que tarde el modelo en ejecutar la inferencia en un único lote. Cuanto mayor sea el tamaño del lote, más largo deberá ser este valor. Recuerde que mini_batch_size indica el número de archivos de un lote, y no el número de muestras. Al trabajar con datos tabulares, cada archivo puede contener varias filas, lo que aumentará el tiempo necesario para que el punto de conexión por lotes procese cada archivo. Use valores altos en esos casos para evitar errores de tiempo de espera.

  6. Aunque puede invocar una implementación específica dentro de un punto de conexión, normalmente querrá invocar el propio punto de conexión y dejar que este decida qué implementación se va a usar. Esta se denomina implementación "predeterminada". Esto le ofrece la posibilidad de cambiar la implementación predeterminada y, por tanto, modificar el modelo que sirve a la implementación sin cambiar el contrato con el usuario que invoca el punto de conexión. Use la instrucción siguiente para actualizar la implementación predeterminada:

    DEPLOYMENT_NAME="classifier-xgboost-mlflow"
    az ml batch-endpoint update --name $ENDPOINT_NAME --set defaults.deployment_name=$DEPLOYMENT_NAME
    
  7. En este momento, nuestro punto de conexión por lotes está listo para usarse.

Prueba de la implementación

Para probar nuestro punto de conexión, vamos a usar un ejemplo de datos sin etiquetar ubicados en este repositorio y que se pueden usar con el modelo. Los puntos de conexión de lote solo pueden procesar los datos que se encuentran en la nube y que son accesibles desde el área de trabajo de Azure Machine Learning. En este ejemplo, vamos a cargarlo en un almacén de datos de Azure Machine Learning. En concreto, vamos a crear un recurso de datos que se pueda usar para invocar el punto de conexión para la puntuación. Sin embargo, tenga en cuenta que los puntos de conexión por lotes aceptan datos que se pueden colocar en varias ubicaciones.

  1. Vamos a crear primero el recurso de datos. Este recurso de datos consta de una carpeta con varios archivos CSV que queremos procesar en paralelo mediante puntos de conexión por lotes. Puede omitir este paso si los datos ya están registrados como un recurso de datos o quiere usar otro tipo de entrada.

    a. Cree una definición de recurso de datos en YAML:

    heart-dataset-unlabeled.yml

    $schema: https://azuremlschemas.azureedge.net/latest/data.schema.json
    name: heart-dataset-unlabeled
    description: An unlabeled dataset for heart classification.
    type: uri_folder
    path: data
    

    b. Cree el recurso de datos:

    az ml data create -f heart-dataset-unlabeled.yml
    
  2. Ahora que los datos se han cargado y están listos para usarse, vamos a invocar el punto de conexión:

    JOB_NAME = $(az ml batch-endpoint invoke --name $ENDPOINT_NAME --input azureml:heart-dataset-unlabeled@latest --query name -o tsv)
    

    Nota

    Es posible que la utilidad jq no esté instalada en todas las instalaciones. Puede obtener instrucciones en este vínculo.

    Sugerencia

    Observe que no se indica el nombre de implementación en la operación de invocación. Esto se debe a que el punto de conexión enruta automáticamente el trabajo a la implementación predeterminada. Dado que nuestro punto de conexión solo tiene una implementación, esa es la predeterminada. Puede tener como destino una implementación específica indicando el argumento o parámetro deployment_name.

  3. Se inicia un trabajo por lotes tan pronto como el comando vuelve. Puede supervisar el estado del trabajo hasta que finalice:

    az ml job show -n $JOB_NAME --web
    

Análisis de las salidas

Las predicciones de salida se generan en el archivo de predictions.csv como se indica en la configuración de implementación. El trabajo genera una salida con nombre denominada score donde se coloca este archivo. Solo se genera un archivo por trabajo por lotes.

El archivo tiene la estructura siguiente:

  • Hay una fila por cada punto de datos que se envió al modelo. Para los datos tabulares, significa que el archivo (predictions.csv) contiene una fila para cada fila presente en cada uno de los archivos procesados. Para otros tipos de datos (por ejemplo, imágenes, audio, texto), hay una fila por cada archivo procesado.

  • Las columnas siguientes están en el archivo (en orden):

    • row (opcional), el índice de fila correspondiente en el archivo de datos de entrada. Esto solo se aplica si los datos de entrada son tabulares. Las predicciones se devuelven en el mismo orden en que aparecen en el archivo de entrada para que pueda confiar en que el número de fila coincide con la predicción correspondiente.
    • prediction, la predicción asociada a los datos de entrada. Este valor se devuelve "tal cual" ha sido proporcionado por la función predict(). del modelo.
    • file_name, el nombre de archivo desde el que se leyeron los datos. En los datos tabulares, use este campo para saber qué predicción pertenece a los datos de entrada.

Puede descargar los resultados del trabajo con el nombre del trabajo:

Use los siguientes comandos para descargar las predicciones:

az ml job download --name $JOB_NAME --output-name score --download-path ./

Una vez descargado el archivo, puede abrirlo con su herramienta favorita. En el ejemplo siguiente se cargan las predicciones mediante el dataframe de Pandas.

import pandas as pd

score = pd.read_csv(
    "named-outputs/score/predictions.csv", names=["row", "prediction", "file"]
)

La salida tiene el siguiente aspecto:

row prediction file
0 0 heart-unlabeled-0.csv
1 1 heart-unlabeled-0.csv
2 0 heart-unlabeled-0.csv
307 0 heart-unlabeled-3.csv

Sugerencia

Observe que en este ejemplo los datos de entrada eran datos tabulares en formato CSV y había 4 archivos de entrada diferentes (heart-unlabeled-0.csv, heart-unlabeled-1.csv, heart-unlabeled-2.csv y heart-unlabeled-3.csv).

Consideraciones para la implementación con fines de inferencia por lotes

Azure Machine Learning admite la implementación de modelos de MLflow en puntos de conexión por lotes sin tener que indicar ningún script de puntuación. Esto representa una manera cómoda de implementar modelos que requieren el procesamiento de grandes cantidades de datos por lotes. Azure Machine Learning usa información en la especificación del modelo de MLflow para orquestar el proceso de inferencia.

Cómo se distribuye el trabajo entre los trabajos

Los puntos de conexión por lotes distribuyen el trabajo en el nivel de archivo tanto para los datos estructurados como para los no estructurados. Como consecuencia, solo se admiten archivos de URI y carpetas de URI para esta característica. Cada trabajo procesa lotes con el número de archivos que indica Mini batch size. En el caso de los datos tabulares, los puntos de conexión por lotes no tienen en cuenta el número de filas que hay dentro de cada archivo al distribuir el trabajo.

Advertencia

Las estructuras de carpetas anidadas no se exploran durante la inferencia. Si particiona los datos en carpetas, asegúrese de aplanar la estructura de antemano.

Las implementaciones de lotes llamarán a la función predict del modelo de MLflow una vez por archivo. En el caso de los archivos CSV que contienen varias filas, puede suponer una presión de memoria en el proceso subyacente y aumentar el tiempo que tarda el modelo en puntuar un único archivo (especialmente para modelos de lenguaje grandes). Si encuentra varias excepciones de memoria insuficiente o entradas de tiempo de espera en los registros, considere la posibilidad de dividir los datos en archivos más pequeños con menos filas o de implementar el procesamiento por lotes en el nivel de fila dentro del script de puntuación o modelo.

Tipos de archivo admitidos

Los siguientes tipos de datos se admiten para la inferencia por lotes al implementar modelos de MLflow sin un entorno y un script de puntuación. Si quiere procesar un tipo de archivo diferente o ejecutar la inferencia de una manera distinta a la que los puntos de conexión por lotes usan de forma predeterminada, siempre podrá crear la implementación con un script de puntuación, tal y como se explica en Uso de modelos de MLflow con un script de puntuación.

Extensión de archivo Tipo devuelto como entrada del modelo Requisito de firma
.csv, .parquet, .pqt pd.DataFrame ColSpec. Si no se proporciona, no se aplican los tipos de columna.
.png, .jpg, .jpeg, .tiff, .bmp, .gif np.ndarray TensorSpec. La entrada se vuelve a configurar para que coincida con la forma de los tensores, si está disponible. Si no hay ninguna firma disponible, se infieren tensores de tipo np.uint8. Para obtener instrucciones adicionales, consulte Consideraciones sobre el procesamiento de imágenes de modelos de MLflow.

Advertencia

Tenga en cuenta que cualquier archivo no admitido que pueda estar presente en los datos de entrada hará que se produzca un error en el trabajo. Aparecerá una entrada de error como la siguiente "ERROR:azureml:Error al procesar el archivo de entrada: /mnt/batch/tasks/.../un-archivo-dado.avro'. No se admite el tipo de archivo 'avro'.".

Cumplimiento de firmas para modelos de MLflow

Los tipos de datos de entrada se aplican mediante trabajos de implementación por lotes mientras se leen los datos con la firma de modelo de MLflow disponible. Esto significa que la entrada de datos debe cumplir los tipos indicados en la firma del modelo. Si los datos no se pueden analizar según lo previsto, se producirá un error en el trabajo con un mensaje de error similar al siguiente: "ERROR:azureml:Error processing input file: '/mnt/batch/tasks/.../a-given-file.csv'. Exception: invalid literal for int() with base 10: 'value'".

Sugerencia

Las firmas en los modelos de MLflow son opcionales, pero se recomiendan encarecidamente, ya que proporcionan una manera cómoda de detectar problemas de compatibilidad de datos pronto. Para obtener más información sobre cómo registrar modelos con firmas, lea Registro de modelos con una firma personalizada, un entorno o ejemplos.

Puede inspeccionar la firma del modelo abriendo el archivo de MLmodel asociado al modelo de MLflow. Para más información sobre cómo funcionan las firmas en MLflow, consulte Firmas en MLflow.

Compatibilidad con tipos

Las implementaciones por lotes solo admiten la implementación de modelos de MLflow con un tipo pyfunc. Si necesita implementar otro tipo distinto, consulte Uso de modelos de MLflow con un script de puntuación.

Personalización de implementaciones de modelos de MLflow con un script de puntuación

Los modelos de MLflow se pueden implementar en puntos de conexión por lotes sin indicar un script de puntuación en la definición de implementación. Sin embargo, puede optar por indicar este archivo (normalmente denominado controlador por lotes) para personalizar cómo se ejecuta la inferencia.

Normalmente, seleccionará este flujo de trabajo cuando:

  • Debe procesar un tipo de archivo no compatible con las implementaciones de MLflow por lotes.
  • Debe personalizar la forma en que se ejecuta el modelo, por ejemplo, usar un tipo específico para cargarlo con mlflow.<flavor>.load().
  • Debe realizar el procesamiento previo y posterior en la rutina de puntuación cuando no lo hace el propio modelo.
  • La salida del modelo no se puede representar correctamente en datos tabulares. Por ejemplo, es un tensor que representa una imagen.
  • El modelo no puede procesar cada archivo a la vez debido a restricciones de memoria y necesita leerlo en fragmentos.

Importante

Si decide indicar un script de puntuación para una implementación de modelo de MLflow, también tendrá que especificar el entorno en el que se ejecutará la implementación.

Pasos

Siga estos pasos para implementar un modelo de MLflow con un script de puntuación personalizado.

  1. Identifique la carpeta donde se coloca el modelo de MLflow.

    a. Vaya al portal de Azure Machine Learning.

    b. Vaya a la sección Modelos.

    c. Seleccione el modelo que está intentando implementar y haga clic en la pestaña Artefactos.

    d. Tome nota de la carpeta que se muestra. Esta carpeta se indicó cuando se registró el modelo.

    Captura de pantalla en la que se muestra la carpeta donde se colocan los artefactos del modelo.

  2. Cree un script de puntuación. Observe cómo se ha incluido en la función init() la carpeta con nombre model que identificó anteriormente.

    deployment-custom/code/batch_driver.py

    # Copyright (c) Microsoft. All rights reserved.
    # Licensed under the MIT license.
    
    import os
    import glob
    import mlflow
    import pandas as pd
    import logging
    
    
    def init():
        global model
        global model_input_types
        global model_output_names
    
        # AZUREML_MODEL_DIR is an environment variable created during deployment
        # It is the path to the model folder
        # Please provide your model's folder name if there's one
        model_path = glob.glob(os.environ["AZUREML_MODEL_DIR"] + "/*/")[0]
    
        # Load the model, it's input types and output names
        model = mlflow.pyfunc.load(model_path)
        if model.metadata and model.metadata.signature:
            if model.metadata.signature.inputs:
                model_input_types = dict(
                    zip(
                        model.metadata.signature.inputs.input_names(),
                        model.metadata.signature.inputs.pandas_types(),
                    )
                )
            if model.metadata.signature.outputs:
                if model.metadata.signature.outputs.has_input_names():
                    model_output_names = model.metadata.signature.outputs.input_names()
                elif len(model.metadata.signature.outputs.input_names()) == 1:
                    model_output_names = ["prediction"]
        else:
            logging.warning(
                "Model doesn't contain a signature. Input data types won't be enforced."
            )
    
    
    def run(mini_batch):
        print(f"run method start: {__file__}, run({len(mini_batch)} files)")
    
        data = pd.concat(
            map(
                lambda fp: pd.read_csv(fp).assign(filename=os.path.basename(fp)), mini_batch
            )
        )
    
        if model_input_types:
            data = data.astype(model_input_types)
    
        # Predict over the input data, minus the column filename which is not part of the model.
        pred = model.predict(data.drop("filename", axis=1))
    
        if pred is not pd.DataFrame:
            if not model_output_names:
                model_output_names = ["pred_col" + str(i) for i in range(pred.shape[1])]
            pred = pd.DataFrame(pred, columns=model_output_names)
    
        return pd.concat([data, pred], axis=1)
    
  3. Vamos a crear un entorno donde se pueda ejecutar el script de puntuación. Dado que nuestro modelo es MLflow, los requisitos de Conda también se especifican en el paquete del modelo (para obtener más detalles sobre los modelos de MLflow y los archivos incluidos, consulte Formato MLmodel). A continuación, compilaremos el entorno con las dependencias de Conda del archivo. Sin embargo, también debe incluirse el paquete azureml-core necesario para las implementaciones por lotes.

    Sugerencia

    Si el modelo ya está registrado en el registro de modelos, puede descargar o copiar el archivo conda.yml asociado al modelo; para ello, vaya a Estudio de Azure Machine Learning> Modelos > Seleccione el modelo de la lista > Artefactos. Abra la carpeta raíz en la navegación y seleccione el archivo conda.yml que aparece. Haga clic en Descargar o copie su contenido.

    Importante

    En este ejemplo se usa un entorno de Conda que se especifica en /heart-classifier-mlflow/environment/conda.yaml. Este archivo se creó mediante la combinación del archivo de dependencias de Conda de MLflow original y la adición del paquete azureml-core. No se puede usar el archivo conda.yml directamente desde el modelo.

    La definición del entorno se incluirá en la propia definición de implementación como un entorno anónimo. Verá las líneas siguientes en la implementación:

    environment:
      name: batch-mlflow-xgboost
      image: mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu20.04:latest
      conda_file: environment/conda.yaml
    
  4. Configurar la implementación:

    Para crear una nueva implementación en el punto de conexión creado, cree una configuración de YAML como la siguiente. Puede comprobar el esquema YAML del punto de conexión por lotes completo para obtener más propiedades.

    deployment-custom/deployment.yml

    $schema: https://azuremlschemas.azureedge.net/latest/modelBatchDeployment.schema.json
    endpoint_name: heart-classifier-batch
    name: classifier-xgboost-custom
    description: A heart condition classifier based on XGBoost
    type: model
    model: azureml:heart-classifier-mlflow@latest
    environment:
      name: batch-mlflow-xgboost
      image: mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu20.04:latest
      conda_file: environment/conda.yaml
    code_configuration:
      code: code
      scoring_script: batch_driver.py
    compute: azureml:batch-cluster
    resources:
      instance_count: 2
    settings:
      max_concurrency_per_instance: 2
      mini_batch_size: 2
      output_action: append_row
      output_file_name: predictions.csv
      retry_settings:
        max_retries: 3
        timeout: 300
      error_threshold: -1
      logging_level: info
    
  5. Ahora vamos a crear la implementación:

    az ml batch-deployment create --file deployment-custom/deployment.yml --endpoint-name $ENDPOINT_NAME
    
  6. En este momento, nuestro punto de conexión por lotes está listo para usarse.

Limpieza de recursos

Ejecute el código siguiente para eliminar el punto de conexión por lotes y todas las implementaciones subyacentes. Los trabajos de puntuación por lotes no se eliminarán.

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

Pasos siguientes