Vai al contenuto

Come esportarePyTorch YOLO con Ultralytics

L'implementazione PyTorch in produzione comporta solitamente l'utilizzo di un esportatore diverso per ogni destinazione: torch.onnx.export per ONNX, coremltools per i dispositivi Apple, onnx2tf per TensorFlow, pnnx per NCNN e così via. Ogni strumento ha la propria API, le proprie peculiarità in termini di dipendenze e le proprie convenzioni di output.

Ultralytics strumenti di esportazione autonomi che integrano diversi backend in un'unica interfaccia coerente. È possibile esportare qualsiasi torch.nn.Module, tra cui timm modelli di immagini, torchvision classificatori e rilevatori, oppure le vostre architetture personalizzate, per ONNX, TorchScript, OpenVINO, CoreML, NCNN, PaddlePaddle, MNN, ExecuTorch, e TensorFlow SavedModel senza dover imparare ogni backend separatamente.

Perché utilizzare Ultralytics YOLO ?

  • Un'unica API per 10 formati: basta imparare una sola convenzione di chiamata invece di una dozzina.
  • Superficie comune: gli assistenti all'esportazione si trovano in ultralytics.utils.export, quindi una volta installati i pacchetti di backend potrai mantenere lo stesso schema di chiamata in tutti i formati.
  • Lo stesso percorso di codice YOLO : le stesse funzioni di supporto sono alla base di ogniYOLO Ultralytics .
  • Quantizzazione FP16 e INT8 integrata per i formati che la supportano (OpenVINO, CoreML, MNN, NCNN).
  • Funziona sulla CPU: non GPU per la fase di esportazione, quindi è possibile eseguirlo localmente su qualsiasi portatile.

Guida rapida

Il modo più veloce è un'esportazione su due righe in ONNX senza YOLO e senza alcuna configurazione oltre a 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")

Formati di esportazione supportati

Il torch2* le funzioni accettano un parametro standard torch.nn.Module e un tensor di input di esempio. MNN, TF SavedModel e TF Graph passano attraverso un artefatto intermedio ONNX Keras. In entrambi i casi non sono richiesti attributi YOLO.

FormatoFunzioneInstallaOutput
ONNXtorch2onnx()pip install onnx.onnx file
TorchScripttorch2torchscript()incluso in PyTorch.torchscript file
OpenVINOtorch2openvino()pip install openvino_openvino_model/ directory
CoreMLtorch2coreml()pip install coremltools.mlpackage
TF SavedModelonnx2saved_model()vedere i requisiti dettagliati di seguito_saved_model/ directory
Grafico TFkeras2pb()vedere i requisiti dettagliati di seguito.pb file
NCNNtorch2ncnn()pip install ncnn pnnx_ncnn_model/ directory
MNNonnx2mnn()pip install MNN.mnn file
PaddlePaddletorch2paddle()pip install paddlepaddle x2paddle_paddle_model/ directory
ExecuTorchtorch2executorch()pip install executorch_executorch_model/ directory

ONNX formato intermedio

MNN, TF SavedModele TF Graph passano attraverso ONNX fase intermedia. Esporta ONNX in ONNX , poi converti.

Incorporazione dei metadati

Diverse funzioni di esportazione accettano un parametro facoltativo metadata dizionario (ad es., torch2torchscript(..., metadata={"author": "me"})) che inserisce coppie chiave-valore personalizzate nell'artefatto esportato, laddove il formato lo consenta.

Esempi passo dopo passo

Tutti gli esempi riportati di seguito utilizzano la stessa configurazione, ovvero una rete ResNet-18 preaddestrata proveniente dal pacchetto timm in modalità di valutazione:

import timm
import torch

model = timm.create_model("resnet18", pretrained=True).eval()
im = torch.randn(1, 3, 224, 224)

Chiama sempre model.eval() prima dell'esportazione

Abbandono scolastico, normalizzazione batch, e altri livelli riservati ai treni si comportano in modo diverso durante l'inferenza. Saltando .eval() genera esportazioni con risultati errati.

Esporta in ONNX

from ultralytics.utils.export import torch2onnx

torch2onnx(model, im, output_file="resnet18.onnx")

Per una dimensione del lotto dinamica, passare un dynamic dizionario:

torch2onnx(model, im, output_file="resnet18_dyn.onnx", dynamic={"images": {0: "batch_size"}})

