By Srinivas Pratapgiri (Goanna student)

Microservice architecture is used to build large scale and complex applications that are composed of small, independent and loosely coupled services. Docker containers are used to deploy microservices.

The main objective of this blog is to

  1. Develop a sentiment analysis classifier to predict the outcomes of the given customer data as either Positive or Negative using PyTorch Transformer library
  2. Convert the classifier into a web application using flask and REST API to make model inferences against arbitrary user data
  3. Build a Dockerfile with Ubuntu as base Image and create a Conda environment to manage Python dependencies.
  4. Deploy the Docker Image on to the Docker container using Docker Compose
  5. Use a bash script containing cURL commands to make inferences from the classifier as either Positive or Negative

1) Sentiment Analysis Classifier

The model for predicting the sentiments of the customer data is built using Transformer library, which contains pre-trained models for NLP — Natural Language Processing. The library is backed by three most popular deep learning libraries- PyTorchTensorFlow and Jax. The model uses the pipeline object in transformers to make all preprocessing and post processing steps on the input text data and generates the inferences on the text. Next, in your python application program import the pickle module to store model object in a file and get it back later on.

import transformers

from transformers import pipeline

model = pipeline("sentiment-analysis")

import pickle
with open('./model.pkl', 'wb') as model_pkl:
    pickle.dump(model, model_pkl)

2) Web Application

Next step in the process is to convert the sentiment classifier into a web application using flask python web framework and use Flask-RESTful API to build a REST API to make inferences from sentiment classifier.

The steps are explained below

a) Import Flask class and an instance of this class will be our Web Service Gate Interface(WSGI) application.

b) Next create an instance of this class . The first argument is the name of the applications module package, where it looks for resources such as templates and static files.

c) We then use the route() decorator to tell Flask which URL should trigger the function i.e the decorator tells the @app that whenever a user visits the app domain at the given .route(for eg. /prediction), execute the prediction() function. In addition to accepting the URL of a route as a parameter, the @app.route() decorator can accept a second argument, a list of HTTP methods. In my application I used POST method to send the customer data.

d) To access the incoming data in Flask inside the prediction(), we have to use the request object. request.get_json() converts the JSON object into Python object. The function jsonify() returns the response in the JSON format.

e) Finally, the run() method runs the application. The default Host it listens on is local host(127.0.0.1) and in my application the Host is set to ‘0.0.0.0’ so that server is available externally.

The code for the above steps is shown below:

#import transformers
from transformers import pipeline

import pickle
with open('./model.pkl', 'rb') as model_pkl:
    model = pickle.load(model_pkl)
        
# Import Flask for creating API
from flask import Flask, request,jsonify

# Initialise a Flask object
app = Flask(__name__)

# Create an API endpoint for predicting
@app.route('/predict')

def predict():
# return the result back
    return  "predict"
    
@app.route('/prediction', methods=['POST'])
def prediction():
    data = request.get_json(force=True)
    s1=data['s']
    result = model(s1)[0]
    final = {"Label:": result['label'],
                 "Confidence Score:":result['score']
           }
    return jsonify(final)

if __name__ == '__main__':
     app.run(host='0.0.0.0', port=5000)

Now we can run the app on the local host with the following command on command line or anaconda cmd.

python app.py

Now that the app is running on the local host and we can make inferences from the app by giving some input text using cURL commands as shown below.

curl -H "Content-Type: application/json" http://127.0.0.1:5000/prediction -d "{\"s\" : \"I enjoy studying computational algorithms\"}"

The result of the above prediction is Positive with a confidence score of 0.99 as shown below:

{"Confidence Score:":0.998389720916748,"Label:":"POSITIVE"}

It is tested with an another input:

curl -H "Content-Type: application/json" http://127.0.0.1:5000/prediction -d "{\"s\" : \"This Challenge is Terrifying!\"}"

The result of the above prediction is Negative with a confidence score of 0.98.

{"Confidence Score:":0.983649492263794,"Label:":"NEGATIVE"}

3) Dockerfile

This step is all about building a Dockerfile with base image as Ubuntu:18.04 and Conda environment to manage all Python dependencies with the specifications as provided in the environment.yml file which is shown as below:

name: test
channels:
- conda-forge
- defaults
- pytorch
dependencies:
- pip
- python=3.6
- pytorch
- transformers
- flask

A brief about Ubuntu and Conda.

Ubuntu is an open source Linux operating system distribution that runs on the desktop,cloud and on internet connected things.

