MLops: Llevando a producción los modelos de machine learning

Arturo Gonzalez
6 min readFeb 4, 2020

Un escenario muy común al que se enfrenta todo científico de datos es tener que poner en producción un modelo de machine learning. Sin embargo, con mucha frecuencia estos se quedan en un jupyter notebook y nunca llegan a ponerse en producción para generar verdadero valor de negocio.

Ante este escenario empresas con gran avance tecnológico han construido sus propias plataformas para la gestión de punta a punta de sus modelos. Uber desarrollo michelangelo, facebook desarrollo FBLearner, google tensorflow extended y posteriormente kubeflow el cual se liberó a la comunidad y se ofrece dentro de su plataforma en la nube (google cloud platform). Afortunadamente para la comunidad open source existe un proyecto libre que nos será de gran utilidad, les presento MLflow.

En este post construiremos un modelo de machine learning con python, lo gestionaremos con mlflow y lo pondremos en operación en un contenedor de docker. El código se puede descargar del siguiente repositorio de github.

A continuación se mencionan conceptos relevantes para este proyecto.

Mlflow es un proyecto open source que facilita la gestión de modelos de machine learning incluyendo la experimentación, la reproducibilidad así como el despliegue de los mismos. El proyecto fue desarrollado por el equipo creador de spark y está disponible como un módulo de python el cuál es muy sencillo instalar mediante la siguiente sentencia:

$ pip install mlflow==1.5.0

MLFlow esta compuesto de tres componentes principales:

  • MLflow tracking: Es una componente para loggeo de métricas, parámetros, versiones de código, así como archivos de salida de las ejecuciones de nuestro código. Existen clientes para Python, R y Java.
  • MLflow projects: Es una estructura de archivos que permiten organizar Y gestionar el modelo de machine learning de manera reproducible. Consiste en tres archivos de salida generados: conda.yaml, MLproject y model.pkl
  • MLflow models: Es un estándar de empaquetado para la ejecución de un modelo y consumo a traves de una REST API. Librerias y frameworks soportados: sklearn, h20, mleap, keras, tensorflow, onnx, etc.

A su vez mlflow se apoya de otras componentes adicionales para poder funcionar las cuales son: backend-store (almacenamiento de metricas) y default-artifact-root (archivos y modelos resultados).

La backend-store puede ser de los siguientes tipos: archivos planos, postgres, mysql, etc.

La default-artifact puede ser de los siguientes tipos: archivos locales, azure blob storage, aws s3, ftp, etc.

A continuación les dejo un tutorial de mlflow.

Matei Zaharia presentando la nueva version de MLFlow

Toda la documentación de mlflow se puede encontrar en la siguiente liga:

https://mlflow.org/docs/latest/index.html

Docker: Proyecto open source que habilita el despliegue de contenedores de Linux siendo una alternativa muy eficiente en muchos casos a la virtualización de máquinas completas.

Docker compose: Es una herramienta para definir aplicaciones multi-contenedor mediante un archivo en formato yaml.

https://docs.docker.com/compose/

Ya que contamos con una base teórica de las componentes que se utilizarán en el proyecto, comencemos.

Arquitectura de proyecto:

Arquitectura de entorno gestionado con docker-compose

Paso 1: Levantar un entorno inicial mediante docker compose.

Para poder levantar este entorno necesitamos los siguientes componentes:

  1. El entorno de desarrollo de jupyter
  2. MLflow server: Gestión de modelos.
  3. Postgres: Base de datos de apoyo para mlflow server.
  4. FTP server: Servidor de archivos de apoyo para mlflow server. Nos basamos en la imagen de https://github.com/mauler/docker-simple-ftp-server
  5. Portainer: Contenedor con UI de gestión del entorno de docker.

Jupyter:

Para el entorno de jupyter nos basaremos en la imagen especificada en este repo: https://github.com/jupyter/docker-stacks, le agregamos mlflow así como el notebook con el modelo ejemplo.

Dockefile jupyter modificado
Archivo de requirements de python

MLFlow server

Para el entorno de mlflow nos basamos en una imagen de python y le agregamos mlflow.

Dockerfile mlflow server
requirements.txt para mlflow server
Dockerfile para postgres
init.sql

Docker Compose

Una vez que tenemos las imagenes construidas, pasamos a levantar el entorno con docker-compose ejecutando el siguiente comando en terminal en el directorio raiz del proyecto.

$ docker-compose up
docker-compose.yaml para levantar todo el entorno

