Aller au contenu principal

Module 11 — Récapitulatif et examen

Ce cours a suivi deux modèles — un ResNet18 vision, un petit encodeur de texte — du format au service, en dix étapes qui se lisent aussi comme la trajectoire d'un projet réel : comprendre le format, exporter, vérifier, optimiser, quantifier, choisir un fournisseur, mesurer, contourner les blocages, servir. Ce récapitulatif fait le lien entre ces étapes et prépare l'examen d'attestation.

Ce que vous savez faire maintenant

Pas une liste académique de mots-clés : les questions concrètes que vous saurez trancher.

  • Comprendre pourquoi un .onnx est un graphe statique protobuf, choisir un jeu d'opérateurs (opset) selon la cible d'inférence, et lire un modèle dans Netron pour diagnostiquer une conversion.
  • Exporter depuis PyTorch avec torch.onnx.export, gérer les axes dynamiques, choisir entre l'exportateur historique (par traçage) et Dynamo, et lire les TracerWarning.
  • Exporter depuis TensorFlow avec tf2onnx, sélectionner une signature de SavedModel, et savoir quand la conversion NHWC vers NCHW coûte ou gêne.
  • Vérifier numériquement l'équivalence entre le modèle d'origine et son export sur des entrées variées, avec np.allclose(atol=1e-4, rtol=1e-4) en float32.
  • Appliquer les niveaux d'optimisation d'ONNX Runtime, comprendre ce que la fusion et le pliage de constantes accomplissent, et sauvegarder un graphe optimisé sans casser la portabilité.
  • Quantifier un modèle dynamiquement puis statiquement, choisir la méthode de calibration (MinMax, Percentile, Entropy) et évaluer la perte de précision sur un jeu de validation.
  • Choisir les fournisseurs d'exécution — CPU, CUDA, TensorRT — dans le bon ordre, gérer le cache TensorRT et surtout détecter un repli silencieux sur CPU avec session.get_providers().
  • Mesurer avec un protocole reproductible : échauffement, série de plusieurs centaines d'inférences, percentiles p50 / p95 / p99, matériel documenté.
  • Diagnostiquer un opérateur non pris en charge, décider entre monter l'opset, réécrire le module, décomposer, ou écrire un opérateur personnalisé.
  • Mettre en service derrière FastAPI avec une session partagée, un prétraitement identique à celui de l'entraînement, et vérifier le service par un test de bout en bout et une somme de contrôle du fichier .onnx.

Liste de contrôle d'un export propre

Le résumé pratique tient sur une page. Un modèle qui coche ces dix cases est prêt à passer en revue de code.

  1. Le modèle d'origine est en mode eval() avant l'export.
  2. Une entrée exemple réaliste est passée à l'exportateur, avec le bon type et la bonne forme.
  3. dynamic_axes (ou dynamic_shapes pour Dynamo) déclare tout axe variable — au minimum la dimension de lot.
  4. La version d'opset est celle la plus ancienne qui supporte tous les opérateurs du modèle et est reconnue par le runtime cible.
  5. onnx.checker.check_model passe sans erreur.
  6. La vérification numérique passe avec atol=1e-4, rtol=1e-4 sur au moins trois jeux d'entrées : réaliste, saturé, extrême.
  7. session.get_providers() renvoie exactement les fournisseurs demandés ; aucun repli silencieux.
  8. La mesure de latence rapporte p50, p95, p99 avec échauffement et matériel documenté.
  9. Le prétraitement d'entrée est versionné à côté du fichier .onnx, dans un module Python versionné.
  10. Un test de bout en bout du service prédit la bonne classe sur une image de référence connue avant tout déploiement.

Fils qui traversent les modules

Trois fils reviennent à travers le cours, et méritent d'être vus comme un tout.

Le contrat des axes. Depuis l'export (module 2) jusqu'à la mesure (module 8) et au service (module 10), la forme d'entrée reste au centre. Un axe non déclaré dynamique fige la taille de lot ; deux axes portant le même nom symbolique doivent rester égaux à l'inférence ; un changement de convention NHWC / NCHW propage des erreurs subtiles jusqu'aux benchmarks.

La vérification numérique. Elle apparaît au module 4, revient après optimisation (5), après quantification (6), après contournement d'opérateur (9). C'est le seul filet qui protège de la dérive silencieuse ; l'écart maximum acceptable dépend du régime (float32, float16, INT8) mais l'exigence de mesurer, elle, ne bouge jamais.

Le repli silencieux. ONNX Runtime accepte volontiers une demande qu'il ne peut pas honorer. Un fournisseur absent est retiré, un opérateur non couvert tombe sur CPU, une conversion float16 rend inf sur une valeur extrême. La vigilance à ces silences fait la différence entre un service qui semble marcher et un service qui marche vraiment.

Quand ne pas utiliser ONNX

Ce cours a défendu ONNX à travers dix modules ; il est équitable de dire quand il n'est pas le bon outil.

  • Un modèle qui ne quittera jamais son cadre d'origine : servir un PyTorch derrière un service Python via TorchScript est plus simple, plus stable et parfois aussi rapide.
  • Un modèle en évolution active : réexporter à chaque commit ajoute une étape et un risque ; tant que le modèle bouge, on remet la conversion à sa stabilisation.
  • Un modèle avec du code métier serré autour du forward (post-traitement complexe, boucles Python, appels à des services externes) : le graphe statique d'ONNX ne les capture pas ; il faut alors couper à un point plus haut du pipeline.

ONNX est un très bon outil pour un modèle mature qu'on doit servir loin de son cadre d'entraînement. C'est le scénario du fil rouge, et de la plupart des services d'inférence en production.

Aller plus loin

Trois lectures à prendre à la suite immédiate de ce cours.

  • Le cours 33 (MLOps opérationnel) couvre la distribution, le versionnage et le canari d'un modèle exporté.
  • Le cours 34 (déploiement à l'échelle) montre comment servir plusieurs modèles derrière un même serveur d'inférence (Triton).
  • La documentation officielle d'ONNX Runtime, onnxruntime.ai, reste la référence à jour ; le projet livre une nouvelle version tous les deux mois environ, et les compatibilités avec les fournisseurs évoluent en conséquence.

Évaluation et attestation

Le parcours se termine par un examen de 40 questions, tirées d'une banque de 48. Les questions couvrent les dix modules dans la proportion indiquée par le plan de cours, avec un accent particulier sur les diagnostics — lire un message d'erreur, décider d'une stratégie de contournement — plutôt que sur les définitions.

Le seuil de réussite est de 70 %, soit 28 bonnes réponses sur 40. Vous disposez de plusieurs tentatives sur une fenêtre glissante de 24 heures, avec cinq tentatives maximum. En cas de réussite, une attestation d'achèvement est délivrée immédiatement ; son numéro est vérifiable sur la plateforme par tout tiers qui reçoit votre attestation.

Les cours gratuits, eux, se concluent par un quiz de 5 questions avec un aperçu de l'attestation, sans certification. Ce parcours-ci est premium : l'attestation est complète et son statut est vérifiable en ligne.

Un dernier conseil avant l'examen

Relisez votre propre trace : les exports que vous avez produits en suivant les modules, les vérifications numériques qui ont passé ou échoué, les mesures que vous avez comparées. Les questions les plus utiles de l'examen portent sur des situations réelles que vous avez déjà eues sous les yeux ; le mécanisme mental qui fait trouver la bonne réponse est celui que vous avez exercé en pratique, pas la mémorisation.

Bon examen.

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'examen

Connexion à votre compte InSkillML et abonnement actif requis. Vous pouvez aussi lancer l'examen depuis Mes cours.