YOLO Vision 2026:

End-to-End-Erkennung in Ultralytics YOLO26 verstehen#

Wenn du von einem früheren Modell wie YOLOv8 oder YOLO11 auf YOLO26 aktualisierst, wirst du als eine der größten Änderungen bemerken, dass die Non-Maximum Suppression (NMS) wegfällt. Herkömmliche YOLO-Modelle erzeugen Tausende von überlappenden Vorhersagen, die einen separaten NMS-Nachbearbeitungsschritt erfordern, um sie auf die endgültigen Detektionen zu reduzieren. Dies erhöht die Latenz, verkompliziert Exportgraphen und kann sich auf verschiedenen Hardwareplattformen unterschiedlich verhalten.

YOLO26 verfolgt einen anderen Ansatz. Es gibt die endgültigen Detektionen direkt aus dem Modell aus – es ist keine externe Filterung erforderlich. Dies wird als End-to-End-Objekterkennung bezeichnet und ist standardmäßig in allen YOLO26-Modellen aktiviert. Das Ergebnis ist eine einfachere Bereitstellungspipeline, eine geringere Latenz und eine bis zu 43 % schnellere Inferenz auf CPUs.

Dieser Leitfaden führt dich durch die Änderungen, erklärt, ob du deinen Code aktualisieren musst, welche Exportformate die End-to-End-Inferenz unterstützen und wie du problemlos von älteren YOLO-Modellen migrierst.

Einen tieferen Einblick in die Motivation hinter diesem architektonischen Wandel findest du im Blogbeitrag von Ultralytics darüber, warum YOLO26 NMS entfernt.

Kurze Zusammenfassung
  • Verwendest du die Ultralytics API oder CLI? Es sind keine Änderungen erforderlich – ändere einfach deinen Modellnamen in yolo26n.pt.
  • Verwendest du benutzerdefinierten Inferenzcode (ONNX Runtime, TensorRT usw.)? Aktualisiere deine Nachbearbeitung – die Detektionsausgabe ist jetzt (N, 300, 6) im Format xyxy, ganz ohne NMS. Andere Aufgaben hängen zusätzliche Daten an (Maskenkoeffizienten, Schlüsselpunkte oder Winkel).
  • Exportierst du? Die meisten Formate unterstützen die End-to-End-Ausgabe nativ. Einige wenige Formate (NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX, Edge TPU und QNN) greifen aufgrund von Einschränkungen nicht unterstützter Operatoren (z. B. torch.topk) jedoch automatisch auf die traditionelle Ausgabe zurück. Hailo-HEF-Workflows werden aus ONNX mit Hailo-spezifischen Skripten kompiliert. Überprüfe daher den Detektionskopf und die NMS-Konfiguration für dein Modell.

Wie End-to-End-Erkennung funktioniert#

YOLO26 verwendet während des Trainings eine Architektur mit zwei Köpfen. Beide Köpfe teilen sich dasselbe Backbone und denselben Neck, erzeugen die Ausgaben jedoch auf unterschiedliche Weise:

KopfZweckErkennungsausgabeNachbearbeitung
One-to-One (Standard)End-to-End-Inferenz(N, 300, 6)Nur Konfidenz-Schwellenwert
One-to-ManyHerkömmliche YOLO-Ausgabe(N, nc + 4, 8400)Erfordert NMS

Die obigen Formen gelten für die Detektion. Andere Aufgaben erweitern die 1:1-Ausgabe um zusätzliche Daten pro Detektion:

AufgabeEnd-to-End-AusgabeZusätzliche Daten
Detektion(N, 300, 6)
Instanzsegmentierung(N, 300, 6 + nm) + Proto (N, nm, H, W)nm Maskenkoeffizienten (Standard 32)
Pose(N, 300, 57)17 Keypoints × 3 (x, y, Sichtbarkeit)
OBB(N, 300, 7)Rotationswinkel

Während des Trainings laufen beide Köpfe gleichzeitig – der 1:viele-Kopf liefert ein reichhaltigeres Lernsignal, während der 1:1-Kopf lernt, saubere, sich nicht überschneidende Vorhersagen zu erzeugen. Während der Inferenz und des Exports ist standardmäßig nur der 1:1-Kopf aktiv, der bis zu 300 Detektionen pro Bild im Format [x1, y1, x2, y2, confidence, class_id] liefert.

