Ultralytics YOLO27 : Inscris-toi sur la liste d’attente.
Get Started
Entraîne ton premier modèle YOLO·Déployer·Leçon 10/10
Leçondébutant

Exporter pour le déploiement

Exporte best.pt vers ONNX, OpenVINO, TensorRT, CoreML, LiteRT ou QNN, puis vérifie que l'export correspond au modèle PyTorch avant de le déployer.

Ton best.pt nécessite Python et PyTorch pour fonctionner ; les téléphones, les navigateurs, les Jetson et les serveurs de production ne les ont généralement pas. Le mode Export convertit le modèle en un fichier autonome utilisable par ces environnements d'exécution, en un seul appel. Le piège : le fait qu'un export se charge ne garantit pas qu'il soit correct, et une comparaison mal faite peut faire paraître défectueux un export correct ou masquer un export défectueux.

Dans cette leçon, tu vas exporter le modèle de pilules vers ONNX, l'exécuter avec la même API YOLO, vérifier qu'il correspond à PyTorch pour les boîtes et le mAP de validation avec des paramètres identiques, puis choisir le format adapté à ta cible : ONNX, OpenVINO, TensorRT, CoreML, LiteRT ou QNN.

Résultat

Tu peux exporter un modèle entraîné dans le format adapté à une cible de déploiement et vérifier, à l'aide d'une comparaison de parité à paramètres équivalents et de la validation, que l'export correspond à best.pt.

Parcours accéléré
Si tu connais déjà les bases, voici la version courte.
  1. yolo export model=runs/detect/pills_v1/weights/best.pt format=onnx — commence ici.

  2. OpenVINO pour les CPU Intel ; TensorRT pour les GPU NVIDIA et Jetson ; CoreML pour Apple ; LiteRT pour Android ; QNN pour les NPU Snapdragon.

  3. Compare .pt et l'export sur la même image, en utilisant rect=False du côté .pt.

  4. Valide les deux au imgsz utilisé pour l'entraînement ; le mAP50-95 devrait être identique.

Pratique

Exemple pratique : exporter vers ONNX#

Onglet Export de modèle de la plateforme Ultralytics, répertoriant des formats de déploiement tels que ONNX, TensorRT, CoreML et OpenVINO

yolo export model=runs/detect/pills_v1/weights/best.pt format=onnx
PyTorch: starting from 'runs/detect/pills_v1/weights/best.pt' with input shape (1, 3, 320, 320) BCHW and output shape(s) (1, 5, 2100) (5.2 MB)
ONNX: export success ✅ 0.9s, saved as 'runs/detect/pills_v1/weights/best.onnx' (9.3 MB)
Predict:         yolo predict task=detect model=runs/detect/pills_v1/weights/best.onnx imgsz=320
Validate:        yolo val task=detect model=runs/detect/pills_v1/weights/best.onnx imgsz=320 data=my_dataset/data.yaml

Ligne par ligne :

  • input shape (1, 3, 320, 320) : une image, 3 canaux couleur, un carré fixe de 320×320 — le imgsz utilisé pour l'entraînement, intégré au fichier.
  • output shape(s) (1, 5, 2100) : 4 valeurs de boîte plus 1 score de classe pour 2 100 boîtes candidates ; NMS est exécuté en dehors du graphe par défaut.
  • 9.3 MB : le fichier ONNX stocke des poids FP32 ; il est donc plus volumineux que le .pt en FP16.
  • Predict: / Validate: : des commandes prêtes à l'emploi pour le fichier exporté, avec le imgsz approprié.

Quelques arguments couvrent la plupart des besoins ; le guide d'intégration ONNX répertorie les autres.

ArgumentPar défautUtilise-le pour
imgszTaille d'entraînementExporter avec une autre taille d'entrée fixe, par exemple imgsz=640
dynamicFalseAccepter des tailles d'entrée variables au lieu d'une seule forme fixe
quantizeAucun (FP32)16 pour les poids FP16 (yolo26n.onnx passe de 9.5 MB à 4.8 MB) ; 8 pour INT8 lorsque le format le prend en charge
nmsAucunnms=True intègre NMS au graphe, de sorte que l'environnement d'exécution renvoie les boîtes finales

Exemple pratique : vérifier que l'export correspond au modèle#

La classe YOLO charge aussi les fichiers exportés ; le code de prédiction présenté précédemment fonctionne donc sans modification. Compare les deux fichiers sur la même image de validation :