Il valore predefinito di opset è 14 e il nome predefinito dell'input è "images". Sovrascrivere con il opset, input_names, oppure output_names argomenti.

Esporta in TorchScript

Non sono necessarie dipendenze aggiuntive. Utilizza torch.jit.trace dietro le quinte.

from ultralytics.utils.export import torch2torchscript

torch2torchscript(model, im, output_file="resnet18.torchscript")

Esporta in OpenVINO

from ultralytics.utils.export import torch2openvino

ov_model = torch2openvino(model, im, output_dir="resnet18_openvino_model")

La directory contiene un file con nome fisso model.xml e model.bin coppia:

resnet18_openvino_model/
├── model.xml
└── model.bin

Passa dynamic=True per forme di input dinamiche, half=True per FP16, oppure int8=True per la quantizzazione a 8 bit. La quantizzazione a 8 bit richiede inoltre un calibration_dataset .

È necessario openvino>=2024.0.0 (o >=2025.2.0 su macOS 15.4 e versioni successive) e torch>=2.1.

Esporta in 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")

Per classificazione modelli, passare un elenco di nomi di classi a classifier_names per aggiungere un'intestazione di classificazione al CoreML .

È necessario coremltools>=9.0, torch>=1.11, e numpy<=2.3.5. Non supportato su Windows.

BlobWriter not loaded errore

coremltools>=9.0 Supporta Python .10–3.13 su macOS e Linux. Nelle Python più recenti Python , l'estensione nativa in C non viene caricata. Utilizza Python .10–3.13 per CoreML .

Esporta in TensorFlow SavedModel

SavedModel TF SavedModel passa attraverso ONNX fase intermedia:

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 funzione restituisce un modello Keras e genera anche TFLite (.tflite) all'interno della directory di output:

resnet18_saved_model/
├── saved_model.pb
├── variables/
├── resnet18_float32.tflite
├── resnet18_float16.tflite
└── resnet18_int8.tflite