Wenn du model.fuse() aufrufst, werden Conv- und BatchNorm-Schichten für eine schnellere Inferenz zusammengelegt, und bei End-to-End-Modellen wird außerdem der 1:viele-Kopf entfernt, wodurch Modellgröße und FLOPs reduziert werden. Weitere Einzelheiten zur Architektur mit zwei Köpfen findest du auf der YOLO26-Modellseite.

Muss ich meinen Code ändern?#

Verwendung der Ultralytics Python API oder CLI#

Keine Änderungen erforderlich. Wenn du die Standard-Ultralytics Python API oder CLI verwendest, funktioniert alles automatisch – Vorhersage, Validierung und Export verarbeiten End-to-End-Modelle von Haus aus.

Keine Codeänderungen mit der Ultralytics API erforderlich
from ultralytics import YOLO

# Load a YOLO26 model
model = YOLO("yolo26n.pt")

# Predict — no NMS step, no code changes
results = model.predict("image.jpg")

Verwendung von benutzerdefiniertem Inferenzcode#

Ja, das Ausgabeformat ist anders. Wenn du benutzerdefinierte Nachbearbeitungslogik für YOLOv8 oder YOLO11 geschrieben hast (z. B. beim Ausführen der Inferenz mit ONNX Runtime oder TensorRT), musst du diese aktualisieren, um die neue Ausgabeform zu verarbeiten:

YOLOv8 / YOLO11YOLO26 (End-to-End)
Erkennungsausgabe(N, nc + 4, 8400)(N, 300, 6)
Box-Formatxywh (Zentrum x, Zentrum y, Breite, Höhe)xyxy (oben links x, oben links y, unten rechts x, unten rechts y)
LayoutBox-Koordinaten + Klassen-Scores pro Anker[x1, y1, x2, y2, conf, class_id]
NMS erforderlichJaNein
NachbearbeitungNMS + Konfidenz-FilterNur Konfidenz-Filter

Bei Segmentierungs-, Posen- und OBB-Aufgaben hängt YOLO26 aufgabenspezifische Daten an jede Detektion an – siehe die Tabelle der Ausgabeformen.

Wobei N die Batch-Größe und nc die Anzahl der Klassen ist (z. B. 80 für COCO).

Mit End-to-End-Modellen wird die Nachbearbeitung viel einfacher – zum Beispiel bei der Verwendung von ONNX Runtime:

import onnxruntime as ort

# Load and run the exported end-to-end model
session = ort.InferenceSession("yolo26n.onnx")
output = session.run(None, {session.get_inputs()[0].name: input_tensor})

# End-to-end output: (batch, 300, 6) → [x1, y1, x2, y2, confidence, class_id]
detections = output[0][0]  # first image in batch
detections = detections[detections[:, 4] > conf_threshold]  # confidence filter — that's it!

Umschalten auf den One-to-Many-Kopf#

Wenn du das traditionelle YOLO-Ausgabeformat benötigst (z. B. um bestehenden NMS-basierten Nachbearbeitungscode wiederzuverwenden), kannst du zum 1:viele-Kopf wechseln, sofern dieser verfügbar ist, indem du end2end=False einstellst:

Verwendung des One-to-Many-Kopfes für herkömmliche NMS-basierte Ausgabe
from ultralytics import YOLO

model = YOLO("yolo26n.pt")

# Prediction with NMS (traditional behavior)
results = model.predict("image.jpg", end2end=False)

# Validation with NMS
metrics = model.val(data="coco.yaml", end2end=False)

# Export without end-to-end
model.export(format="onnx", end2end=False)

Kompatibilität der Exportformate#

Die meisten Exportformate unterstützen die End-to-End-Inferenz von Haus aus, darunter ONNX, TensorRT, CoreML, OpenVINO, LiteRT und MNN.

Die folgenden Formate unterstützen End-to-End nicht und greifen automatisch auf den 1:viele-Kopf zurück: NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX, Edge TPU und Qualcomm QNN.

Was passiert, wenn End-to-End nicht unterstützt wird

Wenn du in eines dieser Formate exportierst, wechselt Ultralytics automatisch zum 1:viele-Kopf und protokolliert eine Warnung – kein manueller Eingriff erforderlich. Das bedeutet, dass du für diese Formate NMS in deiner Inferenzpipeline benötigst, genau wie bei YOLOv8 oder YOLO11.