from ultralytics import YOLO

image = "my_dataset/images/val/Frame_144.jpg"
pt = YOLO("runs/detect/pills_v1/weights/best.pt")(image, rect=False, verbose=False)[0]  # square input, like ONNX
onnx = YOLO("runs/detect/pills_v1/weights/best.onnx")(image, verbose=False)[0]

print(f"pt:   {len(pt.boxes)} pills, mean conf {pt.boxes.conf.mean():.3f}")
print(f"onnx: {len(onnx.boxes)} pills, mean conf {onnx.boxes.conf.mean():.3f}")
print(f"max box difference: {(pt.boxes.xyxy - onnx.boxes.xyxy).abs().max():.4f} px")
pt:   25 pills, mean conf 0.870
onnx: 25 pills, mean conf 0.870
max box difference: 0.0002 px

Même nombre, même confiance, boîtes identiques à une fraction de pixel près. Passons maintenant à la vérification plus rigoureuse : la validation sur l'ensemble du découpage :

from ultralytics import YOLO

pt = YOLO("runs/detect/pills_v1/weights/best.pt").val(data="my_dataset/data.yaml", rect=False, verbose=False)
onnx = YOLO("runs/detect/pills_v1/weights/best.onnx").val(data="my_dataset/data.yaml", verbose=False)
print(f".pt   mAP50-95 {pt.box.map:.4f}")
print(f".onnx mAP50-95 {onnx.box.map:.4f}")
.pt   mAP50-95 0.6570
.onnx mAP50-95 0.6570

Identiques. (La validation rectangulaire par défaut du fichier .pt a obtenu 0.659 : le léger écart vient du remplissage de l'entrée, et non de l'export.)

Une fois la correspondance vérifiée, mesure le temps avec yolo benchmark sur l'appareil cible afin de connaître sa vitesse réelle avant le déploiement.

Choisir un format pour ta cible#

Cycle de vie de la plateforme Ultralytics : annoter avec l'annotation intelligente SAM, entraîner sur des GPU cloud et déployer dans le monde entier, avec les logos des partenaires d'intégration

ObjectifFormatRemarques
Format portable par défaut : serveurs et ordinateurs de bureau sous Linux, Windows et MaconnxONNX Runtime sur CPU ou GPU ; l'export le plus rapide à vérifier
GPU NVIDIA et Jetsonengine (TensorRT)Le plus rapide sur NVIDIA ; exporte sur l’appareil. Voir Optimiser avec TensorRT
Processeurs Intel et iGPUopenvinoGains de vitesse réels sur CPU grâce aux noyaux Intel. Voir OpenVINO sur CPU
Applications pour iPhone, iPad et MaccoremlNatif ; utilise l’Apple Neural Engine
Android et autres appareils mobiles ou embarquéslitertINT8 recommandé pour les appareils mobiles
NPU SnapdragonqnnAccélération Hexagon HTP ; poids INT8 avec activations 16 bits par défaut ; choisis l’architecture HTP avec name
Navigateur Webonnx avec ONNX Runtime WebLes modèles plus petits sont viables : n et s
from ultralytics import YOLO

model = YOLO("runs/detect/pills_v1/weights/best.pt")

model.export(format="onnx")  # multiplateforme : ONNX Runtime
model.export(format="openvino")  # CPU / iGPU Intel
model.export(format="engine", quantize=16)  # NVIDIA TensorRT, FP16 (exécution sur le GPU cible)
model.export(format="coreml")  # Apple iOS / macOS
model.export(format="litert", quantize=8, data="my_dataset/data.yaml")  # Android / périphérie, INT8
model.export(format="qnn", name="73", data="my_dataset/data.yaml")  # NPU Qualcomm Snapdragon (HTP v73) ; calibre avec tes propres données

Chaque export écrit les fichiers à côté des poids : best.onnx, best_openvino_model/, best.engine, et ainsi de suite. Commence par ONNX, même si tu optes finalement pour un autre format : c’est le plus rapide à vérifier et il sert d’entrée à plusieurs autres chaînes d’outils. Le guide des options de déploiement compare tous les formats, et Choisir une cible de déploiement t’aide à prendre ta décision.

