Building a Real-Time Sentiment Analysis Web App with Flask, TensorFlow, and DistilBERT

Soumyadip Sarkar
5 min readOct 30, 2024

In recent years, sentiment analysis has become crucial for understanding customer feedback, tracking public opinion, and enhancing user experiences in applications. With advancements in machine learning, transformer-based models like BERT and its leaner sibling, DistilBERT, have taken NLP to the next level. DistilBERT’s compact size makes it faster and more efficient, offering a solid balance between accuracy and speed. Today, we’re going to build a web-based sentiment analysis tool using Hugging Face’s DistilBERT, Flask, and TensorFlow, containerized with Docker for smooth deployment. I’ll walk you through each step, from setup to overcoming common challenges, including memory management and containerization.

Why Use DistilBERT for Sentiment Analysis?

Sentiment analysis involves identifying the tone of text — positive, negative, or neutral. Think of analyzing movie reviews, customer service feedback, or social media posts. With DistilBERT, a smaller, distilled version of the BERT model, we’re able to capture nuanced sentiment while optimizing for faster response times. DistilBERT retains about 97% of BERT’s accuracy but is significantly faster and more memory-efficient, making it ideal for real-time applications like this one.

Our end goal here is to build a Flask web application that uses DistilBERT to classify user-submitted text as positive or negative. We’ll also be using Docker to ensure our app runs consistently across environments.

Setting Up the Project

Let’s start by organizing our project files. Here’s the structure we’ll follow:

.
├── app.py # Main Flask application
├── Dockerfile # Docker configuration
└── templates
└── index.html # HTML template for the web interface

Each file plays a unique role in this project:

  • app.py: This is our Flask app, where the core logic for loading DistilBERT and handling user requests lives.
  • Dockerfile: This file tells Docker how to build and run our application in a container.
  • index.html: A simple HTML form that allows users to input text for sentiment analysis.

Building the Flask Application

To start, let’s dive into app.py, the core of our web app.

app.py

from flask import Flask, request, render_template
from transformers import TFAutoModelForSequenceClassification, AutoTokenizer
import tensorflow as tf

app = Flask(__name__)

model_name = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = TFAutoModelForSequenceClassification.from_pretrained(model_name)

def preprocess(text):
inputs = tokenizer(text, return_tensors="tf", truncation=True, padding=True, max_length=512)
return inputs

def predict_sentiment(text):
inputs = preprocess(text)
outputs = model(inputs)
logits = outputs.logits
predicted_class = tf.math.argmax(logits, axis=-1).numpy()[0]

if predicted_class == 1:
return "Positive"
else:
return "Negative"

@app.route("/", methods=["GET", "POST"])
def index():
sentiment = ""
if request.method == "POST":
text = request.form["text"]
sentiment = predict_sentiment(text)
return render_template("index.html", sentiment=sentiment)

if __name__ == "__main__":
app.run(debug=True)

How It Works:

  1. Loading the Model: The app initializes both the tokenizer and DistilBERT model from Hugging Face.
  2. Preprocessing the Text: The preprocess function tokenizes and pads the text so it’s compatible with the model’s input requirements.
  3. Predicting Sentiment: The model predicts sentiment (positive or negative) based on the processed text.
  4. Setting Up Routes: Our Flask app listens for POST requests, processes the input text, and returns the sentiment result.

Creating the HTML Template

Our web form is minimalistic, providing users with a single text field to enter input and submit it for analysis and using TailwindCSS.

index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sentiment Analysis</title>
<link
href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css"
rel="stylesheet"
/>
</head>
<body class="bg-gray-100 flex items-center justify-center h-screen">
<div class="w-full max-w-md bg-white rounded-lg shadow-md p-8">
<h1 class="text-2xl font-bold text-center mb-6">Sentiment Analysis</h1>
<form method="post">
<textarea
name="text"
rows="4"
cols="50"
placeholder="Enter a sentence"
class="w-full p-3 border border-gray-300 rounded mb-4"
></textarea>
<button type="submit" class="w-full bg-blue-500 text-white p-3 rounded">
Analyze
</button>
</form>
{% if sentiment %}
<div class="mt-4 p-3 border-t border-gray-300">
<h2 class="text-xl font-semibold">
Sentiment: <span class="font-normal">{{ sentiment }}</span>
</h2>
</div>
{% endif %}
</div>
</body>
</html>

Dockerizing the App

With the Flask app set up, let’s make it portable with Docker. Containerizing our application allows us to run it consistently across different systems.

Dockerfile

# Use an official Python runtime as a parent image
FROM python:3.9-slim

# Set the working directory in the container
WORKDIR /app

# Copy the current directory contents into the container at /app
COPY . /app

# Install dependencies
RUN pip install --no-cache-dir flask tensorflow transformers

# Expose port 5000 for Flask
EXPOSE 5000

# Run the Flask app
CMD ["python", "app.py"]

To build and run the container:

  1. Build the Docker Image: docker build -t flask-sentiment-app .
  2. Run the Docker Container: docker run -p 5000:5000 flask-sentiment-app

With these commands, you should be able to access the Flask app at http://localhost:5000

Handling Out-of-Memory (OOM) Errors

When using memory-intensive models, OOM errors are common. Here’s how to mitigate them:

  1. Reduce Input Length: Set max_length to 256 or even 128 in the preprocess function to reduce memory use.
  2. Upgrade Memory: If using a cloud service, consider upgrading to an instance with more RAM.
  3. Force CPU Usage: Disable GPU to avoid memory allocation issues by adding os.environ["CUDA_VISIBLE_DEVICES"] = "-1".
  4. Enable Memory Growth for TensorFlow:
physical_devices = tf.config.experimental.list_physical_devices('GPU')
for device in physical_devices:
tf.config.experimental.set_memory_growth(device, True)

Testing the App

To test, simply type a sentence in the form and submit. You’ll get the sentiment displayed below the input area. Make sure the app is running smoothly in Docker and handling requests without crashing.

Going Beyond: Making the App Production-Ready

Here are a few steps to make this app production-ready:

  • Add Logging: Log user inputs and system errors for debugging and monitoring.
  • Implement Authentication: If you’re deploying publicly, secure the app.
  • Test Across Platforms: Ensure consistent performance in different environments.
  • Deploy with Kubernetes: Use container orchestration tools like Kubernetes for scalable deployment.

Wrapping Up

And there you have it — a fully functional sentiment analysis web app built with Flask and DistilBERT, and neatly containerized with Docker. This tool has real-world applications, from analyzing customer feedback to enhancing user engagement. Plus, containerization makes it flexible and easy to deploy anywhere.

With a few optimizations, this sentiment analysis app can scale and adapt, bringing NLP capabilities to production environments efficiently. Whether you’re exploring NLP for the first time or looking to integrate machine learning into a project, building something like this is a fantastic way to understand the power of sentiment analysis and transformers.

Let’s keep building, experimenting, and pushing the limits of what we can do with AI and machine learning!

By following this guide, you’ll have created a powerful, deployable app that brings sentiment analysis to life. Good luck, and happy coding!

--

--

Soumyadip Sarkar
Soumyadip Sarkar

Written by Soumyadip Sarkar

Independent Researcher & Software Engineer

No responses yet