Si alguna vez has compartido código, es bastante probable que hayas dicho aquello de “pues en mi máquina funciona” al ver como los demás tienen dificultades para ejecutarlo. Configuración incorrecta, diferencias de versiones o dependencias no instaladas suelen ser algunas de las causas detrás de este fenómeno.
En este post hablaremos de Docker, una herramienta que nos permite tener la garantía de que nuestro software se ejecutará igual en cualquier máquina, librándonos así de múltiples quebraderos de cabeza. En concreto, lo haremos a través del ejemplo de un modelo de machine learning con Python.
¿Qué es exactamente Docker?
Docker es una herramienta que nos permite empaquetar nuestro software en contenedores, que incluyen todas las dependencias y configuraciones necesarias para que pueda ser ejecutado. De esta forma, el contenedor es autosuficiente y podrá ser ejecutado en cualquier máquina con Docker instalado.
Para arrancar un contenedor, deberemos hacerlo a partir de una imagen, que es la plantilla que definirá el contenido del mismo. En docker hub podemos encontrar una amplia variedad de imágenes listas para usar, pero también podemos definir nuestras propias imágenes a través del fichero DockerFile. En este fichero se encontrarán diferentes instrucciones en las que se define lo que queremos que tenga la imagen.
Sintetizando, podemos decir que usamos el DockerFile para definir imágenes, y una vez que tenemos la imagen, el contenedor será una instancia de dicha imagen en ejecución.
Ejemplo Práctico
Veamos ahora cómo podemos aplicar Docker en el contexto de modelos predictivos de aprendizaje automático. Partiremos de un proyecto python de ejemplo donde ya se ha exportado el modelo y tenemos un script que lo carga y genera predicciones para unos datos de entrada. Asimismo, también se cuenta con un fichero requirements.txt con todas las dependencias.
Lo primero que tendremos que hacer será crear el DockerFile. A continuación pasaremos a explicar cada instrucción.
FROM python:3.8-buster
WORKDIR /app
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt
COPY run_model.py run_model.py
COPY model.pkl model.pkl
CMD ["python3", "run_model.py"]
En primer lugar, con el comando FROM definimos la imagen a partir de la cual vamos a construir la nuestra, que en este caso es la imagen oficial de python para la versión 3.8.
Con WORKDIR definimos /app como el espacio de trabajo. Tras esto, procedemos a instalar las dependencias. Con COPY copiamos el fichero requirements.txt al interior del contenedor, y posteriormente con el comando RUN ejecutamos la instalación de dichas dependencias. Copiamos el modelo y el script que lo ejecuta, y por último, con CMD definimos la ejecución por defecto del contenedor, que en este caso será correr con python el script que ejecuta el modelo.
Una vez tenemos nuestro DockerFile listo, podemos construir la imagen con el comando
$ docker build -t my_first_image:v0.1 .
Si todo ha ido correctamente, la nueva imagen debería aparecer listada si ejecutamos
$ docker image ls
Ahora que tenemos la imagen, podemos ejecutar un contenedor con el siguiente comando
$ docker run \
-v $PWD/input/:/input: \
-v $PWD/output/:/output: \
my_first_image:v0.1
Los contenedores no persisten la información, lo que quiere decir que una vez que se paren, los datos que contengan se perderán. Con la flag -v podemos definir volúmenes, que son directorios que si persisten la información. Éstos se encuentran fuera del sistema interno de ficheros del contenedor, y son muy útiles para compartir datos entre diferentes contenedores o con el propio sistema host. Para nuestro ejemplo, usaremos los volúmenes input y output, que pueden ser vistos como carpetas compartidas entre el host y el contenedor. Al ejecutar el contenedor, el script leerá los datos que previamente hemos dejado en input desde el sistema host, obtendrá las predicciones y las escribirá en un fichero dentro de output. Podremos acceder a dicho fichero desde el sistema host entrando en el directorio output.
Conclusión
En este post hemos introducido Docker y cómo podemos usarlo para ejecutar un modelo de aprendizaje automático. Para seguir profundizando, te recomendamos consultar la documentación oficial, y si te ha parecido interesante este artículo, te invitamos a echarle un vistazo al blog de Damavis.