Deploying a Serverless Machine Learning Application With Python

A word about serverless
Serverless architectures have been gaining popularity. Going serverless offloads a lot of the hardest part of managing server infrastructure to the cloud provider. Meaning we no longer have to worry as much about things like scaling, networking, and provisioning resources. Leaving for more time to focus on application logic and developing.
However, serverless architectures aren’t always sunshine and rainbows and unicorns. They are not well suited for long running applications, can be hard to configure, and don’t provide the same flexibility containerized architectures can. But even with these pitfalls, I would argue the benefits outweigh the cost for many (although not all) applications.
In this post, we’ll deploy a simple model with the Serverless Framework CLI. The Serverless CLI is a command line tool that helps alleviate some of the headache the configuring a serverless application with your cloud provider. In this case, we will be using Serverless to help with deployment to AWS.
Overview
We will train a simple Iris flower classifier which will be deployed as a REST API with Serverless Framework. When it’s all said and done, the architecture will look something like this.

You’ll need to install the Serverless CLI and create an AWS account if you don’t already have one.
Before we dive in, all of the code discussed in this post is available in this repo.
The model
The model we’ll be deploying is the always classic Iris classifier.
Let’s set up a virtual environment so we can start creating our model.
Since the focus of the post is on serverless deployment, I won’t get into the actual creation of the model. It’s a simple, out-of-the-box random forest classifier from scikit-learn. If you’re interested in seeing that code, check out this notebook. The end result is a pickled model we can load to use as a classifier.
Deployment
Now that the model is saved, we can start configuring deployment with the Serverless Framework CLI. We need to add an additional Serverless plugin to help with packaging our Python libraries. For the plugin to work properly you need to have Docker installed on your machine (the plugin uses docker to package all the requirements so they work seamlessly with Lambda).
$ npm init
$ npm install --save serverless-python-requirementsTo tell Serverless how to deploy our model on AWS, we need to define a serverless.yml file.
A few things are happening in the serverless.yml file
- We define a provider, stage, and runtime.
- Tell serverless we want to use the serverless-python-requirements plugin to deploy packages we defined in requirements.txt
- Include only files that are relevant to the Lambda function deployment (handler.py, requirements.txt, and everything in the model/ directory)
- State which Lambda functions we want associated with which Api Gateway endpoints.
That’s it! We can now deploy the application.
$ sls deployYou should see output similar to the following.
Serverless: Installing requirements of requirements.txt in .serverless...
Serverless: Docker Image: lambci/lambda:build-python3.6
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Injecting required Python packages to package...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (54.16 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
....................
Serverless: Stack update finished...
Service Information
service: serverless-iris-api
stage: dev
region: us-east-1
stack: serverless-iris-api-dev
api keys:
None
endpoints:
GET - https://e658ykxkhg.execute-api.us-east-1.amazonaws.com/dev/status
POST - https://e658ykxkhg.execute-api.us-east-1.amazonaws.com/dev/predict
functions:
iris-status: serverless-iris-api-dev-iris-status
iris-predict: serverless-iris-api-dev-iris-predict
Serverless: Removing old service artifacts from S3...Now let’s test the endpoints to make sure they’re up and working.
$ curl https://e658ykxkhg.execute-api.us-east-1.amazonaws.com/dev/statusYou should get our status response.
{“message”: “Good to go!”}And for the predict endpoint we test with an array of features X = [3.3, 4.1, 5.3, 1.9].
$ curl -d '{"X": [3.3, 4.1, 5.3, 1.9]}' -H "Content-Type: application/json" -X POST https://e658ykxkhg.execute-api.us-east-1.amazonaws.com/dev/predictWe get back our Iris prediction
{"label": "virginica", "input": [3.3, 4.1, 5.3, 1.9]}