Docker Containers As Machine Learning Environments (Part II)

Extend the Official Python Docker Image to Create an ML Image with Specific Dependencies.

If you are new to containerization, checkout some of these guides from NetApp: What are containers? and Containers vs. Virtual Machines (VMs): What’s the Difference?. Note: The author is not affiliated with NetApp, but believes they have written some good material on the subject.

When would I use containers for machine learning?

Suppose you were working on building a model. On your machine, you have Python 3.6 installed and a set of dependencies for your project (e.g., Numpy, Pandas, Scikit-Learn).

Later, a colleague asks for help testing the accuracy of their model, you grab the code and take a look on your machine. Oh no, your colleague runs a different version of Python (3.9) with a different set of dependencies.

You (Python 3.6)

numpy==1.19.5
pandas==1.2.2
matplotlib==3.3.1
scikit-learn==0.24.1

Colleague (Python 3.9)

numpy==1.21.1
pandas==1.2.3
matplotlib==3.3.4
scikit-learn==0.24.2
Problem: Colleague's code produces errors, warnings or will not even run at all.

You could update all of your dependencies to match your colleagues environment, but then what would happen when you tried to go back to your work?

It would be nice if you could "swap" your machine's Python and dependencies to match your colleague's environment.

This is exactly what containers allow you to do: create and share virtual environments (docker images) easily.

Container images are portable

A container image is the environment (i.e., the filesystem and dependencies required to run the application). This image can be completely captured in a single file called a Dockerfile. These can be shared easily or uploaded to a container registry like DockerHub for anyone to download. I’ll get to sharing container images in another blogpost.

A simple example of a Dockerfile (container image)

Lets start with a very simple example extended from Python’s official docker image:

FROM python:3.9-slim-buster

ENTRYPOINT ["python", "--version"]

The first line simply says that we wish to extend from the official python container image. The ENTRYPOINT line instructs the container to run a process. In this case, that process is the python command with the version flag.

If you build and then run this container image, all it is going to do is print out the version of python. While that is not very impressive, we can make it do much more &emdash; installing specific dependencies, running any setup scripts. But first we have to understand how to build and run the images.

Building a container image.

Once you have a simple Dockerfile, you will have to build it so that it can be run.

docker build -t simple:v6 -f ./Dockerfile . 

The first line here tells us that we want to extend from the official Python image and use version 3.9.

The ENTRYPOINT tells docker to execute the command, python --version

The output of this script should be something like `p

Containers are like portable environments.

Containers and images can be easily and freely shared with anyone. DockerHub is a service that makes uploading and sharing container images easy. In addition, many software foundations provide official containers for downloading and extending.

I have extended the official Python 3.9 image with the minimum set of dependencies I need to do most jobs. I have posted it on DockerHub as JupyterLab Minimalist.

Containers vs container images.

Note that there is a difference between images and containers:

Container Image: The “filesystem” for the container that includes everything required to run the application (dependencies, binaries and configuration).

Container: The process running in isolation that is started from an image.

Most of the time, images are shared or even extended to create another image.

Existing Solutions

Other solutions for creating isolated ML environments are popular, notably Anaconda Individual Edition and VirtualEnv.

The recent course I took, Machine Learning with Python, recommended Anaconda as an environment manager. Students had to install and configure their environments. Many students expressed difficulty with configuring environments and managing dependencies. Containers could have provided an easier way.

The drawback of these solutions is that they are too "single purpose". Containers are not limited to a small subset of languages and packages. There are official containers for Ubuntu, Python, Julia, R, Nodejs, Apache httpd, MySQL, NGINX, Go, PHP, GCC and many more.