Computer Vision & MLOps · 2025
Snani — Comprendre sa radio dentaire
Transformer un détecteur de signes dentaires en un service reproductible et une interface compréhensible sans connaissances médicales ou techniques.
- Contexte
- Projet académique MLOps · application Snani pour le grand public
- Année
- 2025
- Technologies
- YOLOv8 (Ultralytics) · DVC · MLflow · FastAPI
- Rôle
- Projet académique · Computer Vision, MLOps & expérience utilisateur
Présentation Snani — Détection dentaire & MLOps

01
Le défi
Une radio panoramique est difficile à comprendre sans accompagnement. Un résultat de détection composé de classes techniques, de coordonnées et de scores ne répond pas à la question de l’utilisateur : que montre mon image et que dois-je faire vérifier ?
Le second défi est de sortir du notebook : rendre les données reproductibles, comparer les modèles, tracer la sélection du Champion et servir le même checkpoint dans une API testée et conteneurisée.
02
La solution
Deux volets complémentaires : une chaîne MLOps de la donnée au service, et Snani, une interface en français et en arabe qui transforme les détections en signes expliqués simplement. L’utilisateur importe sa radio ou essaie un exemple, visualise les zones repérées, lit les explications et peut partager une image annotée avec son dentiste.
03
Architecture
1 808 radiographies
24 888 annotations nettoyées · DVC
Préparation
audit · remapping 14 → 7 classes
YOLOv8s & MLflow
3 variantes · évaluation eval / test / external
Registre de modèles
Champion / Candidate / Archived · alias stable
CI/CD GitHub Actions
tests · build Docker · intégration · GHCR
API FastAPI
Azure Container Apps · 0–1 réplique
Snani
React / Vercel · français & arabe · mobile
Architecture actuelle d’après docs/deployment.md. La présentation conserve l’étape antérieure Railway + Vercel ; le dépôt documente désormais Azure Container Apps + Vercel.
04
De la donnée à une expérience compréhensible
01Données reproductibles[Présentation p. 7–8 · README.md]
Pipeline DVC inspect → prepare → stats. Les 1 808 images sont conservées ; 3 annotations invalides sont retirées, laissant 24 888 annotations. Les 14 classes d’origine sont regroupées en 7 familles de signes, dont les soins déjà réalisés et les implants.
02Expériences traçables[Présentation p. 12, 14–15 · configs/model_registry.yaml]
YOLOv8s pré-entraîné, résolution 832 px et trois variantes comparées sur eval, test et external. MLflow conserve configurations, checkpoints et métriques ; le registre YAML identifie le Champion et son checkpoint stable.
03Importer sans connaissances techniques[frontend/src/i18n/fr.js · README.md]
Import par fichier, glisser-déposer ou appareil photo, avec un exemple pour découvrir le parcours. Luminosité et contraste sont ajustables ; les paramètres du modèle sont présentés comme niveau de détail et sensibilité, dans des options avancées.
04Comprendre et partager[frontend/src/components/ResultsPanel.jsx · frontend/src/report.js]
Les zones détectées sont reliées à des explications en français ou en arabe, des niveaux de certitude et des conseils de suivi. L’image annotée peut être téléchargée ou partagée avec un dentiste ; les résultats simulés sont explicitement signalés en mode démo.
05Service conteneurisé et testé[.github/workflows/cd-service.yml · docs/deployment.md]
FastAPI expose /health, /model-info et /predict. L’image Docker CPU embarque le Champion ; GitHub Actions exécute les tests, construit l’image, teste le conteneur et publie sur GHCR. Le déploiement automatique Azure dépend de la configuration des identifiants ; un script de déploiement est aussi fourni.
06Confidentialité et limites de service[docs/deployment.md]
Le dépôt documente la suppression des images temporaires après analyse, des fichiers limités à 15 Mo, un CORS restreint et une limite de 10 requêtes/minute et 100/heure par IP. Le conteneur s’exécute sans privilèges root.
05
Décisions techniques
Un Champion choisi sur plusieurs partitions[Présentation p. 14 · configs/model_registry.yaml]
La baseline obtient le meilleur compromis eval/test et un rappel supérieur sur test. Le Candidate améliore légèrement la mAP50 externe (0,332 contre 0,325), mais reste moins bon sur test (0,407 contre 0,422).
Séparer le moteur ML du langage utilisateur[frontend/src/i18n/fr.js · frontend/src/components/ResultsPanel.jsx]
Les classes de détection restent stables côté API ; Snani les traduit en explications, niveaux de certitude et actions lisibles. Les réglages techniques restent accessibles dans les options avancées.
Éteindre le service au repos[docs/deployment.md]
Azure Container Apps est configuré de 0 à 1 réplique. Le frontend ne réveille l’API qu’au chargement d’une radio et explique le démarrage à froid de 30 à 60 secondes, au lieu d’annoncer une latence immédiate garantie.
06
Résultats
Mesures du tableau 4.2 de la présentation (page PDF 14). Les scores décrivent une détection d’objets sur des partitions expérimentales ; ils ne mesurent pas la fiabilité d’un diagnostic pour un patient.
- radiographies conservées
- 1 808
- radiographies conservées
- corpus total, toutes partitions de l’audit[Présentation p. 7–8]
- annotations nettoyées
- 24 888
- annotations nettoyées
- 3 annotations invalides supprimées ; 7 classes finales[Présentation p. 7–8]
- image Docker CPU
- 1,19 GB
- image Docker CPU
- taille rapportée dans la présentation, contre 3,74 GB pour l’ancienne image[Présentation p. 19]
- tests unitaires + intégration
- 11 + 5
- tests unitaires + intégration
- bilan présenté à la soutenance ; le workflow actuel contient aussi des contrôles de sécurité[Présentation p. 19, 22 · cd-service.yml]
| Modèle | Partition | Précision | Rappel | mAP50 | mAP50–95 |
|---|---|---|---|---|---|
| Champion | eval | 0.695 | 0.393 | 0.325 | 0.136 |
| Champion | test | 0.860 | 0.467 | 0.422 | 0.211 |
| Champion | external | 0.682 | 0.383 | 0.325 | 0.146 |
| Candidate | eval | 0.689 | 0.368 | 0.313 | 0.138 |
| Candidate | test | 0.894 | 0.441 | 0.407 | 0.199 |
| Candidate | external | 0.757 | 0.383 | 0.332 | 0.160 |
Sur test, une précision de 0,860 s’accompagne d’un rappel de 0,467 : beaucoup de signes annotés restent manqués. La mAP50 est de 0,325 sur external. Les 86 % de précision ne sont donc ni une accuracy globale ni une probabilité de diagnostic correct.
07
Limites
- Aucune validation clinique par des praticiens : Snani est une aide à la compréhension issue d’un projet académique, à confronter à l’examen d’un dentiste.
- Rappel limité et variations entre cabinets : un résultat sans signe détecté ne garantit pas l’absence de problème.
- Les 7 classes regroupent aussi des traitements et dispositifs déjà présents ; elles ne représentent pas 7 maladies.
- Démarrage à froid de 30 à 60 secondes. La résolution de 832 px limite aussi les détails disponibles pour les petites lésions.
08
Suites possibles
- Enrichir le corpus et tester des résolutions de 1 024 à 1 280 px, sans présumer du gain de performance.
- Évaluer la compréhension des explications par des utilisateurs et organiser une validation avec des chirurgiens-dentistes.
- Ajouter un suivi de latence, de disponibilité et de dérive des données.