Für den Einsatz exportieren
Exportiere best.pt nach ONNX, OpenVINO, TensorRT, CoreML, LiteRT oder QNN und weise vor der Bereitstellung nach, dass der Export mit dem PyTorch-Modell übereinstimmt.
Dein best.pt benötigt Python und PyTorch für die Ausführung; auf Smartphones, in Browsern, auf Jetsons und auf Produktionsservern sind diese normalerweise nicht verfügbar. Der Export-Modus wandelt das Modell mit einem einzigen Aufruf in eine eigenständige Datei für diese Laufzeitumgebungen um. Dabei gilt: Nur weil sich ein Export laden lässt, ist er nicht automatisch korrekt. Ein unüberlegter Vergleich kann einen korrekten Export fehlerhaft erscheinen lassen oder einen fehlerhaften Export verbergen.
In dieser Lektion exportierst du das Pillenmodell nach ONNX, führst es über dieselbe YOLO-API aus, weist anhand von Boxen und mAP auf dem Validierungssatz bei gleichen Einstellungen nach, dass es mit PyTorch übereinstimmt, und wählst das für dein Ziel geeignete Format: ONNX, OpenVINO, TensorRT, CoreML, LiteRT oder QNN.
Praxisnah
Beispiel: Nach ONNX exportieren#

yolo export model=runs/detect/pills_v1/weights/best.pt format=onnxPyTorch: starting from 'runs/detect/pills_v1/weights/best.pt' with input shape (1, 3, 320, 320) BCHW and output shape(s) (1, 5, 2100) (5.2 MB)
ONNX: export success ✅ 0.9s, saved as 'runs/detect/pills_v1/weights/best.onnx' (9.3 MB)
Predict: yolo predict task=detect model=runs/detect/pills_v1/weights/best.onnx imgsz=320
Validate: yolo val task=detect model=runs/detect/pills_v1/weights/best.onnx imgsz=320 data=my_dataset/data.yamlZeile für Zeile:
input shape (1, 3, 320, 320): ein Bild, 3 Farbkanäle, ein festes Quadrat mit 320×320 Pixeln — die beim Training verwendeteimgsz, fest in der Datei hinterlegt.output shape(s) (1, 5, 2100): 4 Boxwerte plus 1 Klassenwert für 2.100 Kandidatenboxen; NMS wird standardmäßig außerhalb des Graphen ausgeführt.9.3 MB: Die ONNX-Datei speichert FP32-Gewichte und ist daher größer als die Datei mit FP16-.pt.Predict:/Validate:: fertige Befehle für die exportierte Datei, bereits mit der passendenimgsz.
Einige Argumente decken die meisten Anwendungsfälle ab; der ONNX-Integrationsleitfaden führt die übrigen auf.
| Argument | Standard | Verwenden für |
|---|---|---|
imgsz | Trainingsgröße | Mit einer anderen festen Eingabegröße exportieren, z. B. imgsz=640 |
dynamic | False | Variable Eingabegrößen statt einer einzigen festen Form akzeptieren |
quantize | Keine (FP32) | 16 für FP16-Gewichte (yolo26n.onnx sinkt von 9.5 MB auf 4.8 MB); 8 für INT8, sofern das Format dies unterstützt |
nms | Keine | nms=True bettet NMS in den Graphen ein, sodass die Laufzeitumgebung die endgültigen Boxen zurückgibt |
Beispiel: Nachweisen, dass der Export übereinstimmt#
Die Klasse YOLO lädt auch exportierte Dateien, sodass der zuvor gezeigte Predict-Code unverändert funktioniert. Vergleiche beide Dateien anhand desselben Validierungsbildes:
from ultralytics import YOLO
image = "my_dataset/images/val/Frame_144.jpg"
pt = YOLO("runs/detect/pills_v1/weights/best.pt")(image, rect=False, verbose=False)[0] # square input, like ONNX
onnx = YOLO("runs/detect/pills_v1/weights/best.onnx")(image, verbose=False)[0]
print(f"pt: {len(pt.boxes)} pills, mean conf {pt.boxes.conf.mean():.3f}")
print(f"onnx: {len(onnx.boxes)} pills, mean conf {onnx.boxes.conf.mean():.3f}")
print(f"max box difference: {(pt.boxes.xyxy - onnx.boxes.xyxy).abs().max():.4f} px")pt: 25 pills, mean conf 0.870
onnx: 25 pills, mean conf 0.870
max box difference: 0.0002 pxGleiche Anzahl, gleiche Konfidenz, Boxen bis auf einen Bruchteil eines Pixels identisch. Jetzt folgt die aussagekräftigere Prüfung: Validierung über die gesamte Aufteilung:
from ultralytics import YOLO
pt = YOLO("runs/detect/pills_v1/weights/best.pt").val(data="my_dataset/data.yaml", rect=False, verbose=False)
onnx = YOLO("runs/detect/pills_v1/weights/best.onnx").val(data="my_dataset/data.yaml", verbose=False)
print(f".pt mAP50-95 {pt.box.map:.4f}")
print(f".onnx mAP50-95 {onnx.box.map:.4f}").pt mAP50-95 0.6570
.onnx mAP50-95 0.6570Identisch. (Die rechteckige Validierung mit Standardeinstellungen für die Datei .pt ergab 0.659: eine kleine Abweichung durch das Auffüllen der Eingabe, nicht durch den Export.)
Sobald die Ergebnisse übereinstimmen, miss die Laufzeit mit yolo benchmark auf dem Zielgerät, damit du die tatsächliche Geschwindigkeit kennst, bevor du das Modell bereitstellst.
Ein Format für dein Ziel auswählen#

