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.
| Formato | Funzione | Installa | Output |
|---|---|---|---|
| ONNX | torch2onnx() | pip install onnx | .onnx file |
| TorchScript | torch2torchscript() | incluso in PyTorch | .torchscript file |
| OpenVINO | torch2openvino() | pip install openvino | _openvino_model/ directory |
| CoreML | torch2coreml() | pip install coremltools | .mlpackage |
| TF SavedModel | onnx2saved_model() | vedere i requisiti dettagliati di seguito | _saved_model/ directory |
| Grafico TF | keras2pb() | vedere i requisiti dettagliati di seguito | .pb file |
| NCNN | torch2ncnn() | pip install ncnn pnnx | _ncnn_model/ directory |
| MNN | onnx2mnn() | pip install MNN | .mnn file |
| PaddlePaddle | torch2paddle() | pip install paddlepaddle x2paddle | _paddle_model/ directory |
| ExecuTorch | torch2executorch() | 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.0onnx2tf>=1.26.3,<1.29.0tf_keras<=2.19.0sng4onnx>=1.0.1onnx_graphsurgeon>=0.3.26(installare con--extra-index-url https://pypi.ngc.nvidia.com)ai-edge-litert>=1.2.0,<1.4.0su macOS (ai-edge-litert>=1.2.0(su altre piattaforme)onnxslim>=0.1.71onnx>=1.12.0,<2.0.0protobuf>=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.0su CUDApaddlepaddle==3.0.0su CPU ARM64paddlepaddle>=3.0.0,<3.3.0su 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:
torch2onnxetorch2openvinoaccettare una tupla o una lista di tensori di esempio per modelli con più ingressi.torch2torchscript,torch2coreml,torch2ncnn,torch2paddle, etorch2executorchsi supponga un singolo tensor di input. - ExecuTorch richiede
flatc: Il runtime di ExecuTorch richiede il compilatore FlatBuffers. Installarlo conbrew install flatbufferssu macOS oppureapt install flatbuffers-compilersu 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-toolkit2SDK (solo Linux). Edge TPU richiede iledgetpu_compilerbinario (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.