AWS Lambda#

Note

Got questions? Reach out to us on Slack.

AWS Lambda is a serverless compute service. It allows you to deploy functions in the cloud without worrying about servers or scaling. It is a great (and cheap) option to deploy Machine Learning models.

This tutorial shows you how to deploy a Machine Learning model to AWS Lambda. Unlike other frameworks or tutorials, Soopervisor and Ploomber allow you to deploy complete inference DAGs (as opposed to a model file) without changing your training pipeline’s code; handling packaging, containerization and deployment.

If you encounter any issues with this tutorial, let us know.

Pre-requisites#

Training vs. serving pipelines#

When training an ML model, you may organize the pipeline in several tasks such as “get data”, “clean data”, “compute feature 1”, “compute feature 2” and “train model”.

To deploy the model, you have to provide both a model file and all the necessary feature generation steps. Soopervisor and Ploomber allow you to create an online inference pipeline from a training one without code changes.

In our case, your inference pipeline includes “compute feature 1” and “compute feature 2”; and adds two new tasks: one to receive the input raw data and another one to load a model and make a prediction using the feature vector.

This tutorial will walk you through the development and deployment process.

Setting up project#

We’ll now fetch an example pipeline:

git clone https://github.com/ploomber/projects
cd projects/templates/ml-online/

Configure the development environment:

ploomber install

Then, activate the environment:

conda activate ml-online

Exploring the example code#

Before diving into the code, let’s plot our pipeline to have a better idea of its structure:

# required to generate plots
conda install pygraphviz --channel conda-forge --yes

# generate plot
ploomber plot

Open the generated pipeline.png file. The left-most task in the pipeline obtains data for training, then we have a of couple tasks that generate some extra feature, a task that joins all features into a single data frame and one that fits a model.

Those tasks are declared in the src/ml_online/pipeline.yaml file. Open the file to review the content, you will see that there are two tasks in the tasks section (to get data and to fit the model), the remaining tasks are coming from the src/ml_online/pipeline-features.yaml; this separation allows us to convert the feature engineering portion of the pipeline into an inference pipeline without code changes.

Note that for this to work, all feature engineering tasks must be Python functions with a configured serializer and unserializer. The other tasks can be of any type.

Training a model#

Let’s now train a model:

ploomber build

Once the pipeline finishes, copy the trained model from products/model.pickle to the standard model location: src/ml_online/model.pickle.

# on linux/mac
cp products/model.pickle src/ml_online/model.pickle

That’s it. We’re ready to export to AWS Lambda.

Generating files#

Let’s now create the necessary files to export to AWS Lambda:

soopervisor add serve --backend aws-lambda

Note

You don’t have to install soopervisor manually; it should’ve been installed when running ploomber install. If missing, install it with pip install soopervisor.

You have to provide a few details before you can run the model in AWS Lambda. First, edit the serve/test_aws_lambda.py file. This file contains a unit test to ensure your model works as expected.

The test case is already configured, you only have to replace the line that contains, body = None for a sample input value. In our case, it looks like this:

body = {
    'sepal length (cm)': 5.1,
    'sepal width (cm)': 3.5,
    'petal length (cm)': 1.4,
    'petal width (cm)': 0.2,
}

Important

You should also remove the line that raises the NotImplementedError.

Next, we have to tell Lambda, how to handle an incoming API request, this happens in the serve/app.py file. The request body is received as a string but our model receives a data frame as input. The sample code already implements a “string to data frame” implementation, hence, you only have to delete the line that raises the NotImplementedError. When you use this for your own model, write the applicable parsing logic.

To deploy to AWS Lambda, soopervisor packages your code and creates a Docker image. We can build such Docker image (without actually deploying to AWS Lambda) to test our API with the following command:

soopervisor export serve --until-build

The command will take a few minutes since it has to create a Docker image, subsequent runs will be much faster.

Once finished, you may start the API locally with:

cd serve
sam local start-api

Open a new terminal and call the API:

curl http://127.0.0.1:3000/predict -X POST -d '{"sepal length (cm)": 5.1, "sepal width (cm)": 3.5, "petal length (cm)": 1.4, "petal width (cm)": 0.2}'

Try calling with other values to get a different prediction

Note

Due to the way the local API is built this will take a few seconds

Congratulations! You just ran Ploomber on AWS Lambda!

Deployment#

soopervisor export serve

explain the –guided thing and add some link

you must be authenticated to use lambda, s3, and CloudFormation

About template.yaml#

To deploy to Lambda, AWS requires a template.yaml file to specify your serverless application. A sample file that configures an API Gateway is provided, but you may need to edit it for your application. Click here to learn more.