Link to this sectionSo exportierst du PyTorch-Modelle, die keine YOLO-Modelle sind, mit Ultralytics#
Ultralytics bietet eigenständige Export-Dienstprogramme unter ultralytics.utils.export an, die mehrere Backends hinter einer konsistenten Schnittstelle bündeln. Du kannst jedes torch.nn.Module, einschließlich timm Bildmodelle, torchvision Klassifikatoren und Detektoren oder deine eigenen benutzerdefinierten Architekturen, nach ONNX, TorchScript, OpenVINO, CoreML, NCNN, PaddlePaddle, MNN, ExecuTorch und TensorFlow SavedModel exportieren, ohne jedes Backend einzeln erlernen zu müssen.
Das Bereitstellen von PyTorch Modellen in der Produktion bedeutet normalerweise, dass man für jedes Ziel einen anderen Exporter jonglieren muss: torch.onnx.export für ONNX, coremltools für Apple-Geräte, onnx2tf für TensorFlow, pnnx für NCNN und so weiter. Jedes Tool hat seine eigene API, Abhängigkeitsbesonderheiten und Ausgabekonventionen. Diese Dienstprogramme fassen das in einem einzigen Aufrufmuster zusammen.
Link to this sectionWarum Ultralytics für den Nicht-YOLO-Export verwenden?#
- Eine API für 10 Formate: Lerne eine einzige Aufrufkonvention statt eines Dutzends.
- Gemeinsame Hilfsoberfläche: Die Export-Helfer befinden sich unter
ultralytics.utils.export. Sobald die Backend-Pakete installiert sind, kannst du dasselbe Aufrufmuster über alle Formate hinweg beibehalten. - Derselbe Codepfad wie bei YOLO-Exporten: Dieselben Helfer steuern jeden Ultralytics YOLO-Export.
- FP16- und INT8-Quantisierung ist für unterstützte Formate (OpenVINO, CoreML, MNN, NCNN) integriert.
- Funktioniert auf der CPU: Für den Export-Schritt selbst ist keine GPU erforderlich, sodass du ihn lokal auf jedem Laptop ausführen kannst.
Link to this sectionKurzanleitung#
Der schnellste Weg ist ein Export in zwei Zeilen nach ONNX ohne YOLO-Code und ohne Einrichtung außer 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")Link to this sectionUnterstützte Exportformate#
Die torch2*-Funktionen nehmen ein Standard-torch.nn.Module und einen Beispiel-Eingabe-Tensor entgegen. MNN, TF SavedModel und TF Frozen Graph durchlaufen ein zwischengeschaltetes ONNX- oder Keras-Artefakt. In beiden Fällen sind keine YOLO-spezifischen Attribute erforderlich.
| Format | Funktion | Installieren | Ausgabe |
|---|---|---|---|
| ONNX | torch2onnx() | pip install onnx | .onnx-Datei |
| TorchScript | torch2torchscript() | in PyTorch enthalten | .torchscript-Datei |
| OpenVINO | torch2openvino() | pip install openvino | _openvino_model/-Verzeichnis |
| CoreML | torch2coreml() | pip install coremltools | .mlpackage |
| TF SavedModel | onnx2saved_model() | siehe detaillierte Anforderungen unten | _saved_model/-Verzeichnis |
| TF Frozen Graph | keras2pb() | siehe detaillierte Anforderungen unten | .pb-Datei |
| NCNN | torch2ncnn() | pip install ncnn pnnx | _ncnn_model/-Verzeichnis |
| MNN | onnx2mnn() | pip install MNN | .mnn-Datei |
| PaddlePaddle | torch2paddle() | pip install paddlepaddle x2paddle | _paddle_model/-Verzeichnis |
| ExecuTorch | torch2executorch() | pip install executorch | _executorch_model/-Verzeichnis |
MNN, TF SavedModel und TF Frozen Graph-Exporte laufen über ONNX als Zwischenschritt. Exportiere zuerst nach ONNX und konvertiere dann.
Einige Export-Funktionen akzeptieren ein optionales metadata-Wörterbuch (z. B. torch2torchscript(..., metadata={"author": "me"})), das benutzerdefinierte Schlüssel-Wert-Paare in das exportierte Artefakt einbettet, sofern das Format dies unterstützt.
Link to this sectionSchritt-für-Schritt-Beispiele#
Jedes Beispiel unten verwendet dieselbe Einrichtung: ein vortrainiertes ResNet-18 von timm im Evaluierungsmodus:
import timm
import torch
model = timm.create_model("resnet18", pretrained=True).eval()
im = torch.randn(1, 3, 224, 224)Dropout, Batch Normalization und andere reine Trainings-Layer verhalten sich während der Inferenz anders. Das Überspringen von .eval() führt zu Exporten mit falschen Ausgaben.
Link to this sectionExport nach ONNX#
from ultralytics.utils.export import torch2onnx
torch2onnx(model, im, output_file="resnet18.onnx")Für eine dynamische Batch-Größe übergib ein dynamic-Wörterbuch:
torch2onnx(model, im, output_file="resnet18_dyn.onnx", dynamic={"images": {0: "batch_size"}})Das Standard-Opset ist 14 und der Standard-Eingabename ist "images". Überschreibe dies mit den Argumenten opset, input_names oder output_names.
Link to this sectionExport nach TorchScript#
Keine zusätzlichen Abhängigkeiten erforderlich. Verwendet torch.jit.trace im Hintergrund.
from ultralytics.utils.export import torch2torchscript
torch2torchscript(model, im, output_file="resnet18.torchscript")Link to this sectionExport nach OpenVINO#
from ultralytics.utils.export import torch2openvino
ov_model = torch2openvino(model, im, output_dir="resnet18_openvino_model")Das Verzeichnis enthält ein Paar aus model.xml und model.bin mit festem Namen:
resnet18_openvino_model/
├── model.xml
└── model.binÜbergib dynamic=True für dynamische Eingabe-Shapes, quantize=16 für FP16 oder quantize=8 für INT8-Quantisierung. INT8 erfordert zusätzlich ein calibration_dataset-Argument.
Erfordert openvino>=2024.0.0 (oder >=2025.2.0 unter macOS 15.4+) und torch>=2.1.
Link to this sectionExport nach 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, classifier_names=None, output_file="resnet18.mlpackage")Für Klassifizierungsmodelle übergib eine Liste von Klassennamen an classifier_names, um dem CoreML-Modell einen Klassifizierungskopf hinzuzufügen.
Erfordert coremltools>=9.0, torch>=1.11 und numpy<=2.3.5. Unter Windows nicht unterstützt.
coremltools>=9.0 liefert Wheels für Python 3.10–3.13 unter macOS und Linux aus. Bei neueren Python-Versionen lädt die native C-Erweiterung nicht. Verwende Python 3.10–3.13 für den CoreML-Export.
Link to this sectionExport nach TensorFlow SavedModel#
Der Export von TF SavedModel erfolgt über ONNX als Zwischenschritt:
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")Die Funktion gibt ein Keras-Modell zurück und generiert zusätzlich TFLite-Dateien (.tflite) im Ausgabeverzeichnis:
resnet18_saved_model/
├── saved_model.pb
├── variables/
├── resnet18_float32.tflite
├── resnet18_float16.tflite
└── resnet18_int8.tfliteAnforderungen:
tensorflow>=2.0.0,<=2.19.0onnx2tf>=1.26.3,<1.29.0tf_keras<=2.19.0sng4onnx>=1.0.1onnx_graphsurgeon>=0.3.26(installiere mit--extra-index-url https://pypi.ngc.nvidia.com)ai-edge-litert>=1.2.0,<1.4.0unter macOS (ai-edge-litert>=1.2.0auf anderen Plattformen)onnxslim>=0.1.82onnx>=1.12.0,<2.0.0protobuf>=5
Link to this sectionExport nach TensorFlow Frozen Graph#
Weiterführend vom SavedModel-Export oben, konvertiere das zurückgegebene keras_model in einen gefrorenen .pb Graphen:
from pathlib import Path
from ultralytics.utils.export import keras2pb
keras2pb(keras_model, output_file=Path("resnet18_saved_model/resnet18.pb"))Link to this sectionExport nach NCNN#
from ultralytics.utils.export import torch2ncnn
torch2ncnn(model, im, output_dir="resnet18_ncnn_model")Das Verzeichnis enthält param- und bin-Dateien mit festem Namen sowie einen Python-Wrapper:
resnet18_ncnn_model/
├── model.ncnn.param
├── model.ncnn.bin
└── model_ncnn.pytorch2ncnn() prüft bei der ersten Verwendung auf ncnn und pnnx.
Link to this sectionExport nach MNN#
Der MNN-Export erfordert eine ONNX-Datei als Eingabe. Exportiere zuerst nach ONNX und konvertiere dann:
from ultralytics.utils.export import onnx2mnn, torch2onnx
torch2onnx(model, im, output_file="resnet18.onnx")
onnx2mnn("resnet18.onnx", output_file="resnet18.mnn")Unterstützt quantize=16 für FP16 und quantize=8 für INT8-Quantisierung. Erfordert MNN>=2.9.6 und torch>=1.10.
Link to this sectionExport nach PaddlePaddle#
from ultralytics.utils.export import torch2paddle
torch2paddle(model, im, output_dir="resnet18_paddle_model")Das Verzeichnis enthält das PaddlePaddle-Modell und Parameterdateien:
resnet18_paddle_model/
├── model.pdmodel
└── model.pdiparamsErfordert x2paddle und die korrekte PaddlePaddle-Distribution für deine Plattform:
paddlepaddle-gpu>=3.0.0,<3.3.0auf CUDApaddlepaddle==3.0.0auf ARM64 CPUpaddlepaddle>=3.0.0,<3.3.0auf anderen CPUs
Wird auf NVIDIA Jetson nicht unterstützt.
Link to this sectionExport nach ExecuTorch#
from ultralytics.utils.export import torch2executorch
torch2executorch(model, im, output_dir="resnet18_executorch_model")Die exportierte .pte-Datei wird im Ausgabeverzeichnis gespeichert:
resnet18_executorch_model/
└── model.pteErfordert torch>=2.9.0 und eine passende ExecuTorch-Laufzeitumgebung (pip install executorch). Informationen zur Nutzung der Laufzeitumgebung findest du in der ExecuTorch-Integration.
Link to this sectionÜberprüfe dein exportiertes Modell#
Überprüfe nach dem Export die numerische Parität mit dem ursprünglichen PyTorch Modell, bevor du es bereitstellst. Ein schneller Smoke-Test mit ONNXBackend aus ultralytics.nn.backends vergleicht Ausgaben und markiert frühzeitig Tracing- oder Quantisierungsfehler:
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(im)[0]
diff = np.abs(pytorch_output - onnx_output).max()
print(f"Max difference: {diff:.6f}") # typically ~1e-5, well under 1e-4 for FP32Bei FP32-Exporten liegt die maximale absolute Differenz typischerweise bei etwa 1e-5 und sollte deutlich unter 1e-4 bleiben. Größere Unterschiede deuten auf nicht unterstützte Operationen, eine falsche Eingabeform oder ein Modell hin, das sich nicht im Eval-Modus befindet. FP16- und INT8-Exporte haben lockerere Toleranzen. Validieren auf echten Daten statt mit zufälligen Tensoren.
Bei anderen Laufzeitumgebungen kann der Name des Eingabetensors abweichen. OpenVINO verwendet beispielsweise den Namen des Forward-Arguments des Modells (typischerweise x bei generischen Modellen), während torch2onnx standardmäßig "images" verwendet.
Link to this sectionBekannte Einschränkungen#
- Multi-Input-Unterstützung ist ungleichmäßig:
torch2onnxundtorch2openvinoakzeptieren ein Tupel oder eine Liste von Beispiel-Tensoren für Modelle mit mehreren Eingängen.torch2torchscript,torch2coreml,torch2ncnn,torch2paddleundtorch2executorchsetzen einen einzelnen Eingabetensor voraus. - ExecuTorch benötigt
flatc: Die ExecuTorch-Laufzeit erfordert den FlatBuffers-Compiler. Installiere ihn mitbrew install flatbuffersauf macOS oderapt install flatbuffers-compilerauf Ubuntu. - Keine Inferenz über Ultralytics: Exportierte Nicht-YOLO-Modelle können nicht über
YOLO()zur Inferenz geladen werden. Nutze die native Laufzeitumgebung für jedes Format (ONNX Runtime, OpenVINO Runtime usw.). - Nur-YOLO-Formate: Axelera und Sony IMX500 Exporte erfordern YOLO-spezifische Modellattribute und sind für generische Modelle nicht verfügbar.
- Plattformspezifische Formate: TensorRT erfordert eine NVIDIA GPU. RKNN erfordert das
rknn-toolkit2SDK (nur Linux). Edge TPU erfordert dieedgetpu_compiler-Binary (nur Linux).
Link to this sectionFazit#
Diese Dienstprogramme nehmen jedes PyTorch Modell von einem einfachen torch.nn.Module bis hin zu einem einsatzbereiten ONNX, OpenVINO, CoreML, TensorFlow oder Mobile-Runtime-Artefakt über eine konsistente API entgegen. Wähle das Format, das zu deiner Zielhardware passt, überprüfe die numerische Parität gegenüber dem ursprünglichen Modell und folge dann dem passenden Integrationsleitfaden für laufzeit-spezifische Bereitstellungsschritte.
Link to this sectionFAQ#
Link to this sectionWelche Modelle kann ich mit Ultralytics exportieren?#
Jedes torch.nn.Module. Dazu gehören Modelle von timm, torchvision oder jedes beliebige benutzerdefinierte PyTorch-Modell. Das Modell muss sich vor dem Export im Evaluierungsmodus (model.eval()) befinden. ONNX und OpenVINO akzeptieren zusätzlich ein Tupel von Beispiel-Tensoren für Multi-Input-Modelle.
Link to this sectionWelche Exportformate funktionieren ohne GPU?#
Alle unterstützten Formate (TorchScript, ONNX, OpenVINO, CoreML, TF SavedModel, TF Frozen Graph, NCNN, PaddlePaddle, MNN, ExecuTorch) können auf der CPU exportiert werden. Für den Exportprozess selbst ist keine GPU erforderlich. TensorRT ist das einzige Format, das eine NVIDIA GPU benötigt.
Link to this sectionWelche Ultralytics-Version benötige ich?#
Verwende Ultralytics >=8.4.38, das das ultralytics.utils.export-Modul und die standardisierten output_file/output_dir-Argumente enthält.
Link to this sectionKann ich ein torchvision-Modell für die iOS-Bereitstellung nach CoreML exportieren?#
Ja. torchvision-Klassifikatoren, Detektoren und Segmentierungsmodelle exportieren nach .mlpackage via torch2coreml. Für Bildklassifizierungsmodelle übergib eine Liste von Klassennamen an classifier_names, um einen Klassifikations-Head einzubetten. Führe den Export auf macOS oder Linux aus. CoreML wird unter Windows nicht unterstützt. Siehe die CoreML-Integration für Details zur iOS-Bereitstellung.
Link to this sectionKann ich mein exportiertes Modell auf INT8 oder FP16 quantisieren?#
Ja, für verschiedene Formate. Übergib quantize=16 für FP16 oder quantize=8 für INT8 beim Export nach OpenVINO, CoreML, MNN oder NCNN. INT8 erfordert in OpenVINO zusätzlich ein calibration_dataset-Argument für die post-training quantization. Siehe die Integrationsseite des jeweiligen Formats für Abwägungen zur Quantisierung.
Link to this sectionWie überprüfe ich, ob ein exportiertes Modell dem Original entspricht?#
Führe das ursprüngliche PyTorch Modell und das exportierte Modell mit derselben Eingabe aus und vergleiche dann die Ausgaben. Lade die exportierte Datei mit dem passenden Backend (zum Beispiel ONNXBackend für ONNX) und prüfe die maximale absolute Differenz. Bei FP32-Exporten liegt diese typischerweise bei etwa 1e-5 und sollte deutlich unter 1e-4 bleiben; größere Abweichungen deuten auf nicht unterstützte Operationen, eine falsche Eingabeform oder ein Modell hin, das nicht im Eval-Modus ist. Siehe Überprüfe dein exportiertes Modell für ein ausführbares Beispiel.