For AI agents: the complete documentation index is available at https://docs.ovhcloud.com/fr/llms.txt, the full documentation bundle is available at https://docs.ovhcloud.com/fr/llms-full.txt, and this page is available as Markdown at https://docs.ovhcloud.com/fr/guides/public-cloud/ai-machine-learning/ai-deploy-web-service-yolov5.md.

AI Deploy - Tutoriel - Déployer un service web pour YOLOv5 en utilisant Flask

Voir en Markdown

Comment déployer un service web pour YOLOv5 en utilisant vos propres paramètres de valeurs avec Flask

Info

AI Deploy est couvert par les Conditions particulières OVHcloud Public Cloud.

Objectif

L'objectif de ce tutoriel est de montrer comment déployer un service web pour YOLOv5 en utilisant vos propres poids générés après l'entraînement d'un modèle YOLOv5 sur votre jeu de données.

Pour cela, vous allez utiliser Flask, un micro-framework open source pour le développement web en Python. Vous apprendrez également à construire et à utiliser une image Docker personnalisée pour une application Flask.

Pour plus d'informations sur la façon d'entraîner YOLOv5 sur un jeu de données personnalisé, reportez-vous à la documentation suivante.

Prérequis

  • un projet AI Deploy créé au sein d'un projet Public Cloud
  • un utilisateur pour AI Deploy
  • Docker installé sur votre ordinateur local
  • quelques connaissances sur la construction d'images et les Dockerfile
  • vos poids obtenus après l'entraînement d'un modèle YOLOv5 sur votre jeu de données (reportez-vous à la partie « Export trained weights for future inference » du notebook pour YOLOv5)

En pratique

Tout d'abord, l'arborescence de votre dossier doit être la suivante.

Sortie de la commande tree du projet de service web listant Dockerfile app.py requirements.txt un dossier models_train avec yolov5m_100epochs.pt et yolov5s_100epochs.pt un dossier static avec bandeau.png et style.css et un dossier templates avec index.html
  • Vous devez créer le dossier nommé models_train, c'est là que vous pourrez stocker les poids générés après vos entraînements. Vous êtes libre de placer autant de fichiers de poids que vous le souhaitez dans le dossier models_train.

  • Nous allons ici principalement voir comment écrire le code app.py, le fichier requirements.txt et le Dockerfile. Si vous souhaitez voir le code complet, reportez-vous au dépôt GitHub.

Écrire l'application Flask

Créez un fichier Python nommé app.py.

À l'intérieur de ce fichier, importez les modules requis :

import sys
import io
from PIL import Image
import cv2
import torch
from flask import Flask, render_template, request, make_response
from werkzeug.exceptions import BadRequest
import os

Créez l'app Flask :

app = Flask(__name__)

Chargez vos propres poids :

Ici, un dictionnaire python est créé pour stocker le nom de chacun de vos fichiers de poids (clé) et le modèle correspondant (valeur).

# create a python dictionary for your models d = {<key>: <value>, <key>: <value>, ..., <key>: <value>}
dictOfModels = {}
# create a list of keys to use them in the select part of the html code
listOfKeys = []

Écrivez la fonction d'inférence :

def get_prediction(img_bytes,model):
    img = Image.open(io.BytesIO(img_bytes))
    # inference
    results = model(img, size=640)  
    return results

Définissez la méthode GET :

@app.route('/', methods=['GET'])
def get():
  # in the select we will have each key of the list in option
  return render_template("index.html", len = len(listOfKeys), listOfKeys = listOfKeys)

Définissez la méthode POST :

@app.route('/', methods=['POST'])
def predict():
    file = extract_img(request)
    img_bytes = file.read()
    # choice of the model
    results = get_prediction(img_bytes,dictOfModels[request.form.get("model_choice")])
    print(f'User selected model : {request.form.get("model_choice")}')
    # updates results.imgs with boxes and labels
    results.render()
    # encoding the resulting image and return it
    for img in results.ims:
        RGB_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        im_arr = cv2.imencode('.jpg', RGB_img)[1]
        response = make_response(im_arr.tobytes())
        response.headers['Content-Type'] = 'image/jpeg'
    return response

def extract_img(request):
    # checking if image uploaded is valid
    if 'file' not in request.files:
        raise BadRequest("Missing file parameter!")
    file = request.files['file']
    if file.filename == '':
        raise BadRequest("Given file is invalid")
    return file

Définissez le main et démarrez votre app :

if __name__ == '__main__':

    print('Starting yolov5 webservice...')
    # Getting directory containing models from command args (or default 'models_train')
    models_directory = 'models_train'
    if len(sys.argv) > 1:
        models_directory = sys.argv[1]
    print(f'Watching for yolov5 models under {models_directory}...')
    for r, d, f in os.walk(models_directory):
        for file in f:
            if ".pt" in file:
                # example: file = "model1.pt"
                # the path of each model: os.path.join(r, file)
                model_name = os.path.splitext(file)[0]
                model_path = os.path.join(r, file)
                print(f'Loading model {model_path} with path {model_path}...')
                dictOfModels[model_name] = torch.hub.load('ultralytics/yolov5', 'custom', path=model_path, force_reload=True)
                # you would obtain: dictOfModels = {"model1" : model1 , etc}
        for key in dictOfModels :
            listOfKeys.append(key) # put all the keys in the listOfKeys

    # starting app
    app.run(debug=True,host='0.0.0.0')

Trouvez plus d'informations sur l'application Flask ici pour être prêt à l'utiliser.

Écrire le fichier requirements.txt de l'application

