Artefactos y modelos en MLflow
En este artículo se explican los artefactos de MLflow y los modelos de MLflow, así como en qué se diferencian los modelos de MLflow de otros artefactos. También se explica la forma en que Azure Machine Learning usa las características de un modelo de MLflow para habilitar flujos de trabajo de implementación optimizados.
Artefactos y modelos
En MLflow, hay varias diferencias fundamentales entre el registro de artefactos de archivos simples y el de los modelos de MLflow.
Artefacto
Un artefacto es cualquier archivo generado y capturado en la ejecución de un experimento o en un trabajo. Un artefacto puede ser un modelo serializado en forma de archivo pickle, las ponderaciones de un modelo de PyTorch o de TensorFlow, o un archivo de texto que contenga los coeficientes de una regresión lineal. Algunos artefactos no tienen nada que ver con el propio modelo, pero contienen configuraciones de ejecución, información de preprocesamiento o datos de ejemplo. Los artefactos pueden tener varios formatos.
En el ejemplo siguiente se registra un artefacto de archivo.
filename = 'model.pkl'
with open(filename, 'wb') as f:
pickle.dump(model, f)
mlflow.log_artifact(filename)
Modelo
Un modelo de MLflow es un artefacto para el que se hacen suposiciones más sólidas que proporcionan un contrato claro entre los archivos guardados y lo que significan. Sin embargo, si los archivos del modelo se registran simplemente como artefactos, es preciso saber lo que significa cada uno de los archivos y cómo cargarlos para la inferencia.
Los modelos de MLflow se pueden registrar mediante el SDK de MLflow, por ejemplo:
import mlflow
mlflow.sklearn.log_model(sklearn_estimator, "classifier")
El registro de modelos de MLflow en Azure Machine Learning tiene las siguientes ventajas:
- Puede implementar modelos de MLflow en puntos de conexión por lotes o en tiempo real sin proporcionar un script de puntuación ni un entorno.
- Las implementaciones de modelos de MLflow generan automáticamente un archivo swagger, por lo que puede usar la característica Prueba en Estudio de Azure Machine Learning.
- Puede usar los modelos de MLflow directamente como entradas de canalización.
- Puede usar el panel de IA responsable con los modelos de MLflow.
Formato MLmodel
En el caso de los modelos registrados como archivos de artefacto simples, antes de cargar el modelo para la inferencia es preciso saber lo que pretendía el creador del modelo en cada archivo. Pero en el caso de los modelos de MLflow, el modelo se carga con el formato MLmodel para especificar el contrato entre los artefactos y lo que representan.
El formato de MLmodel almacena los recursos en una carpeta que no tiene ningún requisito de nomenclatura específico. Entre los recursos se encuentra un archivo denominado MLmodel que es la fuente única de la verdad para cargar y usar el modelo.
En la siguiente imagen se muestra una carpeta del modelo de MLflow denominadacredit_defaults_model en Estudio de Azure Machine Learning. La carpeta contiene el archivo MLmodel y otros artefactos del modelo.
En el ejemplo siguiente se muestra un archivo de MLmodel para un modelo de Computer Vision entrenado con fastai
:
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 el gran número de marcos de aprendizaje automático disponibles, MLflow introdujo el concepto de tipo como una manera de proporcionar un contrato único para 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 deben conservar y cargar los modelos 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. Por consiguiente, cada tipo puede usar los métodos que proporcionen el mejor rendimiento o la mayor compatibilidad según sus procedimientos recomendados, sin poner en peligro la compatibilidad con el estándar de MLmodel.
En el siguiente ejemplo se muestra 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 los modelos 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. Si hay alguna firma disponible, MLflow impone los tipos de entrada cuando los datos se envían al modelo. Para más información, consulte Cumplimiento de firmas de MLflow.
Las firmas se indican en el momento en que se registran los modelos y se conservan en la sección signature
del archivo MLmodel. La característica de registro automático de MLflow es la mejor opción para inferir firmas. Sin embargo, los modelos se pueden registrar manualmente si las firmas inferidas no son las que se necesitan. Para obtener más información, consulte Registro de modelos con firmas.
Hay dos tipos de firmas:
- Las firmas basadas en columnas funcionan en datos tabulares. En el caso de los modelos con este tipo de firma, MLflow proporciona
pandas.DataFrame
objetos como entradas. - Las firmas basadas en tensores funcionan con matrices o tensores con n dimensiones. En los modelos que tienen esta firma, MLflow proporciona
numpy.ndarray
como entrada, o un diccionario denumpy.ndarray
en el caso de tensores con nombre.
En el siguiente ejemplo se muestra la sección signature
de un modelo de Computer Vision entrenado con fastai
. Este modelo recibe un lote de imágenes representadas como tensores de forma (300, 300, 3)
con su representación en RGB como enteros sin signo. El modelo genera lotes de predicciones como probabilidades para dos clases.
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 que tiene una firma disponible. Este archivo facilita la realización de pruebas de las implementaciones mediante Estudio de Azure Machine Learning.
Entorno del modelo
Los requisitos para la ejecución del modelo se especifican en el archivo conda.yaml. MLflow puede detectar automáticamente dependencias, o bien puede indicarlas usted manualmente llamando al método mlflow.<flavor>.log_model()
. Esta operación puede ser útil en los casos si las bibliotecas de MLflow incluidas en el entorno no son las que quería usar.
En el siguiente archivo conda.yaml de ejemplo se muestra un entorno para un modelo creado con el marco fastai
:
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:
Un entorno de MLflow funciona en el nivel del modelo, pero un entorno de Azure Machine Learning funciona en el nivel del área de trabajo, en el caso de los entornos registrados, o en el nivel de trabajos o implementaciones, en el caso de los entornos anónimos. Al implementar modelos de MLflow, Azure Machine Learning compila el entorno del modelo y lo usa para la implementación. Puede usar la CLI de Azure Machine Learning para reemplazar este comportamiento e implementar modelos de MLflow en entornos específicos de Azure Machine Learning.
Función predict
Todos los modelos de MLflow contienen una función predict
, a la que se llama cuando se usa una implementación sin código para el modelo. Lo que la función predict
devuelve, como por ejemplo, clases, probabilidades, previsiones, etc., depende del marco o tipo que se haya usado para el entrenamiento. La documentación de cada tipo describe lo que devuelve.
Puede personalizar la función predict
para cambiar la forma en que se ejecuta la inferencia. Puede registrar modelos con un comportamiento diferente o registrar un tipo de modelo personalizado.
Flujos de trabajo para cargar modelos de MLflow
Puede cargar modelos de MLflow desde las siguientes ubicaciones:
- Directamente desde la ejecución en la que se registraron los modelos.
- Desde el sistema de archivos en que se guardan los modelos.
- Desde el registro de modelos en el que 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 los 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 con el formato Open Neural Network Exchange (ONNX) devuelven
ModelProto
, mientras que un modelo de árbol de decisión entrenado conscikit-learn
devuelve un objetoDecisionTreeClassifier
. Usemlflow.<flavor>.load_model()
para volver a cargar el mismo objeto de modelo y los mismos tipos que se registraron.Volver a cargar un modelo para ejecutar la inferencia. Puede cargar modelos mediante el SDK de MLflow y obtener un contenedor que tenga una función
predict
garantizada. Da igual el tipo que use, ya que todos los modelos de MLflow tienen una funciónpredict
.MLflow garantiza que puede llamar a esta función mediante argumentos del tipo
pandas.DataFrame
,numpy.ndarray
odict[string, numpyndarray]
, en función de la firma del modelo. MLflow controla la conversión de tipos al tipo de entrada que espera el modelo. Usemlflow.pyfunc.load_model()
para volver a cargar un modelo y ejecutar la inferencia.