Comment exporterPyTorch YOLO avec Ultralytics
Le déploiement PyTorch en production implique généralement d'utiliser un exportateur différent pour chaque cible : torch.onnx.export pour ONNX, coremltools pour les appareils Apple, onnx2tf pour TensorFlow, pnnx pour NCNN, etc. Chaque outil dispose de sa propre API, de ses particularités en matière de dépendances et de ses conventions de sortie.
Ultralytics des utilitaires d'exportation autonomes qui regroupent plusieurs backends derrière une interface unique et cohérente. Vous pouvez exporter n'importe quel torch.nn.Module, notamment timm modèles d'images, torchvision des classificateurs et des détecteurs, ou vos propres architectures personnalisées, pour ONNX, TorchScript, OpenVINO, CoreML, NCNN, PaddlePaddle, MNN, ExecuTorch, et SavedModel TensorFlow sans avoir à apprendre chaque backend séparément.
Pourquoi utiliser Ultralytics YOLO ?
- Une seule API pour 10 formats : apprenez une seule convention d'appel au lieu d'une douzaine.
- Surface commune : les utilitaires d'exportation se trouvent dans
ultralytics.utils.export, de sorte qu'une fois les paquets backend installés, vous pouvez conserver le même modèle d'appel quel que soit le format. - Même chemin de code que pour YOLO : les mêmes utilitaires sont à la base de toutesYOLO Ultralytics .
- Quantification FP16 et INT8 intégrée pour les formats qui la prennent en charge (OpenVINO, CoreML, MNN, NCNN).
- Fonctionne sur CPU: aucune GPU pour l'étape d'exportation elle-même, vous pouvez donc l'exécuter localement sur n'importe quel ordinateur portable.
Démarrage rapide
La méthode la plus rapide consiste à exporter en deux étapes vers ONNX sans YOLO et sans aucune configuration particulière pip install ultralytics onnx timm:
import timm
import torch
from ultralytics.utils.export import torch2onnx
model = timm.create_model("resnet18", pretrained=True).eval()
torch2onnx(model, torch.randn(1, 3, 224, 224), output_file="resnet18.onnx")
Formats d'exportation pris en charge
L'argument torch2* les fonctions prennent un argument standard torch.nn.Module et un exemple tensor d'entrée. MNN, TF SavedModel et TF Graph passent par un artefact intermédiaire ONNX Keras. Dans aucun des deux cas, aucun attribut YOLO n'est requis.
| Format | Fonction | Installer | Sortie |
|---|---|---|---|
| ONNX | torch2onnx() | pip install onnx | .onnx fichier |
| TorchScript | torch2torchscript() | fourni avec PyTorch | .torchscript fichier |
| OpenVINO | torch2openvino() | pip install openvino | _openvino_model/ répertoire |
| CoreML | torch2coreml() | pip install coremltools | .mlpackage |
| TF SavedModel | onnx2saved_model() | voir les conditions détaillées ci-dessous | _saved_model/ répertoire |
| Graphique TF | keras2pb() | voir les conditions détaillées ci-dessous | .pb fichier |
| NCNN | torch2ncnn() | pip install ncnn pnnx | _ncnn_model/ répertoire |
| MNN | onnx2mnn() | pip install MNN | .mnn fichier |
| PaddlePaddle | torch2paddle() | pip install paddlepaddle x2paddle | _paddle_model/ répertoire |
| ExecuTorch | torch2executorch() | pip install executorch | _executorch_model/ répertoire |
ONNX format intermédiaire
MNN, TF SavedModelet les graphiques TF sont exportés via ONNX étape intermédiaire. Exportez ONNX vers ONNX , puis convertissez.
Intégration des métadonnées
Plusieurs fonctions d'exportation acceptent un paramètre facultatif metadata dictionnaire (par exemple, torch2torchscript(..., metadata={"author": "me"})) qui intègre des paires clé-valeur personnalisées dans l'artefact exporté lorsque le format le permet.
Exemples étape par étape
Tous les exemples ci-dessous utilisent la même configuration, à savoir un modèle ResNet-18 pré-entraîné issu de timm en mode évaluation :
import timm
import torch
model = timm.create_model("resnet18", pretrained=True).eval()
im = torch.randn(1, 3, 224, 224)
Appelez toujours model.eval() avant l'exportation
Abandon scolaire, normalisation par lots, et d'autres couches réservées à l'entraînement se comportent différemment lors de l'inférence. Ignorer .eval() génère des exportations contenant des résultats erronés.
Exporter vers ONNX
from ultralytics.utils.export import torch2onnx
torch2onnx(model, im, output_file="resnet18.onnx")
Pour une taille de lot dynamique, transmettez un dynamic dictionnaire :
torch2onnx(model, im, output_file="resnet18_dyn.onnx", dynamic={"images": {0: "batch_size"}})
La valeur par défaut de l'opset est 14 et le nom par défaut de l'entrée est "images". Remplacer par le opset, input_names, ou output_names arguments.
Exporter vers TorchScript
Aucune dépendance supplémentaire n'est requise. Utilisations torch.jit.trace en coulisses.
from ultralytics.utils.export import torch2torchscript
torch2torchscript(model, im, output_file="resnet18.torchscript")
Exporter vers OpenVINO
from ultralytics.utils.export import torch2openvino
ov_model = torch2openvino(model, im, output_dir="resnet18_openvino_model")
Le répertoire contient un fichier au nom fixe model.xml et model.bin paire :
resnet18_openvino_model/
├── model.xml
└── model.bin
Passer dynamic=True pour les formes d'entrée dynamiques, half=True pour FP16, ou int8=True pour la quantification INT8. Le format INT8 nécessite en outre un calibration_dataset argument.
Nécessite openvino>=2024.0.0 (ou >=2025.2.0 sur macOS 15.4 et versions ultérieures) et torch>=2.1.
Exporter vers CoreML
import coremltools as ct
from ultralytics.utils.export import torch2coreml
inputs = [ct.TensorType("input", shape=(1, 3, 224, 224))]
ct_model = torch2coreml(model, inputs, im, output_file="resnet18.mlpackage")
Pour classification modèles, transmettez une liste de noms de classes à classifier_names pour ajouter une catégorie de classification au CoreML .
Nécessite coremltools>=9.0, torch>=1.11, et numpy<=2.3.5. Non pris en charge sous Windows.
BlobWriter not loaded erreur
coremltools>=9.0 prend en charge les versions Python . Python à 3.13 Python sous macOS et Linux. Sur Python plus récentes Python , l'extension C native ne se charge pas. Utilisez Python . Python à 3.13 pour CoreML .
Exporter versSavedModel TensorFlow
SavedModel TF passe par ONNX étape intermédiaire :
from ultralytics.utils.export import onnx2saved_model, torch2onnx
torch2onnx(model, im, output_file="resnet18.onnx")
keras_model = onnx2saved_model("resnet18.onnx", output_dir="resnet18_saved_model")
La fonction renvoie un modèle Keras et génère également TFLite (.tflite) dans le répertoire de sortie :
resnet18_saved_model/
├── saved_model.pb
├── variables/
├── resnet18_float32.tflite
├── resnet18_float16.tflite
└── resnet18_int8.tflite
Conditions requises :
tensorflow>=2.0.0,<=2.19.0onnx2tf>=1.26.3,<1.29.0tf_keras<=2.19.0sng4onnx>=1.0.1onnx_graphsurgeon>=0.3.26(installer avec--extra-index-url https://pypi.ngc.nvidia.com)ai-edge-litert>=1.2.0,<1.4.0sous macOS (ai-edge-litert>=1.2.0(sur d'autres plateformes)onnxslim>=0.1.71onnx>=1.12.0,<2.0.0protobuf>=5
Exporter vers un graphe TensorFlow
Dans la continuité de SavedModel décrite ci-dessus, convertissez le modèle Keras obtenu en un modèle « frozen » .pb graphique :
from pathlib import Path
from ultralytics.utils.export import keras2pb
keras2pb(keras_model, output_file=Path("resnet18_saved_model/resnet18.pb"))
Exporter vers NCNN
from ultralytics.utils.export import torch2ncnn
torch2ncnn(model, im, output_dir="resnet18_ncnn_model")
Le répertoire contient des fichiers param et bin portant des noms fixes, ainsi qu'un Python :
resnet18_ncnn_model/
├── model.ncnn.param
├── model.ncnn.bin
└── model_ncnn.py
torch2ncnn() vérifie si ncnn et pnnx lors de la première utilisation.
Exporter vers MNN
L'exportation MNN nécessite un ONNX en entrée. Exportez ONNX au format ONNX , puis convertissez :
from ultralytics.utils.export import onnx2mnn, torch2onnx
torch2onnx(model, im, output_file="resnet18.onnx")
onnx2mnn("resnet18.onnx", output_file="resnet18.mnn")
Compatible avec half=True pour FP16 et int8=True pour la quantification INT8. Nécessite MNN>=2.9.6 et torch>=1.10.
Exporter vers PaddlePaddle
from ultralytics.utils.export import torch2paddle
torch2paddle(model, im, output_dir="resnet18_paddle_model")
Ce répertoire contient les fichiers PaddlePaddle et de paramètres PaddlePaddle :
resnet18_paddle_model/
├── model.pdmodel
└── model.pdiparams
Nécessite x2paddle et la PaddlePaddle adaptée à votre plateforme :
paddlepaddle-gpu>=3.0.0,<3.3.0sur CUDApaddlepaddle==3.0.0sur CPU ARM64paddlepaddle>=3.0.0,<3.3.0sur d'autres processeurs
Non pris en charge sur NVIDIA .
Exporter vers ExecuTorch
from ultralytics.utils.export import torch2executorch
torch2executorch(model, im, output_dir="resnet18_executorch_model")
Les données exportées .pte Le fichier est enregistré dans le répertoire de sortie :
resnet18_executorch_model/
└── model.pte
Nécessite torch>=2.9.0 et un runtime ExecuTorch correspondant (pip install executorch). Pour l'utilisation en exécution, consultez le Intégration d'ExecuTorch.
Vérifiez votre modèle exporté
Après l'exportation, vérifiez la cohérence des données avec le PyTorch d'origine avant la mise en production. Effectuez un test de fonctionnement rapide avec ONNXBackend de ultralytics.nn.backends compare les résultats et signale rapidement les erreurs de traçage ou de quantification :
import numpy as np
import timm
import torch
from ultralytics.nn.backends import ONNXBackend
model = timm.create_model("resnet18", pretrained=True).eval()
im = torch.randn(1, 3, 224, 224)
with torch.no_grad():
pytorch_output = model(im).numpy()
onnx_model = ONNXBackend("resnet18.onnx", device=torch.device("cpu"))
onnx_output = onnx_model.forward(im)[0]
diff = np.abs(pytorch_output - onnx_output).max()
print(f"Max difference: {diff:.6f}") # should be < 1e-5
Différence attendue
Pour les exportations en FP32, la différence absolue maximale doit être inférieure à 1e-5. Des écarts plus importants indiquent des opérations non prises en charge, une forme d'entrée incorrecte ou un modèle qui n'est pas en mode évaluation. Les exportations en FP16 et INT8 ont des tolérances plus souples. Effectuez la validation sur des données réelles plutôt que sur des tenseurs aléatoires.
Dans d'autres environnements d'exécution, le tensor d'entrée peut varier. OpenVINO, par exemple, utilise le nom de l'argument de propagation du modèle (généralement x (pour les modèles génériques), tandis que torch2onnx par défaut "images".
Limitations connues
- La prise en charge des entrées multiples est inégale:
torch2onnxettorch2openvinoaccepter un tuple ou une liste de tenseurs d'exemple pour les modèles à entrées multiples.torch2torchscript,torch2coreml,torch2ncnn,torch2paddle, ettorch2executorchsupposons un tensor d'entrée unique. - ExecuTorch a besoin de
flatc: Le runtime ExecuTorch nécessite le compilateur FlatBuffers. Installez-le avecbrew install flatbufferssous macOS ouapt install flatbuffers-compilersous Ubuntu. - Aucune déduction via Ultralytics:YOLO exportés ne peuvent pas être rechargés via
YOLO()pour l'inférence. Utilisez le moteur d'exécution natif pour chaque format (ONNX, OpenVINO, etc.). - FormatsYOLO: les exportations vers Axelera et Sony IMX500 nécessitent des attributs de modèle YOLO et ne sont pas disponibles pour les modèles génériques.
- Formats spécifiques à chaque plateforme: TensorRT nécessite unGPU NVIDIA . RKNN nécessite la
rknn-toolkit2SDK (Linux uniquement). Edge TPU nécessite laedgetpu_compilerbinaire (Linux uniquement).
FAQ
Quels modèles puis-je exporter avec Ultralytics?
N'importe quel torch.nn.Module. Cela inclut les modèles de timm, torchvision ou tout autre PyTorch personnalisé. Le modèle doit être en mode évaluation (model.eval()) avant l'exportation. ONNX OpenVINO acceptent OpenVINO un tuple de tenseurs d'exemple pour les modèles à entrées multiples.
Quels formats d'exportation fonctionnent sans carte GPU?
Tous les formats pris en charge (TorchScript, ONNX, OpenVINO, CoreML, TF SavedModel, TF Graph, NCNN, PaddlePaddle, MNN, ExecuTorch) peuvent être exportés sur CPU. Aucun GPU nécessaire pour le processus d'exportation lui-même. TensorRT le seul format qui nécessite unGPU NVIDIA .
De quelle Ultralytics ai-je besoin ?
Utiliser Ultralytics >=8.4.38, qui comprend le ultralytics.utils.export module et la norme output_file/output_dir arguments.
Puis-je exporter un modèle TorchVision vers CoreML iOS ?
Oui. Les classificateurs, détecteurs et modèles de segmentation de TorchVision s'exportent vers .mlpackage via torch2coreml. Pour les modèles de classification d'images, transmettez une liste de noms de classes à classifier_names pour l'intégrer dans un modèle de classification. Exécutez l'exportation sous macOS ou Linux. CoreML pas pris en charge sous Windows. Consultez la CoreML pour plus de détails sur iOS .
Puis-je quantifier mon modèle exporté en INT8 ou FP16 ?
Oui, pour plusieurs formats. OK half=True pour FP16 ou int8=True pour INT8 lors de l'exportation vers OpenVINO, CoreML, MNN ou NCNN. L'utilisation d'INT8 dans OpenVINO nécessite OpenVINO un calibration_dataset argument pour quantification post-entraînement. Consultez la page d'intégration de chaque format pour connaître les compromis en matière de quantification.