Deploy Deep Learning or Machine Learning Model using Flask on Heroku
What does deploying a model mean?
The process of taking a trained Deep Learning or machine learning model and making its predictions available to users is known as Model Deployment. so, first train the model using the Colab or local machine and then deploy the model.
Deploying to Heroku with Flask
Flask is one of the quickest and easiest ways to deploy your work. flask gives more control on your application. There are other options available to deploy your Model using Jupyter notebook like anvil , ipywidgets but we will go with flask.
It is an option on various deployment platforms, one of which is Heroku. Heroku gives you different options for how to create your web application, including proper web applications in Python, Ruby, PHP, etc but in this guide we are simply going to create a free account and deploy your first model using flask and heroku CLI.
Prerequisites
- You should have an exported model and which functions as your demo. i have Object Detection Model it can detect up to 80 objects.
- create a free account on Heroku
- The Heroku Command Line Interface (CLI) makes it easy to create and manage your Heroku apps directly from the terminal. It’s an essential part of using Heroku.
- The Heroku CLI requires Git
Let's Start
we will devide this guide in two parts:
- STEP 1: flask app setup
- STEP 2: Deploy
NOTE: you can skip to STEP 2 if you have already setup your flask app.
STEP 1: flask app setup
if you are new to flask or lazy to design forntend of web app than you can follow my design. we will see what needs to be changed but before going to that let's Look at how web app is going to looks like : object Detection
copy your all Model code in single python Module(file) and define function that is responsible for predictions of input. in my case i have define one function detect that take image name as argument and run detection on it and save result in uploads directory.you can download all files from Here.
@app.route('/', methods=['POST'])
def upload_image():
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
if file.filename == '':
flash('No image selected for uploading')
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
# replace this function
detect(file.filename,False)
#print('upload_image filename: ' + filename)
flash('Image successfully uploaded and displayed below')
return render_template('index.html', filename=filename)
else:
flash('Allowed image types are - png, jpg, jpeg')
return redirect(request.url)
In above given app.py:upload_image() you just need to change one line detect(file.filename,False) with yours if you are building image classifier. when user click on submit button it will save image in uploads directory and run your algorithm on it and again save that image(in case of image classifier) in uploads directory to serve it to user.
It's better to give some examples to user. by one Click user can see what your model does. e.g. i have given 3 Try it example.
STEP 2: Deploy
Creating your Git repo. What do you need?
You project needs to be in a Git repository as we’re going to tell Heroku to copy it from there, and the simplest way to get your demo deployed is to have everything you need in your repo (unless you start getting close to the size limit which we will discuss at the end).
Let's see, minimum you need in your directory is as follows:
- app.py
- Procfile
- requirements.txt
- your model's weight file that you have exported after model trained.
- Any other files you use (eg: images to make your demo UI pretty)
Here is my directory structure:
app.py
it's your main file that responsible for your app's working. it may import your model and essential imports.
Procfile
Your Procfile (process file) only needs to contain 1 line, and it tells Heroku what kind of application to create.
web: gunicorn app:app
you should be aware of that, Procfile dosen't have any file extension. sometimes people save it as .txt file and than get's Error. you can check that in above directory structure image.
requirements.txt
When you deploy your application, Heroku builds a server image, essentially one giant file that it can quickly copy onto
a server when someone wants to run your app. All of the packages you need must be specified in your requirements.txt. That
means all of the things you pip install
at the top of your any python file should be moved to here (plus any packages you use which
your particular platform makes available by default). mine is given below:
click==8.0.1
colorama==0.4.4
cycler==0.10.0
Flask==2.0.1
Flask-SQLAlchemy==2.5.1
greenlet==1.1.0
gunicorn==20.1.0
itsdangerous==2.0.1
Jinja2==3.0.1
kiwisolver==1.3.1
MarkupSafe==2.0.1
matplotlib==3.4.2
numpy==1.20.3
opencv-python-headless==4.5.2.52
Pillow==8.2.0
pyparsing==2.4.7
python-dateutil==2.8.1
six==1.16.0
SQLAlchemy==1.4.17
you can easly generate this file: open command prompt and navigate to project directory and run below command:
pip freeze > requirements.txt
But problem with pip freeze
is that, it will write all available libraries in your environment rather than only import libraries. you can also use pigar
for this task it will only write your import requirements.
NOTE: if you are using opencv-python in your model than you needs to make changes in requirements.txt file. change line opencv-python==version to opencv-python-headless==version
500 MB "slug" limit
Heroku limits the size of the final "slug" as they call it (the server image they create) to 500 MB, and that includes all of the libraries you use along with all of their dependancies, so what you thought was quite a small project, may well be closer to the limit than you expected.
Most basic beginner projects should be fine but if you do need to reduce the size of your server image (especially once you start hosting multiple demo projects), you can store your model exports (and any other large files) on Google Drive or Dropbox or somewhere similar, and load them across from there.
import urllib.request
MODEL_URL = "https://drive.google.com/uc?export=download&id=YOUR_FILE_ID"
urllib.request.urlretrieve(MODEL_URL, "filename.weights")
learner = load_learner(Path("."), "filename.weights")
NOTE: Mostly we create virtual environment(python venv) to develope flask app. it's better to delete that folder when you are deploying your model. it will help you to decrease slug size.
Step 1: Open command prompt and Navigate to flask app directory. login to your heroku account.
heroku login
Step 2: initialize empty Git repository.
git init
Step 3: if your file is large than 100MB than it's better to use Git LFS tool. if your file is smaller than 100MB, than no needs to run below commands.
git lfs track '*.weights'
git add .gitattributes
Step 4: Commit changes to Git.
git add .
git commit -m "initial commit"
Step 5: Create heroku app and give it unique name. if you get error of name than try to give another name and try again.
heroku create "objdetect"
NOTE : Name must start with a letter, end with a letter or digit and can only contain lowercase letter and dashes.
You can check that we are using heroku's Git version control
git remote -v
Step 6: Push all files to heroku
git push heroku master
After compeleting above operation you can see your slug size and url to access app.
Conclusion
Developing end-to-end Machine Learning web apps can be daunting. But this is a free, simpler, easier way to create demo web applications.