| Zielwert | Format | Hinweise |
|---|---|---|
| Flexibler Standard: Server und Desktop-Rechner mit Linux, Windows und Mac | onnx | ONNX Runtime auf CPU oder GPU; der am schnellsten zu überprüfende Export |
| NVIDIA-GPUs und Jetson | engine (TensorRT) | Am schnellsten auf NVIDIA; exportiere direkt auf dem Gerät. Siehe Mit TensorRT optimieren |
| Intel-CPUs und integrierte GPUs | openvino | Echte CPU-Beschleunigung durch Intel-Kernels. Siehe OpenVINO auf der CPU |
| Apps für iPhone, iPad und Mac | coreml | Nativ; nutzt die Apple Neural Engine |
| Android und andere mobile oder eingebettete Geräte | litert | INT8 wird für mobile Geräte empfohlen |
| Snapdragon-NPUs | qnn | Beschleunigung durch Hexagon HTP; standardmäßig INT8-Gewichte mit 16-Bit-Aktivierungen; wähle mit name die HTP-Architektur aus |
| Webbrowser | onnx mit ONNX Runtime Web | Kleinere Modelle sind realistisch: n und s |
from ultralytics import YOLO
model = YOLO("runs/detect/pills_v1/weights/best.pt")
model.export(format="onnx") # plattformübergreifend: ONNX Runtime
model.export(format="openvino") # Intel-CPU / integrierte GPU
model.export(format="engine", quantize=16) # NVIDIA TensorRT, FP16 (auf der Ziel-GPU ausführen)
model.export(format="coreml") # Apple iOS / macOS
model.export(format="litert", quantize=8, data="my_dataset/data.yaml") # Android / Edge, INT8
model.export(format="qnn", name="73", data="my_dataset/data.yaml") # Qualcomm Snapdragon NPU (HTP v73); kalibriere mit deinen eigenen DatenJeder Export wird neben den Gewichten gespeichert: best.onnx, best_openvino_model/, best.engine usw. Beginne mit ONNX, auch wenn du später ein anderes Format verwendest: Es lässt sich am schnellsten überprüfen und dient als Eingabe für mehrere andere Toolchains. Der Leitfaden zu den Bereitstellungsoptionen vergleicht alle Formate, und Ein Bereitstellungsziel auswählen führt dich durch die Entscheidung.
Modellquantisierung tauscht Genauigkeit gegen geringere Größe und höhere Geschwindigkeit. FP16 (quantize=16) halbiert die Dateigröße bei nahezu unveränderter Genauigkeit. INT8 (quantize=8) ist noch kleiner und schneller, benötigt aber Kalibrierungsbilder – repräsentative Frames, die beim Export verarbeitet werden, um Wertebereiche festzulegen; Ultralytics empfiehlt mindestens 300. Überprüfe ein INT8-Modell immer, bevor du es einsetzt: Der Genauigkeitsverlust kann je nach Modell und Kalibrierungsdatensatz vernachlässigbar oder erheblich sein.
Diese Fehler vermeiden#
Symptom: Das Modell .pt erkennt auf Frame_144.jpg 35 Pillen, die ONNX-Datei dagegen 25, und der Export scheint fehlerhaft. Ursache: Bei der PyTorch-Inferenz wird jedes Bild mit so wenig Auffüllung wie möglich auf ein Rechteck ausgerichtet, dessen Seitenlängen Vielfache des Strides sind (für diese 16:9-Bilder 192×320). Ein statisches ONNX-Modell verwendet dagegen immer ein Quadrat von 320×320. Andere Eingabe, andere Detektionen mit geringer Konfidenz. Lösung: Übergib beim Vergleich rect=False an das Modell .pt, wie in parity.py.
Symptom: Du übergibst imgsz=640 an best.onnx, doch im Protokoll steht weiterhin 320x320. Ursache: Ein statischer Export hat eine einzige Eingabegröße, die beim Export festgelegt wird. Lösung: Exportiere mit der Größe, die du verwenden willst (imgsz=640), oder exportiere mit dynamic=True.
Ein .engine, das auf einer A100 erstellt wurde, läuft nicht auf einem Jetson Orin und funktioniert möglicherweise nach einem TensorRT-Upgrade nicht mehr. Exportiere auf dem Zielgerät und verwende dabei die TensorRT-Version, mit der es laufen soll. ONNX ist portabel; Engines sind es nicht.
Wenn du bei einem INT8-Export data weglässt, gibt Ultralytics eine Warnung aus und kalibriert dann anhand des standardmäßigen COCO8-Beispielsatzes – acht Bildern, die deinen Pillen überhaupt nicht ähneln. Übergib deinen eigenen Datensatz: model.export(format="litert", quantize=8, data="my_dataset/data.yaml").
Du hast es ausgeliefert#
Du hast jetzt ein trainiertes best.pt, Validierungsnachweise neben einer Baseline, eine exportierte Datei für deine Laufzeitumgebung und den Beleg, dass der Export mit dem Original übereinstimmt. Das ist der vollständige Ablauf – Daten, Training, Validierung, Export, Bereitstellung – und Produktionsteams führen ihn regelmäßig aus. Ultralytics YOLO in der Produktion knüpft an deinen geprüften Export an und behandelt optimierte Laufzeitumgebungen, Tracking-Pipelines, die Bereitstellung mehrerer Streams und Monitoring.
Lösung anzeigen
from ultralytics import YOLO
# Train
model = YOLO("yolo26n.pt")
model.train(data="my_dataset/data.yaml", epochs=10, imgsz=320, name="pills_e2e")
# Validate
metrics = model.val()
print(f"mAP50-95 = {metrics.box.map:.3f}") # 0.659
# Export
model.export(format="onnx")parity.py: pt 25 pills, onnx 25 pills, max box difference 0.0002 px
without rect: pt 35 pills (192x320 input) vs onnx 25 (320x320): input mismatch, not an export bug
val_export.py: .pt 0.6570, .onnx 0.6570
Target: Intel laptop CPU -> openvino, for faster CPU inference than ONNX Runtime