La quantification des modèles échange de la précision contre une réduction de taille et un gain de vitesse. FP16 (quantize=16) divise la taille du fichier par deux avec une précision presque inchangée. INT8 (quantize=8) réduit encore la taille et accélère davantage, mais nécessite des images de calibration — des images représentatives que l’export traite pour déterminer les plages de valeurs ; Ultralytics en recommande au moins 300. Valide toujours un modèle INT8 avant sa mise en production : la perte peut être négligeable ou importante selon le modèle et le jeu de calibration.

Éviter ces erreurs#

Comparer des entrées différentes

Symptôme : le modèle .pt détecte 35 pilules dans Frame_144.jpg, tandis que le fichier ONNX en détecte 25, et l'exportation semble défectueuse. Cause : l'inférence PyTorch complète chaque image jusqu'au plus petit rectangle dont les dimensions sont alignées sur le stride (192×320 pour ces images 16:9), tandis qu'un modèle ONNX statique utilise toujours une image carrée de 320×320. Des entrées différentes entraînent des détections de confiance faible différentes. Solution : passe rect=False au modèle .pt pour la comparaison, comme dans parity.py.

Un export statique ignore ton imgsz

Symptôme : tu passes imgsz=640 à best.onnx, mais le journal indique toujours 320x320. Cause : un export statique a une seule taille d'entrée, définie au moment de l'exportation. Solution : exporte à la taille prévue pour l'exécution (imgsz=640) ou exporte avec dynamic=True.

Les moteurs TensorRT dépendent de l'appareil

Un .engine créé sur un A100 ne fonctionnera pas sur un Jetson Orin et risque de ne pas fonctionner après une mise à niveau de TensorRT. Exporte sur l'appareil cible, avec la version de TensorRT qui sera utilisée. ONNX est portable ; les moteurs ne le sont pas.

Par défaut, INT8 effectue l'étalonnage sur COCO8

Si tu omets data lors d'un export INT8, Ultralytics affiche un avertissement, puis effectue l'étalonnage sur l'échantillon COCO8 par défaut — huit images qui ne ressemblent en rien à tes pilules. Passe ton propre échantillon : model.export(format="litert", quantize=8, data="my_dataset/data.yaml").

Tu as déployé#

Tu disposes maintenant d’un best.pt entraîné, de résultats de validation comparés à une référence, d’un fichier exporté pour ton environnement d’exécution et de la preuve que l’export correspond à l’original. C’est le cycle complet — données, entraînement, validation, export, déploiement — que les équipes en production exécutent régulièrement. Ultralytics YOLO en production part de ton export vérifié et couvre les environnements d’exécution optimisés, les pipelines de suivi, le traitement de plusieurs flux et la surveillance.

Essayer

Exporte ton pills_v1/weights/best.pt en ONNX, puis exécute parity.py et val_export.py. Relance parity.py sans rect=False et note comment évolue le nombre de .pt. Fournis quatre éléments : le nombre de détections correspondantes, l’écart maximal entre les boîtes, les deux valeurs mAP50-95 et une ligne indiquant le format requis par ta véritable cible de déploiement et pourquoi.

Valider
git add -A && git commit -m "feat(deploy): exported best.pt to onnx for production runtime"
Terminé lorsque
Tu as terminé la leçon lorsque tous les éléments suivants sont réunis.
  • runs/detect/pills_v1/weights/best.onnx existe et effectue des prédictions avec YOLO().

  • Avec rect=False, les nombres de détections correspondent et l’écart maximal entre les boîtes est inférieur à 1 px.

  • Les valeurs mAP50-95 de validation d’ONNX et de .pt correspondent avec des paramètres identiques, et tu as indiqué ton format cible en justifiant ton choix.

Afficher la solution
from ultralytics import YOLO

# Train
model = YOLO("yolo26n.pt")
model.train(data="my_dataset/data.yaml", epochs=10, imgsz=320, name="pills_e2e")

# Validate
metrics = model.val()
print(f"mAP50-95 = {metrics.box.map:.3f}")  # 0.659

# Export
model.export(format="onnx")
parity.py:      pt 25 pills, onnx 25 pills, max box difference 0.0002 px
without rect:   pt 35 pills (192x320 input) vs onnx 25 (320x320): input mismatch, not an export bug
val_export.py:  .pt 0.6570, .onnx 0.6570
Target:         Intel laptop CPU -> openvino, for faster CPU inference than ONNX Runtime
Et ensuite ?

Cours terminé — passe le quiz final pour obtenir ton certificat Entraîne ton premier modèle YOLO, puis poursuis avec Ultralytics YOLO en production.