Déployer rapidement des modèles de ML avec FastAPI

Le déploiement de modèle de Machine learning (ML) est l’une des étapes les plus importantes dans un projet de ML. Pourquoi ? La réponse est bien évidente, car déployer un modèle consiste tout simplement à rendre ce modèle disponible dans un environnement (ex. de production) où il pourra fournir des prédictions à d’autres systèmes.
En effet, ce n’est qu’une fois les modèles déployés qu’ils commencent à ajouter de la valeur, ce qui fait du déploiement une étape cruciale.
Il y a plusieurs approches pour déployer un modèle, il est possible de l’embarquer directement dans une webapp (voir notre article sur streamlit) ou l’exposer via une API REST.

Dans cet article, nous vous présenterons comment déployer un modèle de ML avec FastApi (un modèle d’analyse de sentiments) et un conteneur docker.

Création du modèle d’analyse de sentiments

Nous allons réutiliser un modèle camembert pré-entrainé sur un jeu de données de commentaires récupérés sur Allociné. Je vous invite vivement à y faire un tour sur notre article Analyse De Sentiments Avec CamemBERT pour plus de détails. Ce modèle permet de déterminer si des phrases sont plutôt positives ou négatives.
Le code que nous allons utiliser est le suivant  :

from transformers import AutoTokenizer, TFAutoModelForSequenceClassification
from transformers import pipeline

tokenizer = AutoTokenizer.from_pretrained("tblard/tf-allocine", use_fast=True)
model = TFAutoModelForSequenceClassification.from_pretrained("tblard/tf-allocine")

nlp = pipeline('sentiment-analysis', model=model, tokenizer=tokenizer)

En effet, j’utilise un tokenizer et un modèle déjà disponible dans le Transformers 🤗. Je crée ensuite le pipeline adapté pour la suite.

Présentation de FastApi

FastAPI est un *nouveau* framework web pour construire des APIs avec Python 3.6+.
Les principales caractéristiques sont les suivantes :
– Rapide
– Une documentation interactive automatique.
– Basé sur les standards open-source des API : OpenAPI (précédemment connu sous le nom de Swagger) et JSON Schema.

Nous utiliserons donc ce framework pour notre api.

L’installation se fait comme suit :

pip install fastapi

On installe également un serveur ASGI ( Asynchronous Server Gateway Interface ), tels que Uvicorn.
Un serveur ASGI permet de fournir une interface standard entre les serveurs Web, les frameworks et les applications Python compatibles async.

pip install uvicorn

Création de notre api FastApi

Pour la création de notre api nous commençons par créer un fichier main.py contenant notre pipeline et nos différents endpoints.

import joblib
import re
#ml import
from transformers import AutoTokenizer, TFAutoModelForSequenceClassification
from transformers import pipeline
#Api import
from fastapi import FastAPI
from pydantic import BaseModel


# On crée notre instance FastApi puis on définit l'objet enstiment
app = FastAPI()
class Sentiment(BaseModel):
    sentiment: str
    sentiment_probability: float


# On crée notre pipeline
tokenizer = AutoTokenizer.from_pretrained("tblard/tf-allocine", use_fast=True)
model = TFAutoModelForSequenceClassification.from_pretrained("tblard/tf-allocine")

nlp = pipeline('sentiment-analysis', model=model, tokenizer=tokenizer)

# Nos différents endpoints

@app.get('/')
def get_root():
    return {'message': 'Welcome to the sentiment analysis API'}

@app.get('/predict/{message}',response_model=Sentiment)
async def predict(message: str):
   prediction_result = nlp(message)[0]
   return Sentiment(sentiment=prediction_result['label'], sentiment_probability=float(prediction_result['score']))

Ce script python importe d’abord les librairies nécessaires, définit un objet Sentiment, définit le pipeline NLP et les différents endpoints. Le endpoint (BASEURL/predict/) sera utilisé pour analyser le sentiment d’un texte en français. J’exécute le serveur avec la commande suivante :

uvicorn main:app 
# Vous pouvez aussi utiliser l'option --reload
# afin de redémarrer le serveur à chaque modification du code.
# Par défaut le serveur démarre sur le port 8000