Für Hailo HEF findet der Kompilierschritt außerhalb von model.export(format=...) nach einem ONNX-Export statt. Verwende die Hailo-DFC-Protokolle, das .alls-Modellskript und das NMS-JSON, die genau zu deinem Detektionsmodell passen; wenn ein End-to-End-YOLO26-Graph von deiner Hailo-Toolchain nicht unterstützt wird, exportiere das ONNX-Modell mit end2end=False und kompiliere den traditionellen Detektionskopf.

TensorRT + INT8

TensorRT unterstützt End-to-End, ist jedoch bei einem Export mit quantize=8 auf TensorRT 10.3.0 unter JetPack 6 automatisch deaktiviert.

Kompromisse bei Genauigkeit und Geschwindigkeit#

End-to-End-Detektion bietet erhebliche Vorteile bei der Bereitstellung bei minimalen Auswirkungen auf die Genauigkeit:

MetrikEnd-to-End (Standard)1:viele + NMS (end2end=False)
CPU-InferenzgeschwindigkeitBis zu 43 % schnellerBasislinie
mAP-Auswirkung~0,5 mAP niedrigerEntspricht oder übertrifft YOLO11
NachbearbeitungNur Konfidenz-FilterVollständige NMS-Pipeline
BereitstellungskomplexitätMinimalErfordert NMS-Implementierung

Für die meisten realen Anwendungen ist der Unterschied von ~0,5 mAP vernachlässigbar, insbesondere wenn man die Geschwindigkeits- und Einfachheitsgewinne berücksichtigt. Wenn maximale Genauigkeit deine oberste Priorität ist, kannst du jederzeit mit end2end=False auf den 1:viele-Kopf zurückgreifen.

Siehe die YOLO26-Leistungsmetriken für detaillierte Benchmarks über alle Modellgrößen hinweg (n, s, m, l, x).

Migration von YOLOv8 oder YOLO11#

Wenn du ein bestehendes Projekt auf YOLO26 aktualisierst, findest du hier eine kurze Checkliste für einen reibungslosen Übergang:

  • Benutzer von Ultralytics API / CLI: Keine Änderungen erforderlich – aktualisiere einfach den Modellnamen auf yolo26n.pt (oder yolo26n-seg.pt, yolo26n-pose.pt, yolo26n-obb.pt)
  • Benutzerdefinierter Nachbearbeitungscode: Aktualisiere ihn zur Verarbeitung der neuen Ausgabeformen – (N, 300, 6) für die Detektion sowie aufgabenspezifische Daten für Segmentierung, Pose und OBB. Beachte auch die Änderung des Box-Formats von xywh zu xyxy
  • Exportpipelines: Überprüfe den Abschnitt zur Formatkompatibilität für dein Zielformat
  • TensorRT + INT8: Unter JetPack 6 deaktiviert TensorRT 10.3.0 End-to-End mit quantize=8 automatisch – verwende eine andere TensorRT-Version, um End-to-End beizubehalten
  • FP16-Exporte: Wenn du alle Ausgaben in FP16 benötigst, exportiere mit end2end=False – siehe warum output0 FP32 bleibt
  • iOS / CoreML: End-to-End wird vollständig unterstützt. Wenn du Xcode-Vorschauunterstützung benötigst, verwende end2end=False mit nms=True
  • Edge-Geräte (NCNN, RKNN): Diese Formate fallen automatisch auf One-to-Many zurück, also füge NMS in deine On-Device-Pipeline ein

Fazit#

Die End-to-End-Detektion ist in YOLO26 der Standard und erfordert keine Codeänderungen, wenn du die Ultralytics Python API oder CLI verwendest. Lediglich benutzerdefinierte Nachbearbeitungspipelines müssen aktualisiert werden, um die neue (N, 300, 6)-Ausgabe zu lesen und den NMS-Schritt wegzulassen – mit Ausnahme von Exportformaten, die auf die 1:viele-Ausgabe zurückgreifen (wie NCNN und RKNN), welche weiterhin NMS auf dem Gerät erfordern. Detaillierte Geschwindigkeits- und Genauigkeits-Benchmarks über alle Modellgrößen hinweg findest du auf der YOLO26-Modellseite und den vollständigen Satz an Exportoptionen und -formaten in der Dokumentation zum Export-Modus.

FAQ#

Kann ich end2end=True und nms=True zusammen verwenden?#

