Récapitulation et examen final
Dix modules pour passer d'un modèle enregistré sous l'alias @champion
dans MLflow à un service FastAPI qui tient 300 requêtes par seconde,
journalise chaque prédiction avec un identifiant unique, refuse les
appels sans jeton valide et se déploie en une commande. Voici la carte
complète du cours, les fils qui la traversent et la liste de contrôle
d'une API de modèle en production.
Le cours d'un coup d'œil
| Module | L'essentiel à retenir |
|---|---|
| 1. Routes, types et documentation | Annotations Python standard = OpenAPI vivant à /docs ; GET pour lire, POST avec corps JSON pour prédire ; --reload en local seulement |
| 2. Validation Pydantic | Modèle de requête et de réponse ; contraintes ge, le, Literal[...], validateurs métier ; 422 automatique et exemple visible dans Swagger |
| 3. Chargement du modèle | lifespan charge une seule fois, alias @champion depuis MLflow, échec au démarrage plutôt qu'à la première requête |
| 4. Prédiction unitaire et par lots | Une fonction de prétraitement unique partagée entre entraînement et service ; borne à 5 000 dossiers, réponse 413 au-delà |
| 5. Gestion des erreurs | 422 pour un schéma faux, 400 pour une règle métier violée, 500 pour un défaut interne, 503 pour l'indisponibilité ; jamais de trace exposée |
| 6. Async et tâches de fond | def par défaut, async def seulement s'il y a await ; BackgroundTasks pour du court, file externe (Celery, RQ) pour du long |
| 7. Authentification par jeton | Clé d'API dans un en-tête X-API-Key, comparaison secrets.compare_digest, rotation avec chevauchement, HTTPS non négociable |
| 8. Journalisation et sondes | Journaux JSON avec X-Request-Id, sonde de vie triviale, sonde de disponibilité qui teste les dépendances, métriques RED sur Prometheus |
| 9. Conteneurisation et déploiement | Dockerfile en plusieurs étages, base slim, utilisateur non privilégié, image < 500 Mo, .dockerignore obligatoire |
| 10. Tests de charge et dimensionnement | Locust en sans-interface, lire p95 et p99 (jamais la moyenne), diagnostiquer modèle / sérialisation / pool de fils, deux réplicas au minimum |
Les fils qui traversent le cours
Le contrat public est plus étroit et plus stable que l'interne. Le
module 2 le pose avec DossierAbonne ; le module 4 le protège avec la
fonction de prétraitement unique ; le module 5 le tient avec les codes
4xx bien classés. Une API dont le schéma public change en même temps que
le modèle est une API que personne n'ose intégrer.
Un service ML est d'abord un service, pas d'abord un modèle. Les neuf modules qui suivent le chargement — validation, prédiction, erreurs, async, jeton, journaux, image, dimensionnement — passent autant de temps sur le tuyau que sur le calcul. Un modèle brillant derrière un tuyau bancal donne un service que personne n'utilise ; un modèle correct derrière un tuyau propre est un actif que l'équipe maintient dix ans.
Trois séparations fondamentales structurent le code. Contrat public / objet interne (modules 2 et 4). Sonde de vie / sonde de disponibilité (module 8). Erreur du client / erreur du service (module 5). Chaque confusion coûte cher : le client déboussolé qui rejoue en boucle, l'orchestrateur qui redémarre alors qu'il devrait retirer du trafic, le tableau de bord qui affiche 500 pour un champ mal orthographié.
Chaque décision a un chiffre. Le module 10 chiffre le débit et le coût par million de prédictions ; le module 9 chiffre la taille de l'image et la mémoire par travailleur ; le module 3 chiffre le chargement du modèle. Un service ML sans chiffres est un service qu'on ne peut ni faire évoluer, ni facturer, ni comparer.
Liste de contrôle d'une API de modèle en production
À imprimer et à cocher avant chaque promotion.
Contrat public.
- Modèle Pydantic pour la requête, modèle Pydantic pour la réponse.
- Exemple concret dans
model_configvisible dans/docs. - Un champ nouveau est optionnel avec valeur par défaut ; jamais de
suppression sans passer par
/v2/.
Modèle et prétraitement.
- Chargement unique au démarrage via
lifespan, alias@champion. - Version du modèle exposée dans chaque réponse et sur
/model/info. - Fonction de prétraitement importée depuis un paquet partagé, jamais réécrite dans le service.
Erreurs et journaux.
- 422 pour un schéma faux, 400 pour une règle métier, 500 avec
trace_idrenvoyé mais jamais de trace Python. - Gestionnaire d'exceptions global,
debug=Falseen production. - Journaux JSON structurés avec
X-Request-Id, une ligneINFOpar requête,ERRORuniquement pour ce qui exige une intervention.
Sécurité.
- Clé d'API dans un en-tête, comparaison
secrets.compare_digest. - Rotation avec chevauchement, secrets hors du dépôt Git.
- HTTPS obligatoire, limitation de débit par appelant avec
429etRetry-After.
Sondes et métriques.
/health/livetriviale,/health/readyteste les dépendances./metricsPrometheus, alertes sur latence p95, taux d'erreur, saturation CPU.
Image et déploiement.
Dockerfileen plusieurs étages, baseslim, image sous 500 Mo.- Utilisateur non privilégié,
.dockerignorecomplet, scan de vulnérabilités avant push. - Deux réplicas au minimum, échelle automatique à partir de 70 % d'usage CPU.
Dimensionnement et coût.
- Nombre de travailleurs mesuré par Locust, pas déduit de la formule
2 × cœurs + 1. - p95 tenu sous la valeur promise dans l'accord de niveau de service.
- Coût par million de prédictions calculé et suivi mois après mois.
Un service qui coche ces vingt cases répond à 95 % des reproches qu'un comité d'architecture ou une équipe SRE peut lui adresser. Les 5 % restants sont des sujets d'ingénierie plus profonds (mise en cache distribuée, GPU partagé, service mesh) qui relèvent d'autres cours.
L'examen final
L'examen comporte 40 questions couvrant les dix modules : construction
d'une application FastAPI minimale, validation Pydantic et messages 422,
chargement au démarrage plutôt qu'à la requête, prédiction unitaire et
par lots avec prétraitement cohérent, distinction fine entre 400, 422,
500 et 503, choix entre def et async def, sécurisation par clé d'API
et limitation de débit, journaux structurés avec identifiant de requête,
séparation des sondes de vie et de disponibilité, image Docker en
plusieurs étages, lecture des percentiles Locust et dimensionnement en
travailleurs et réplicas.
Plusieurs questions présentent des situations à diagnostiquer : un
service qui recharge le modèle à chaque requête, une clé d'API glissée
dans l'URL par un tutoriel ancien, une sonde de santé qui répond ok
alors que le modèle est cassé, une route async def qui embouteille la
boucle d'événement avec un calcul CPU, un lot qui fait exploser la
mémoire, un 422 renvoyé pour une règle métier qui aurait dû être un
400, une image Docker de 3 Go qui bloque les déploiements. C'est le
jugement qui est évalué, pas la récitation de définitions.
En cas de réussite, votre attestation d'achèvement est délivrée immédiatement ; son numéro est vérifiable par tout tiers sur la plateforme.
Reprenez le tableau ci-dessus et, pour chaque ligne, demandez-vous
« quelle serait la signature d'un bogue ici ? ». Si vous savez décrire
pourquoi un async def sans await divise le débit par dix, pourquoi
la sonde de vie ne doit pas tester la base de données, pourquoi la
p99 compte plus que la moyenne, et pourquoi la fonction de
prétraitement doit vivre dans un seul dépôt, vous êtes prêt. Bonne
chance !
Examen final
Prêt à valider ce cours ?
40 questions tirées au hasard dans la banque du cours · seuil de réussite 70 % · certificat PDF vérifiable délivré immédiatement en cas de réussite.
Commencer l'examenConnexion à votre compte InSkillML et abonnement actif requis. Vous pouvez aussi lancer l'examen depuis Mes cours.