Day 21 - Deploy a Machine Learning Model Using FastAPI and Heroku for Real-Time Predictions

Today’s challenge was focused on deploying a machine learning model for real-time predictions. I chose to deploy our Day 8 problem of Fake News Detection model using FastAPI as the API framework and Heroku for hosting the app.

If you want to see the code, you can find it here: GIT REPO.

Tools & Technologies

  • FastAPI: For building the API.
  • Heroku: For deploying the app.
  • Scikit-learn: For the machine learning model (PassiveAggressive Classifier and TfidfVectorizer).
  • Pickle: To save and load the trained model and vectorizer.
  • Uvicorn: ASGI server for running FastAPI apps.

The Model

For this project, I used a PassiveAggressive Classifier with a TfidfVectorizer to detect fake news articles. The dataset included two categories: True News and Fake News. Here’s a step-by-step guide on how to complete this task, starting with training the model (we already explored this in the Day 8 problem, so please refer to that post before proceeding), followed by creating a FastAPI app and deploying it on Heroku.

Steps for Full Flow:

Step 1: Finalize and Save the Model

Since you have already built and trained the model, the next step is to save it along with the TfidfVectorizer using pickle. This will allow us to load the model and vectorizer in the FastAPI app.

import pickle

# Save the trained model
with open('model.pkl', 'wb') as model_file:
    pickle.dump(model, model_file)

# Save the TF-IDF vectorizer
with open('tfidf_vectorizer.pkl', 'wb') as vec_file:
    pickle.dump(tf_idf_vectorizer, vec_file)

print("Model and vectorizer saved!")

After running the script this will save your model (model.pkl) and the vectorizer (tfidf_vectorizer.pkl) so they can be loaded in the FastAPI application.

Step 2: Create the FastAPI App

Next, create a FastAPI app that will load the trained model and vectorizer, and provide an endpoint for users to submit news articles and receive predictions.

Directory structure:

fake-news-api/
│
├── main.py              # FastAPI app
├── model.pkl            # Saved PassiveAggressiveClassifier model
├── tfidf_vectorizer.pkl  # Saved TfidfVectorizer
├── requirements.txt      # Python dependencies
├── Procfile              # Heroku process file
└── runtime.txt           # Specify Python version

main.py:

from fastapi import FastAPI
from pydantic import BaseModel
import pickle
import numpy as np

# Initialize FastAPI app
app = FastAPI(title="Fake News Detection API", version="1.0")

# Load the saved model and vectorizer
with open("model.pkl", "rb") as model_file:
    model = pickle.load(model_file)

with open("tfidf_vectorizer.pkl", "rb") as vec_file:
    tfidf_vectorizer = pickle.load(vec_file)

# Define the request body structure using Pydantic
class NewsArticle(BaseModel):
    text: str

# Define the prediction endpoint
@app.post("/predict")
def predict_fake_news(article: NewsArticle):
    # Vectorize the incoming text
    vectorized_text = tfidf_vectorizer.transform([article.text])

    # Make a prediction
    prediction = model.predict(vectorized_text)

    # Return the result
    result = "Fake" if prediction[0] == 0 else "True"
    return {"prediction": result}

# Home route
@app.get("/")
def read_root():
    return {"message": "Welcome to the Fake News Detection API! Visit /docs for Swagger documentation."}

Step 3: Prepare requirements.txt

You need to list all the dependencies your project needs in a requirements.txt file:

fastapi
uvicorn
scikit-learn
pandas
numpy
gunicorn

Step 4: Run the application Locally

You can run the FastAPI application using Uvicorn. To do so, open your terminal or command prompt and navigate to the directory containing main.py. Then, run:

uvicorn main:app --reload

This will:

  • Start the FastAPI server.
  • Automatically reload the server if you make any changes to the code.
  • Run the app at http://127.0.0.1:8000/.
  • Open your browser and navigate to http://127.0.0.1:8000/. You should see the welcome message from your API.
  • To explore and test the API, go to http://127.0.0.1:8000/docs. This will show an interactive Swagger UI where you can test the /predict endpoint by submitting a news article’s text.

Testing the API

The API was tested using several news articles for both real and fake news categories. Here are a few examples:

  • Example 1: Real News

    • Text: “The U.S. Congress passed a $1.9 trillion COVID-19 relief package on Wednesday, aimed at providing economic aid to millions of Americans impacted by the pandemic.”
    • Prediction: True
  • Example 2: Fake News

    • Text: “Aliens have landed on Earth and established a base in Antarctica. Government officials are working with them to develop advanced technology.”
    • Prediction: Fake

What to Do After Testing Locally

Once everything is working as expected on your local machine, you’re ready to push the app to Heroku for deployment.

For that, set up requirements.txt, Procfile, and push your code to Heroku.

Create the Procfile

Heroku needs a Procfile to understand how to run your application:

web: gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app
  • -w 4: This specifies 4 worker processes for handling multiple requests.
  • -k uvicorn.workers.UvicornWorker: Uses Uvicorn workers to handle the ASGI app.

Specify the Python Version

Optionally, you can create a runtime.txt file to specify the Python version you want to use:

python-3.9.12

Now, initialize Git and Push to Heroku.

Gratitude

This was the first problem involving integration with an external FastAPI application. I learned how to store the trained model and later use it for external applications. I also explored the deployment process. Looking forward to the next day

Stay Tuned!

Posts in this series