Esperamos unos segundos y verificamos que los contenedores se hayan levantado correctamente mediante portainer accesible en http://localhost:9000

Interfaz de usuario de portiner donde vemos los contenedores ejecutandose.

Paso 2: Desarrollo del modelo de machine learning:

Dado que el objetivo de este post es demostrar el flujo completo desde el desarrollo hasta la puesta en operación de un modelo, vamos a tomar un ejemplo del dataset de diabetes incluido en la carpeta de ejemplos del repositorio de mlflow (este ejercicio ya viene cargado en la imagen de jupyter construida).

Para poder acceder a jupyter, buscamos en los logs de docker compose y encontramos una linea semejante a la de la imagen, la copiamos y sustituimos la parte entre parentesis por localhost o 127.0.0.1.

Log de docker-compose

La cadena anterior quedaría: http://localhost:8888/?token=….. etc.

Pegamos esta cadena en nuestro browser y este terminará dirigiéndonos a localhost:8888/lab. Posteriormente abrimos el archivo ejemplo ipynb y ejecutamos el notebook.

Entorno jupyter con notebook ejemplo listo para ejecución.

3. Registro de modelos en MLFlow

Una vez ejecutado el código, el modelo estará registrado en mlflow donde estarán loggedas las métricas especificadas en el notebook mediante los comandos:

  • mlflow.log_param
  • mlflow.log_metric
  • mlflow.sklearn.log_model
UI principal mlflow http://localhost:5000
Parámetros y métricas de ejecución
Modelo loggeado

Paso 4: Creación de una imagen de docker con el modelo entrenado.

Para este paso, nos conectamos mediante bash al contenedor del servidor de mlflow mediante el siguiente comando:

$ docker exec -it ml-deployment_mlflow_1 /bin/bash

Una vez dentro del contenedor ejecutamos el siguiente comando:

$ mlflow models build-docker -m ftp://test:test@ftpd/home/test/0/e7df5edb12d547538e94ce06d7970754/artifacts/model/model

Siendo la cadena ftp://….. la ubicación del modelo entrenado en en el servidor de ftp.

MLflow construirá una imagen de docker basada en ubuntu (default de mlflow) con el modelo entrenado adentro y la hará disponible en el docker-registry local. El contenedor de Mlflow es capaz de acceder al docker engine ya que tanto el binario como el socket estan mapeados como un volumen. Este proceso tarda unos minutos.

Construccion de la imagen con el modelo entrenado

Paso 5: Creación del contenedor con el modelo entrenado.

Una vez que este disponible la imagen dentro del registry de docker, procedemos a instanciarla para llevar a cabo predicciones. Ejecutamos con el siguiente comando desde nuestro sistema operativo base:

$ docker run -it -p 5002:8080 mlflow-pyfunc-servable:latest

Paso 6. Llevar a cabo una predicción.

Existen muchas herramientas para llevar a cabo pruebas sobre APIs, nosotros utilizaremos POSTMAN que es un servicio web para llevar a cabo testing sobre Rest APIS. Especificamos metodo POST y el URL: http://localhost:5002/invocations, el tipo de contenido “application/json” así como el body del request (datos de entrada a predecir).

Predicción del modelo entrenado sobre un registro de 10 variables de entrada.

Consideraciones

Este proyecto esta construido para demostrar el flujo completo desde el desarrollo de un modelo hasta su operación, sin embargo se tienen que resaltar aspectos importantes si se desea implementarlo a escala.

  1. Necesaria incorporación de herramientas de seguridad y auditoría.
  2. Necesaria la incorporación de bases de datos robustas y almacenamiento de archivos con respaldos.
  3. Necesaria la incorporación de control de versiones y un flujo de CI/CD, Ansible, etc.
  4. Despliegue del modelo sobre infraestructura de microservicios de kubernetes para garantizar su alta disponibilidad.
  5. Necesaria Incorporación de herramienta descriptiva de API mediante swagger.
  6. Necesaria incorporación de un API manager para llevar la adecuada contabilidad y acceso al modelo.

Conclusiones Finales

En este post se mostró como gestionar un modelo de machine learning de punta a punta, sin embargo, también se mostró que para llevar esto a una escala productiva es necesario incorporar más elementos que brinden alta disponibilidad, seguridad y respaldo.

En el próximo post se mostrará como implementar la gestión de punta a punta de modelos sobre una arquitectura basada en nube.

Recursos adicionales

https://mc.ai/setup-mlflow-in-production/

--

--