La première chose à faire est de profiter de l’une des fonctionnalités la plus importante de FastApi : la documentation interactive (Swagger). Pour ce faire, on ouvre un navigateur et on rentre l’adresse (http://localhost:8000/docs). On voit les deux différents endpoints définis dans notre code.

On peut essayer de tester le endpoint root /.

Le serveur nous renvoie une réponse 200 avec le message approprié. Pas mal déjà 😉
Il est temps de tester notre endpoint /predict. J’utilise le texte suivant :

La vie est belle, il faut donc en profiter !

Notre api nous renvoie bien le sentiment de ce texte.

Création du conteneur Docker

Maintenant que nous avons une API fonctionnelle, nous pouvons facilement la déployer n’importe où sous la forme d’un conteneur Docker. Si vous ne connaissez pas Docker, il s’agit essentiellement d’un outil qui vous permet de packager et d’exécuter des applications dans des environnements isolés appelés conteneurs.

De plus, une image Docker est une représentation statique de l’application ou du service, de leur configuration et de leurs dépendances. Pour exécuter l’application ou le service, l’image Docker de l’application est instanciée, créant ainsi un conteneur.

En effet, Docker peut construire des images automatiquement en lisant les instructions d’un Dockerfile. Un Dockerfile est un fichier qui contient toutes les commandes qu’un utilisateur pourrait exécuter en ligne de commandes pour construire une image.

Nous créerons donc un Dockerfile pour notre api.

FROM tiangolo/uvicorn-gunicorn-fastapi:python3.8
COPY ./api /api
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
WORKDIR /api

Ce Dockerfile réutilise une image officielle de FastApi, copie le dossier dans lequel se trouve notre api puis installe les dépendances nécessaires qui sont définies dans le fichier requirements.txt.

On crée ensuite notre image docker avec la commande suivante :

docker build -t deploy-ml-fastapi .

Puis on instancie un conteneur.

docker run -d --name sentiment-analysis-api -p 80:80 deploy-ml-fastapi

Je vois dans Docker Desktop que mon conteneur est bien démarré sur le port 80.

On retrouvera notre Spécification OpenApi (documentation) interactive à l’adresse (http://localhost:80/docs).

Maintenant que l’API est exécutée dans un conteneur Docker, nous pouvons la déployer sur un large éventail de plateformes ! Si vous souhaitez aller plus loin dans ce projet, consultez les liens ci-dessous si vous souhaitez déployer cette API sur une plateforme Cloud.

How to Deploy Docker Containers on AWS
Deploy Docker Containers on Azure
Deploy Docker Containers on Google Cloud Platform

Le code source pour ce projet est disponible ici (deploy-ml-fastapi)

Sources

FastAPI framework, high performance, easy to learn, fast to code, ready for production
Conteneur, images et registres Docker

Conclusion

Dans cet article, nous avons présenté comment déployer un modèle de ML avec FastApi et un docker. J’ai longtemps utilisé Flask pour créer des apis en python, mais j’avoue que FastApi est un concurrent de taille !
Pour pousser l’exercice plus loin je vous conseille d’essayer de déployer ce conteneur docker sur une plateforme de Cloud public tel Google Cloud Platform ou Amazon Web services. Si vous êtes intéressés par ce dernier point, laissez un commentaire dans ce sens et nous ferons un tutoriel sur le déploiement de modèle de machine learning sur du Cloud public.

DockerFastApi
Commentaires (2)
Ajouter un commentaire
  • Denise SAGBO

    Bonjour mosieur. J’ ai éssayé FastAPI en suivant exactement vos instructions mais je suis bloqué au niveau du déployement en utlisant l’ image Docker.
    Quand j’ exécute le Dockerfile contenant les instructions, j’ obtient l’ erreure suivante:

    COPY failed: file not found in build context or excluded by .dockerignore: stat api: file does not exist

    Je voudrais demander où trouver les fichiers requirements.txt et api.

    J’ ai besoin de votre aide s’ il vous plait. J’ y suis bloqué depuis 4 jours.