Un modèle peut se dégrader sans qu’aucun serveur tombe

Un modèle peut perdre en qualité pendant que tous les serveurs affichent du vert. C’est un problème un peu spécial par rapport aux applications qu’on opère déjà.

Prenons un service de prévision qui répond vite et ne produit aucune exception dans les logs. Malgré ça, ses suggestions deviennent moins utiles chaque semaine. Le code est resté pareil, mais les données et les comportements autour ont changé.

Une application dépend de son code et des entrées qu’elle reçoit maintenant. Un modèle dépend aussi des relations apprises dans un historique. Si les habitudes, les produits ou les sources bougent, la précision peut descendre sans créer une panne technique évidente.

On commence à regrouper les pratiques pour gérer ça sous le nom MLOps. Il y a beaucoup de DevOps là-dedans : automatiser, versionner, surveiller et être capable de revenir en arrière. La différence est que l’unité déployée ne vient pas seulement du code.

Relier les artefacts d’une version

Pour reproduire une prédiction, je veux retrouver au moins le code de préparation, les données d’entraînement, les paramètres, le fichier du modèle, son environnement d’exécution et les seuils métier. Un manifeste peut relier ces pièces :

model: demand-forecast
version: 1.7.2
training_code: git:9f3a1c2
feature_schema: demand-features-v4
training_snapshot: sales-2017-01_to_2018-12@sha256:ab41...
runtime: python-3.7-sklearn-0.20
metric:
  mae: 8.4
approval_threshold:
  max_mae: 10.0
created_at: 2019-02-12T15:20:00Z

Le pipeline commence par valider le schéma et construire les features avec le même code qu’en production. Il entraîne un candidat, calcule les métriques sur une période gardée à part, puis enregistre le modèle seulement si les tests passent. La promotion vers la production exige une approbation et ne remplace pas l’ancienne version; elle déplace un pointeur vers le nouvel artefact.

Cette séparation rend le retour arrière possible. Si la version 1.7.2 se comporte mal, le service peut reprendre la 1.7.1 avec son propre schéma et ses transformations. Garder seulement le dernier fichier model.pkl ne suffit pas, parce que l’ancienne version peut dépendre d’autres features.

Déployer sans donner tout le trafic d’un coup

Je vois trois façons de comparer un nouveau modèle :

  1. shadow : la nouvelle version reçoit une copie des requêtes, mais sa réponse n’est pas utilisée;
  2. canary : une petite proportion des décisions utilise la nouvelle version;
  3. champion/challenger : les deux produisent un score et on compare leurs résultats sur la même période.

Le mode shadow vérifie le temps de réponse, les erreurs et la compatibilité des données sans toucher au workflow. Il ne mesure pas l’effet d’une décision, puisque le résultat du nouveau modèle n’agit sur rien. Le canary permet cette mesure, mais exige un identifiant stable pour attribuer le dossier à la même version et une règle d’arrêt rapide.

Chaque prédiction devrait écrire une trace comme :

{
  "predictionId": "pred-88421",
  "modelVersion": "1.7.2",
  "featureSchema": "demand-features-v4",
  "inputHash": "7c3e...",
  "prediction": 42.6,
  "servedAt": "2019-02-15T10:02:04Z",
  "latencyMs": 38
}

Quand la vraie demande arrive deux semaines plus tard, un job la relie à predictionId, calcule l’erreur et met à jour les métriques par produit, région et version. Sans cette clé, on connaît la qualité moyenne du système sans savoir quel modèle a produit quoi.

Surveiller avant et après l’arrivée de la cible

On connaît immédiatement la disponibilité, le taux d’erreur et la latence. On peut aussi surveiller les entrées sans attendre :

  • proportion de valeurs manquantes;
  • catégories jamais vues pendant l’entraînement;
  • moyenne, quantiles et distribution de chaque feature;
  • volume par segment;
  • score moyen et proportion de décisions au-dessus du seuil.

Un test de dérive peut comparer la distribution récente à la référence d’entraînement. Ce signal ne prouve pas que le modèle est mauvais. Il dit que le monde qu’il reçoit n’est plus tout à fait celui sur lequel il a appris. Il faut ensuite regarder les erreurs réelles dès que les étiquettes arrivent.

Le feedback peut être retardé de plusieurs semaines ou manquer complètement. Je garderais donc deux tableaux : santé immédiate du service et qualité retardée des décisions. Une alerte de données peut mettre le modèle en mode prudent — seuil plus élevé, validation humaine ou règle de secours — sans attendre le calcul final.

Ne pas réentraîner une source brisée

Réentraîner automatiquement à chaque dérive peut apprendre plus vite le mauvais signal. Si une colonne tombe à zéro après une migration, le nouveau modèle va s’adapter à la panne. Le pipeline devrait s’arrêter lorsque le schéma, les volumes ou les contrôles de domaine échouent.

Je définirais une procédure de reprise :

alerte → geler les promotions → vérifier la source
       → comparer au modèle précédent et à une règle simple
       → corriger/rejouer les données → réentraîner un candidat
       → valider → promouvoir graduellement ou revenir en arrière

Avant le déploiement, je veux savoir qui reçoit chaque alerte, qui peut désactiver la version et quelle règle prend le relais. Une bonne métrique de laboratoire autorise l’expérience. Le MLOps commence quand l’équipe peut relier une mauvaise décision à une version, comprendre ce qui a changé et revenir à un état connu sans arrêter tout le processus.