De los artefactos a los modelos en MLflow

En este artículo, se explican las diferencias entre un artefacto y un modelo en MLflow y cómo hacer la transición de uno a otro. También se explica cómo utiliza Azure Machine Learning el concepto de modelo de MLflow para habilitar flujos de trabajo de implementación simplificados.

¿Cuál es la diferencia entre un artefacto y un modelo?

Si no está familiarizado con MLflow, quizá no conoce la diferencia entre el registro de artefactos o archivos y el registro de modelos de MLflow. Hay algunas diferencias fundamentales entre los dos:

Artefacto

Cualquier archivo generado (y capturado) por la ejecución de un experimento o un trabajo es un artefacto. Un artefacto de compilación puede representar un modelo serializado como un archivo pickle, el peso de un modelo de PyTorch o de TensorFlow, o incluso un archivo de texto que contenga los coeficientes de una regresión lineal. Algunos artefactos también podrían no tener nada que ver con el propio modelo; en su lugar, podrían contener configuraciones para ejecutar el modelo o preprocesar información, o datos de ejemplo, etc. Los artefactos pueden tener varios formatos.

Es posible que ya haya estado registrando artefactos:

filename = 'model.pkl'
with open(filename, 'wb') as f:
  pickle.dump(model, f)

mlflow.log_artifact(filename)

Modelo

Un modelo en MLflow también es un artefacto. Sin embargo, hacemos suposiciones más sólidas sobre este tipo de artefactos. Estas suposiciones nos permiten crear un contrato claro entre los archivos guardados y lo que significan. Al registrar los modelos como artefactos (archivos simples), debe saber lo que el generador de modelos significaba para cada uno de esos archivos, con el fin de saber cómo cargar el modelo para la inferencia. Por el contrario, los modelos de MLflow se pueden cargar mediante el contrato especificado en el formato MLModel.

En Azure Machine Learning, el registro de modelos tiene las siguientes ventajas:

  • Puede implementarlos en puntos de conexión por lotes o en tiempo real sin proporcionar un script de puntuación ni un entorno.
  • Cuando se implementan, las implementaciones del modelo tienen una instancia de Swagger generada automáticamente y la función Prueba se puede usar en Estudio de Azure Machine Learning.
  • Puede usar los modelos directamente como entradas de canalización.
  • Puede usar el panel de IA responsable con sus modelos.

Puede registrar modelos mediante el SDK de MLflow:

import mlflow
mlflow.sklearn.log_model(sklearn_estimator, "classifier")

Formato MLmodel

MLflow adopta el formato MLModel como una manera de crear un contrato entre los artefactos y lo que representan. El formato MLModel almacena los recursos en una carpeta. Entre estos recursos, hay un archivo denominado MLmodel. Este archivo es la única fuente de verdad sobre cómo se puede cargar y usar un modelo.

En la captura de pantalla siguiente se muestra la carpeta de un modelo de MLflow de ejemplo en Estudio de Azure Machine Learning. El modelo se coloca en una carpeta denominada credit_defaults_model. No hay ningún requisito específico sobre la nomenclatura de esta carpeta. La carpeta contiene el archivo MLmodel entre otros artefactos de modelo.

A screenshot showing assets of a sample MLflow model, including the MLmodel file.

El código siguiente es un ejemplo del aspecto que podría tener el archivo MLmodel para un modelo de Computer Vision entrenado con fastai:

MLmodel

artifact_path: classifier
flavors:
  fastai:
    data: model.fastai
    fastai_version: 2.4.1
  python_function:
    data: model.fastai
    env: conda.yaml
    loader_module: mlflow.fastai
    python_version: 3.8.12
model_uuid: e694c68eba484299976b06ab9058f636
run_id: e13da8ac-b1e6-45d4-a9b2-6a0a5cfac537
signature:
  inputs: '[{"type": "tensor",
             "tensor-spec": 
                 {"dtype": "uint8", "shape": [-1, 300, 300, 3]}
           }]'
  outputs: '[{"type": "tensor", 
              "tensor-spec": 
                 {"dtype": "float32", "shape": [-1,2]}
            }]'

Tipos de modelo

Teniendo en cuenta la variedad de marcos de aprendizaje automático disponibles, MLflow introdujo el concepto de tipo como una manera de proporcionar un contrato único para trabajar con todos estos marcos. Un tipo indica lo que se espera de un modelo determinado creado con un marco específico. Por ejemplo, TensorFlow tiene su propio tipo, que especifica cómo se debe conservar y cargar un modelo de TensorFlow. Dado que cada tipo de modelo indica cómo deben conservarse y cargarse los modelos de un marco concreto, el formato MLmodel no impone un único mecanismo de serialización que todos los modelos deban admitir. Esta decisión permite que cada tipo use los métodos que proporcionan el mejor rendimiento o la mejor compatibilidad según sus procedimientos recomendados, sin poner en peligro la compatibilidad con el estándar MLmodel.

El siguiente es un ejemplo de la sección flavors de un modelo fastai.

flavors:
  fastai:
    data: model.fastai
    fastai_version: 2.4.1
  python_function:
    data: model.fastai
    env: conda.yaml
    loader_module: mlflow.fastai
    python_version: 3.8.12

Firma de modelo

Las firmas de modelo de MLflow son una parte importante de la especificación del modelo, ya que sirven como un contrato de datos entre el modelo y el servidor que ejecuta los modelos. También son importantes para analizar e imponer tipos de entrada de modelo en el momento de la implementación. MLflow impone tipos de entrada cuando los datos se envían al modelo si hay una firma disponible. Para más información, consulte Cumplimiento de firmas de MLflow.