Conda is an open source package management system and environment management system that runs on Windows, macOS and Linux. Conda quickly installs, runs and updates packages and their dependencies. Conda easily creates, saves, loads and switches between environments on your local computer. It was created for Python programs, but it can package and distribute software for any language.

Conda as a package manager helps you find and install packages. If you need a package that requires a different version of Python, you do not need to switch to a different environment manager, because Conda is also an environment manager. With just a few commands, you can set up a totally separate environment to run that different version of Python, while continuing to run your usual version of Python in your normal environment.

The Dockerfile for my application is as follows and I will explain the instructions of this file.

#Base Image
FROM ubuntu:18.04

# Update Ubuntu image and install curl package
RUN apt-get update && apt-get install -y curl

# Install miniconda to /miniconda
RUN curl -LO http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh
RUN bash Miniconda3-latest-Linux-x86_64.sh -p /miniconda -b
RUN rm Miniconda3-latest-Linux-x86_64.sh
ENV PATH=/miniconda/bin:${PATH}
RUN conda update -y conda

WORKDIR /app
COPY . /app

# Create the environment:
COPY environment.yml .
RUN conda env create -f environment.yml

# Make RUN commands use the new environment:
SHELL ["conda", "run", "-n", "test", "/bin/bash", "-c"]

# The code to run when container is started:
COPY app.py .
ENTRYPOINT ["conda", "run", "--no-capture-output", "-n", "test", "python", "app.py"]

Docker starts building the new image taking Ubuntu:18.04 as base image:

FROM ubuntu:18.04

Ubuntu base image is updated and cURL is installed using below:

RUN apt-get update && apt-get install -y curl

Below command downloads the latest Miniconda3 and installs it. The installer is deleted after installation. The ENV command sets the path for conda and finally, conda package is updated to keep it up-to-date for future.

RUN curl -LO http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh                       
RUN bash Miniconda3-latest-Linux-x86_64.sh -p /miniconda -b                       RUN rm Miniconda3-latest-Linux-x86_64.sh                       
ENV PATH=/miniconda/bin:${PATH}                       
RUN conda update -y conda

Below command creates a working directory /app for the Docker Image:

WORKDIR /app

Below command copies all the files from your local directory to /app directory:

COPY . /app

Below command copies the environment.yml file to the /app directory and conda reads the environment variables specified in environment.yml file to create a new conda environment in the container.

COPY environment.yml .                      
RUN conda env create -f environment.yml

Run command uses the new conda environment.

SHELL ["conda", "run", "-n", "test", "/bin/bash", "-c"]

Copy app.py to the /app directory on container and the app.py runs in the conda env when the container starts.

COPY app.py .                       
ENTRYPOINT ["conda", "run", "--no-capture-output", "-n", "test", "python", "app.py"]

4) Docker Compose

There are two ways to build and run a Docker Image

a) docker build and docker run

b) create a docker-compose.yml file and use docker-compose up command

In this work, I used docker compose to build and run the Docker Image

Before going into the process of building and running Image let us see

What is a Docker-compose?

Docker-compose is a tool for defining and running multi-container docker applications. With compose, you use a yml file to configure the applications and services. The advantage of the docker compose is that with a single command, we can create and start all the services from our configuration. Here is the docker-compose.yml file for my application.

version : "3.7"
services:
  app:
    build: .
    container_name: arq_test
    restart: always
    ports:
     - "5000:5000"

It’s version is 3.7, runs one service called app, the container name is arq_test and host port are mapped to the container port:

docker Image can be built and run using single command

docker-compose up

The snapshot of docker image build and running process is shown below:

5) test_service.sh

Now that my sentiment analysis app is running in the conda env inside the docker container, we can test the inferences app using cURL commands. The cURL commands are written in a bash script file named test_servcie.sh

test_service.sh file is:

#!/bin/bash
curl -H "Content-Type: application/json" http://0.0.0.0:5000/prediction -d @pos.json
curl -H "Content-Type: application/json" http://0.0.0.0:5000/prediction -d @neg.json

pos.json file is:

{
"s":"This challenge is lots of fun!"
}

neg.json file is:

{
"s":"This challenge is terrifying!"
}

The results of the prediction are the confidence score and Label.


Reproduced with permission
Author: Srinivas Pratapgiri (Goanna student)
Source: https://srinipratapgiri.medium.com/sentiment-analysis-on-customer-data-microservice-deployed-in-conda-environment-on-a-docker-7e9f63439c96

Recommended Posts

No comment yet, add your voice below!


Add a Comment

Your email address will not be published. Required fields are marked *