Le fichier requirements.txt nous permettra d'indiquer tous les modules nécessaires au fonctionnement de notre application. Ce fichier sera utile lors de l'écriture du Dockerfile.

Flask==2.1.0
torch==1.13.1
torchvision==0.14.1
psutil==5.9.4
IPython==8.8.0
requests==2.28.2
PyYAML==6.0
tqdm==4.64.1
pandas==1.5.2
opencv-python-headless==4.6.0.66
matplotlib==3.6.3
seaborn==0.12.2

Écrire le Dockerfile de l'application

Votre Dockerfile doit commencer par l'instruction FROM indiquant l'image parente à utiliser. Dans notre cas, nous choisissons de partir d'une image python:3.8 :

FROM python:3.8

Créez le répertoire personnel et ajoutez-y vos fichiers :

WORKDIR /workspace
ADD . /workspace

Installez le fichier requirements.txt qui contient les modules Python nécessaires à l'aide d'une commande pip install ... :

RUN pip install -r requirements.txt

Définissez votre commande de lancement par défaut pour démarrer l'application :

CMD [ "python" , "/workspace/app.py" ]

Attribuez les droits d'accès corrects à l'utilisateur ovhcloud (42420:42420) :

RUN chown -R 42420:42420 /workspace
ENV HOME=/workspace

Construire l'image Docker depuis le Dockerfile

Depuis le répertoire contenant votre Dockerfile, exécutez l'une des commandes suivantes pour construire l'image de votre application :

# Build the image using your machine's default architecture
docker build . -t flask-yolov5:latest

# Build image targeting the linux/amd64 architecture
docker buildx build --platform linux/amd64 -t flask-yolov5:latest .
  • La première commande construit l'image en utilisant l'architecture par défaut de votre système. Cela peut fonctionner si votre machine utilise déjà l'architecture linux/amd64, qui est requise pour exécuter des containers avec nos produits AI. Cependant, sur des systèmes avec une architecture différente (par exemple ARM64 sur Apple Silicon), l'image résultante ne sera pas compatible et ne pourra pas être déployée.

  • La seconde commande cible explicitement l'architecture linux/amd64 afin de garantir la compatibilité avec nos services AI. Elle nécessite buildx, qui n'est pas installé par défaut. Si vous n'avez jamais utilisé buildx auparavant, vous pouvez l'installer en exécutant : docker buildx install

Info

L'argument point . indique que votre contexte de build (emplacement du Dockerfile et des autres fichiers nécessaires) est le répertoire courant.

L'argument -t vous permet de choisir l'identifiant à donner à votre image. Les identifiants d'image sont généralement composés d'un nom et d'un tag de version <name>:<version>. Pour cet exemple, nous avons choisi flask-yolov5:latest.

Tester en local (optionnel)

Lancez la commande Docker suivante pour lancer votre application localement sur votre ordinateur :

docker run --rm -it -p 5000:5000 --user=42420:42420 flask-yolov5:latest
Info

L'argument -p 5000:5000 indique que vous souhaitez exécuter une redirection de port depuis le port 5000 de votre machine locale vers le port 5000 du container Docker. Le port 5000 est le port par défaut utilisé par les applications Flask.

Warning

N'oubliez pas l'argument --user=42420:42420 si vous souhaitez simuler exactement le même comportement que celui qui se produira sur les apps AI Deploy. Il exécute le container Docker en tant qu'utilisateur OVHcloud spécifique (utilisateur 42420:42420).

Une fois démarrée, votre application devrait être disponible sur http://localhost:5000.

Envoyer l'image vers le registre partagé

Warning

Le registre partagé ne doit être utilisé qu'à des fins de test. Pensez à créer et à rattacher votre propre registre. Plus d'informations à ce sujet sont disponibles ici. Les images envoyées vers ce registre sont réservées aux workloads AI Tools et ne seront pas accessibles pour des usages externes.

Trouvez l'adresse de votre registre partagé en lançant cette commande :

ovhai registry list

Connectez-vous au registre partagé avec vos identifiants habituels d'utilisateur AI Platform :

docker login -u <user> -p <password> <shared-registry-address>

Envoyez l'image compilée vers le registre partagé :

docker tag flask-yolov5:latest <shared-registry-address>/flask-yolov5:latest
docker push <shared-registry-address>/flask-yolov5:latest

Lancer l'app AI Deploy

La commande suivante démarre une nouvelle app exécutant votre application Flask :

ovhai app run --default-http-port 5000 --cpu 4 <shared-registry-address>/flask-yolov5:latest
Info

--default-http-port 5000 indique que le port à atteindre sur l'URL de l'app est le 5000.

Info

--cpu 4 indique que nous demandons 4 CPU pour cette app.

Info

Pensez à ajouter l'attribut --unsecure-http si vous souhaitez que votre application soit accessible sans authentification.

Aller plus loin

  • Vous pouvez imaginer déployer une app Flask afin de classifier les sentiments dans un texte. Reportez-vous à ce tutoriel.
  • Une autre façon de créer une app AI Deploy est d'utiliser Streamlit ! C'est par ici.

Si vous avez besoin d'une formation ou d'une assistance technique pour la mise en oeuvre de nos solutions, contactez votre commercial ou cliquez sur ce lien pour obtenir un devis et demander une analyse personnalisée de votre projet à nos experts de l’équipe Professional Services.

Votre avis nous intéresse !

N'hésitez pas à nous faire part de vos questions, retours et suggestions pour améliorer le service :

Cette page vous a-t-elle aidé ?