Las firmas se indican cuando el modelo se registra y se conserva en el archivo en la sección signature del archivo MLmodel. La característica de registro automático de MLflow infiere automáticamente las firmas de una manera más adecuada. Sin embargo, es posible que tenga que registrar los modelos manualmente si las firmas inferidas no son las que necesita. Para obtener más información, consulte Registro de modelos con firmas.

Hay dos tipos de firmas:

  • Firma basada en columnas: esta firma funciona en forma de datos tabulares. En el caso de los modelos con este tipo de firma, MLflow proporciona pandas.DataFrame objetos como entradas.
  • Firma basada en Tensor: corresponde a firmas que funcionan con tensores o matrices de n dimensiones. Para modelos con esta firma, MLflow proporciona numpy.ndarray como entrada (o un diccionario de numpy.ndarray en el caso de tensores con nombre).

El ejemplo siguiente corresponde a un modelo de visión artificial entrenado con fastai. Este modelo recibe un lote de imágenes representadas como tensores que tienen la forma (300, 300, 3) con su representación en RGB (enteros sin signo). El modelo genera lotes de predicciones (probabilidades) para dos clases.

MLmodel

signature:
  inputs: '[{"type": "tensor",
             "tensor-spec": 
                 {"dtype": "uint8", "shape": [-1, 300, 300, 3]}
           }]'
  outputs: '[{"type": "tensor", 
              "tensor-spec": 
                 {"dtype": "float32", "shape": [-1,2]}
            }]'

Sugerencia

Azure Machine Learning genera un archivo de Swagger para la implementación de un modelo en formato MLflow con una firma disponible. Esto facilita la prueba de las implementaciones con Estudio de Azure Machine Learning.

Entorno del modelo

Los requisitos para la ejecución de un modelo se especifican en el archivo conda.yaml. MLflow puede detectar automáticamente dependencias, o bien puede indicarlas manualmente llamando al método mlflow.<flavor>.log_model(). Esto último puede ser útil en los casos en los que las bibliotecas incluidas en el entorno no son las que quiere usar.

El siguiente es un ejemplo de código de un entorno que se usa para un modelo creado con el marco fastai:

conda.yaml

channels:
- conda-forge
dependencies:
- python=3.8.5
- pip
- pip:
  - mlflow
  - astunparse==1.6.3
  - cffi==1.15.0
  - configparser==3.7.4
  - defusedxml==0.7.1
  - fastai==2.4.1
  - google-api-core==2.7.1
  - ipython==8.2.0
  - psutil==5.9.0
name: mlflow-env

Nota:

¿Cuál es la diferencia entre un entorno de MLflow y un entorno de Azure Machine Learning?

Mientras que un entorno de MLflow funciona en el nivel del modelo, un entorno de Azure Machine Learning funciona en el nivel del área de trabajo (para entornos registrados) o trabajos o implementaciones (para entornos anónimos). Al implementar modelos de MLflow en Azure Machine Learning, se crea y se usa el entorno del modelo para la implementación. Como alternativa, puede reemplazar este comportamiento con la CLI v2 de Azure Machine Learning e implementar modelos de MLflow mediante entornos específicos de Azure Machine Learning.

Función predict

Todos los modelos de MLflow contienen una función predict. Esta función es la que se llama cuando se implementa un modelo con una experiencia de implementación sin escritura de código. Lo que la función predict devuelve (por ejemplo, clases, probabilidades, previsiones, etc.) depende del marco (es decir, el tipo) que se ha usado para el entrenamiento. Lea la documentación de cada tipo para saber lo que devuelven.

En los mismos casos, puede ser necesario personalizar esta función de lenguajepredict para cambiar la forma en la que se ejecuta la inferencia. En esos casos, debe registrar los modelos con un comportamiento diferente en el método predict o registrar el tipo de un modelo personalizado.

Flujos de trabajo para cargar modelos de MLflow

Puede cargar modelos que se crearon como modelos de MLflow desde varias ubicaciones, entre las que se incluyen:

  • Directamente desde la ejecución en la que se registraron los modelos.
  • Desde el sistema de archivos donde se guardan los modelos.
  • Desde el registro de modelos donde se registran los modelos.

MLflow proporciona una forma coherente de cargar estos modelos independientemente de la ubicación.

Hay dos flujos de trabajo disponibles para cargar modelos:

  • Volver a cargar el mismo objeto y los tipos que se registraron: puede cargar modelos mediante el SDK de MLflow y obtener una instancia del modelo con tipos que pertenecen a la biblioteca de entrenamiento. Por ejemplo, un modelo ONNX devuelve un ModelProto mientras que un modelo de árbol de decisión entrenado con scikit-learn devuelve un objeto DecisionTreeClassifier. Use mlflow.<flavor>.load_model() para volver a cargar el mismo objeto de modelo y los mismos tipos que se registraron.

  • Cargar de nuevo un modelo para ejecutar la inferencia: se pueden cargar modelos mediante el SDK de MLflow y obtener un contenedor en el que MLflow garantice que habrá una función predict. Da igual el tipo que use, todos los modelos de MLflow tienen una función de lenguajepredict. Además, MLflow garantiza que se pueda llamar a esta función mediante argumentos del tipo pandas.DataFrame, numpy.ndarray o dict[string, numpyndarray] (según la firma del modelo). MLflow controla la conversión de tipos al tipo de entrada que espera el modelo. Use mlflow.pyfunc.load_model() para volver a cargar un modelo y ejecutar la inferencia.