Nein. Diese Optionen schließen sich gegenseitig aus. Wenn du nms=True bei einem End-to-End-Modell während des Exports einstellst, wird es mit einer Warnung automatisch auf nms=False gezwungen. Der End-to-End-Kopf verarbeitet die Duplikatfilterung bereits intern, sodass ein externer NMS nicht erforderlich ist.

Die Kombination aus end2end=False und nms=True ist jedoch eine gültige Konfiguration – sie integriert traditionelles NMS in den Exportgraphen. Dies kann für CoreML-Exporte nützlich sein, da du dadurch die Vorschaufunktion in Xcode direkt mit dem Detektionsmodell verwenden kannst.

Was steuert der max_det-Parameter in End-to-End-Modellen?#

Der Parameter max_det (Standard: 300) legt die maximale Anzahl der pro Bild zurückgegebenen Detektionen fest. Du kannst ihn zum Zeitpunkt der Inferenz oder des Exports anpassen:

model.predict("image.jpg", max_det=100)  # fewer detections
model.export(format="onnx", max_det=500)  # more detections for dense scenes

Beachte, dass die standardmäßigen YOLO26-Checkpoints mit max_det=300 trainiert wurden. Zwar kannst du diesen Wert erhöhen, jedoch wurde der 1:1-Kopf während des Trainings darauf optimiert, bis zu 300 saubere Detektionen zu erzeugen, sodass Detektionen über dieses Limit hinaus möglicherweise von geringerer Qualität sind. Wenn du mehr als 300 Detektionen pro Bild benötigst, solltest du ein erneutes Training mit einem höheren max_det-Wert in Betracht ziehen.

Mein exportiertes ONNX-Modell gibt (1, 300, 6) aus – ist das korrekt?#

Ja, das ist das erwartete End-to-End-Ausgabeformat für die Detektion: Batch-Größe von 1, bis zu 300 Detektionen, jeweils mit 6 Werten [x1, y1, x2, y2, confidence, class_id]. Einfach nach Konfidenzschwellenwert filtern und fertig – kein NMS erforderlich.

Für andere Aufgaben unterscheidet sich die Ausgabeform:

AufgabeAusgabeformBeschreibung
Detektion(1, 300, 6)[x1, y1, x2, y2, conf, class_id]
Segmentierung(1, 300, 38) + (1, 32, 160, 160)6 Box-Werte + 32 Masken-Koeffizienten sowie ein Prototyp-Masken-Tensor
Pose(1, 300, 57)6 Box-Werte + 17 Keypoints × 3 (x, y, Sichtbarkeit)
OBB(1, 300, 7)6 Box-Werte + 1 Rotationswinkel

Wie prüfe ich, ob mein exportiertes Modell End-to-End ist?#

Du kannst dies entweder über die Ultralytics Python API oder durch direktes Überprüfen der Metadaten des exportierten ONNX-Modells tun:

Prüfen, ob ein Modell End-to-End ist
from ultralytics import YOLO

model = YOLO("yolo26n.onnx")
model.predict(verbose=False)  # run predict to setup predictor first
print(model.predictor.model.end2end)  # True if end-to-end is enabled

Alternativ kannst du die Ausgabeform überprüfen – End-to-End-Detektionsmodelle geben (1, 300, 6) aus, während traditionelle Modelle (1, nc + 4, 8400) ausgeben. Informationen zu anderen Aufgabenformen findest du in den FAQ zu den Ausgabeformen.

Wird End-to-End für Instanzsegmentierung, Pose- und OBB-Aufgaben unterstützt?#

Ja. YOLO26-Aufgabenvarianten im Detektionsstil – Detektion, Instanzsegmentierung, Posenschätzung und ausgerichtete Objekterkennung (OBB) – unterstützen die End-to-End-Inferenz standardmäßig. Der end2end=False-Fallback ist ebenfalls über diese Aufgaben hinweg verfügbar.

Jede Aufgabe erweitert die Basis-Detektionsausgabe um aufgabenspezifische Daten:

AufgabeModellEnd-to-End-Ausgabe
Detektionyolo26n.pt(N, 300, 6)
Instanzsegmentierungyolo26n-seg.pt(N, 300, 38) + Proto (N, 32, 160, 160)
Poseyolo26n-pose.pt(N, 300, 57)
OBByolo26n-obb.pt(N, 300, 7)

Kommentare