Requisiti:

  • 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 (installare con --extra-index-url https://pypi.ngc.nvidia.com)
  • ai-edge-litert>=1.2.0,<1.4.0 su macOS (ai-edge-litert>=1.2.0 (su altre piattaforme)
  • onnxslim>=0.1.71
  • onnx>=1.12.0,<2.0.0
  • protobuf>=5

Esporta in grafico TensorFlow

A seguito SavedModel descritta sopra, converti il modello Keras restituito in un modello congelato .pb grafico:

from pathlib import Path

from ultralytics.utils.export import keras2pb

keras2pb(keras_model, output_file=Path("resnet18_saved_model/resnet18.pb"))

Esporta su NCNN

from ultralytics.utils.export import torch2ncnn

torch2ncnn(model, im, output_dir="resnet18_ncnn_model")

La directory contiene file *param* e *bin* con nomi fissi, oltre a un Python :

resnet18_ncnn_model/
├── model.ncnn.param
├── model.ncnn.bin
└── model_ncnn.py

torch2ncnn() verifica la presenza di ncnn e pnnx al primo utilizzo.

Esporta su MNN

L'esportazione MNN richiede un ONNX come input. Esporta ONNX in ONNX , poi converti:

from ultralytics.utils.export import onnx2mnn, torch2onnx

torch2onnx(model, im, output_file="resnet18.onnx")
onnx2mnn("resnet18.onnx", output_file="resnet18.mnn")

Supporti half=True per FP16 e int8=True per la quantizzazione INT8. Richiede MNN>=2.9.6 e torch>=1.10.

Esporta su PaddlePaddle

from ultralytics.utils.export import torch2paddle

torch2paddle(model, im, output_dir="resnet18_paddle_model")

La directory contiene i file PaddlePaddle e dei parametri PaddlePaddle :

resnet18_paddle_model/
├── model.pdmodel
└── model.pdiparams

È necessario x2paddle e la PaddlePaddle corretta per la tua piattaforma:

  • paddlepaddle-gpu>=3.0.0,<3.3.0 su CUDA
  • paddlepaddle==3.0.0 su CPU ARM64
  • paddlepaddle>=3.0.0,<3.3.0 su altre CPU

Non supportato su NVIDIA .

Esporta in ExecuTorch

from ultralytics.utils.export import torch2executorch

torch2executorch(model, im, output_dir="resnet18_executorch_model")

Il file esportato .pte Il file viene salvato nella directory di output:

resnet18_executorch_model/
└── model.pte

È necessario torch>=2.9.0 e un runtime ExecuTorch corrispondente (pip install executorch). Per informazioni sull'utilizzo durante l'esecuzione, consultare il Integrazione con ExecuTorch.

Verifica il modello esportato

Dopo l'esportazione, verificare la corrispondenza dei valori numerici con il PyTorch originale prima della distribuzione. Un rapido test di verifica con ONNXBackend da ultralytics.nn.backends confronta i risultati e segnala tempestivamente eventuali errori di tracciamento o quantizzazione:

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

Differenza prevista

Per le esportazioni in FP32, la differenza assoluta massima dovrebbe essere inferiore a 1e-5. Differenze più marcate indicano operazioni non supportate, una forma di input errata o un modello non in modalità di valutazione. Le esportazioni in FP16 e INT8 presentano tolleranze più ampie. Verificare su dati reali anziché su tensori casuali.

Per altri runtime, tensor di input potrebbe variare. OpenVINO, ad esempio, utilizza il nome dell'argomento di propagazione del modello (in genere x (per i modelli generici), mentre torch2onnx il valore predefinito è "images".

Limitazioni Note

  • Il supporto per più ingressi è disomogeneo: torch2onnx e torch2openvino accettare una tupla o una lista di tensori di esempio per modelli con più ingressi. torch2torchscript, torch2coreml, torch2ncnn, torch2paddle, e torch2executorch si supponga un singolo tensor di input.
  • ExecuTorch richiede flatc: Il runtime di ExecuTorch richiede il compilatore FlatBuffers. Installarlo con brew install flatbuffers su macOS oppure apt install flatbuffers-compiler su Ubuntu.
  • Nessuna deduzione tramite Ultralytics:YOLO esportati non possono essere ricaricati tramite YOLO() per l'inferenza. Utilizza il runtime nativo per ciascun formato (ONNX, OpenVINO, ecc.).
  • FormatiYOLO: le esportazioni per Axelera e Sony IMX500 richiedono attributi YOLO e non sono disponibili per i modelli generici.
  • Formati specifici per piattaforma: TensorRT richiede unaGPU NVIDIA . RKNN richiede il rknn-toolkit2 SDK (solo Linux). Edge TPU richiede il edgetpu_compiler binario (solo Linux).

FAQ

Quali modelli posso esportare con Ultralytics?

Qualsiasi torch.nn.Module. Ciò include modelli di timm, torchvision o qualsiasi PyTorch personalizzato. Il modello deve essere in modalità di valutazione (model.eval()) prima dell'esportazione. ONNX OpenVINO accettano OpenVINO una tupla di tensori di esempio per i modelli a più ingressi.

Quali formati di esportazione funzionano senza una GPU?

Tutti i formati supportati (TorchScript, ONNX, OpenVINO, CoreML, TF SavedModel, TF Graph, NCNN, PaddlePaddle, MNN, ExecuTorch) possono essere esportati su CPU. Per il processo di esportazione non GPU necessaria alcuna GPU . TensorRT l'unico formato che richiede unaGPU NVIDIA .

Di quale Ultralytics ho bisogno?

Utilizzare Ultralytics >=8.4.38, che comprende il ultralytics.utils.export modulo e lo standardizzato output_file/output_dir argomenti.

È possibile esportare un modello TorchVision in CoreML iOS ?

Sì. I classificatori, i rilevatori e i modelli di segmentazione di TorchVision possono essere esportati in .mlpackage tramite torch2coreml. Per i modelli di classificazione delle immagini, passare un elenco di nomi di classi a classifier_names da elaborare in un classificatore. Eseguire l'esportazione su macOS o Linux. CoreML non CoreML supportato su Windows. Vedere il CoreML per i dettagli iOS .

Posso quantizzare il mio modello esportato a INT8 o FP16?

Sì, per diversi formati. Passa half=True per FP16 oppure int8=True per INT8 durante l'esportazione in OpenVINO, CoreML, MNN o NCNN. L'INT8 in OpenVINO richiede OpenVINO un calibration_dataset argomento per quantizzazione post-addestramento. Per i compromessi relativi alla quantizzazione, consultare la pagina dedicata all'integrazione di ciascun formato.



📅 Creato 0 giorni fa ✏️ Aggiornato 0 giorni fa
raimbekovm

Commenti