Passer au contenu

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.

FormatFonctionInstallerSortie
ONNXtorch2onnx()pip install onnx.onnx fichier
TorchScripttorch2torchscript()fourni avec PyTorch.torchscript fichier
OpenVINOtorch2openvino()pip install openvino_openvino_model/ répertoire
CoreMLtorch2coreml()pip install coremltools.mlpackage
TF SavedModelonnx2saved_model()voir les conditions détaillées ci-dessous_saved_model/ répertoire
Graphique TFkeras2pb()voir les conditions détaillées ci-dessous.pb fichier
NCNNtorch2ncnn()pip install ncnn pnnx_ncnn_model/ répertoire
MNNonnx2mnn()pip install MNN.mnn fichier
PaddlePaddletorch2paddle()pip install paddlepaddle x2paddle_paddle_model/ répertoire
ExecuTorchtorch2executorch()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.0
  • onnx2tf>=1.26.3,<1.29.0
  • tf_keras<=2.19.0
  • sng4onnx>=1.0.1
  • onnx_graphsurgeon>=0.3.26 (installer avec --extra-index-url https://pypi.ngc.nvidia.com)
  • ai-edge-litert>=1.2.0,<1.4.0 sous macOS (ai-edge-litert>=1.2.0 (sur d'autres plateformes)
  • onnxslim>=0.1.71
  • onnx>=1.12.0,<2.0.0
  • protobuf>=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.0 sur CUDA
  • paddlepaddle==3.0.0 sur CPU ARM64
  • paddlepaddle>=3.0.0,<3.3.0 sur 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: torch2onnx et torch2openvino accepter un tuple ou une liste de tenseurs d'exemple pour les modèles à entrées multiples. torch2torchscript, torch2coreml, torch2ncnn, torch2paddle, et torch2executorch supposons un tensor d'entrée unique.
  • ExecuTorch a besoin de flatc: Le runtime ExecuTorch nécessite le compilateur FlatBuffers. Installez-le avec brew install flatbuffers sous macOS ou apt install flatbuffers-compiler sous 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-toolkit2 SDK (Linux uniquement). Edge TPU nécessite la edgetpu_compiler binaire (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.



📅 Créé il y a 0 jours ✏️ Mis à jour il y a 0 jours
raimbekovm

Commentaires