DEV Community

Cover image for Servir un modèle lourd sans faire exploser la facture serveur
Amine Affif
Amine Affif

Posted on

Servir un modèle lourd sans faire exploser la facture serveur

Un modèle d'IA est lourd et gourmand. Servi sans précaution, il fait exploser les temps de réponse et la facture serveur. Sur un SaaS d'analyse audio que j'ai conçu et mis en ligne seul, il fallait que ça reste rapide, sécurisé et tenable économiquement.

La décision d'hébergement. J'ai servi le modèle sur un serveur que je gère, avec NGINX et un nettoyage automatique des fichiers, plutôt que sur une infrastructure facturée à l'usage. Ça demande plus de travail de déploiement, mais la facture ne suit plus le nombre d'analyses. Elle se prévoit.

Côté code, deux règles comptent pour un service de ce type.

1. Charger le modèle une seule fois, au démarrage. Pas à chaque requête. Avec FastAPI, c'est le rôle du paramètre lifespan. L'application ne reçoit pas de requêtes tant que le démarrage n'est pas terminé.

from contextlib import asynccontextmanager
from fastapi import FastAPI

models = {}

@asynccontextmanager
async def lifespan(app: FastAPI):
    models["main"] = load_model()  # lent : fait une seule fois
    yield
    models.clear()

app = FastAPI(lifespan=lifespan)
Enter fullscreen mode Exit fullscreen mode

L'ancienne méthode, on_event, est dépréciée.

2. Ne pas bloquer le serveur pendant un calcul. Une fonction async def qui calcule longtemps bloque toute l'application. Une fonction def est exécutée par FastAPI dans un pool de threads.

@app.post("/analyze")
def analyze(file: UploadFile):  # def : exécuté dans un pool de threads
    return models["main"].predict(file)
Enter fullscreen mode Exit fullscreen mode

C'est ainsi que le modèle tourne en production sur ce SaaS.

Amine Affif, développeur full-stack à Paris. amineaffif.com

Top comments (0)