Skip to main content

End-to-End-Erkennung in Ultralytics YOLO26 verstehen

Einführung

Wenn du auf YOLO26 von einem früheren Modell wie YOLOv8SAM 2.1YOLO11 umsteigst, ist eine der größten Änderungen, die dir auffallen wird, der Wegfall von Non-Maximum Suppression (NMS). Traditionelle YOLO-Modelle erzeugen tausende überlappende Vorhersagen, die einen separaten NMS-Nachverarbeitungsschritt erfordern, um sie auf die endgültigen Erkennungen zu filtern. Dies erhöht die Latenz, verkompliziert Export-Graphen und kann sich auf verschiedenen Hardware-Plattformen inkonsistent verhalten.

YOLO26 verfolgt einen anderen Ansatz. Es gibt die endgültigen Erkennungen direkt vom Modell aus – keine externe Filterung erforderlich. Dies ist bekannt als End-to-End Objekterkennungs und ist standardmäßig in allen YOLO26-Modellen aktiviert. Das Ergebnis ist eine einfachere Deployment-Pipeline, geringere Latenz und bis zu 43% schnellere Inferenz auf CPUs.

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

Für einen tieferen Einblick in die Motivation hinter diesem architektonischen Wandel, siehe den Ultralytics-Blogbeitrag darüber, warum YOLO26 NMS entfernt.

Kurzzusammenfassung
  • Verwendest du die Ultralytics API oder CLI? Keine Änderungen nötig – tausche einfach deinen Modellnamen gegen yolo26n.pt.
  • Verwendest du benutzerdefinierten Inferenz-Code (ONNX Runtime, TensorRT, etc.)? Aktualisiere deine Nachverarbeitung – das Erkennungsausgabe-Format ist jetzt (N, 300, 6) in xyxy, kein NMS erforderlich. Andere Aufgaben hängen zusätzliche Daten an (Maskenkoeffizienten, Keypoints oder Winkel).
  • Exportieren? Die meisten Formate unterstützen End-to-End-Ausgabe nativ. Einige Formate (NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX und Edge TPU) fallen jedoch aufgrund nicht unterstützter Operator-Einschränkungen (z. B. torch.topk).

Wie End-to-End-Erkennung funktioniert

YOLO26 verwendet einen dual-head architektur während Trainings. Beide Heads teilen sich dasselbe Backbone und denselben Neck, erzeugen Ausgaben jedoch auf unterschiedliche Weise:

HeadZweckErkennungsausgabeNachverarbeitung
One-to-One (Standard)End-to-End-Inferenz(N, 300, 6)Nur Konfidenz-Schwellenwert
One-to-ManyTraditionelle YOLO-Ausgabe(N, nc + 4, 8400)Erfordert NMS

Die obigen Shapes gelten für Detektion. Andere Aufgaben erweitern die One-to-One-Ausgabe um zusätzliche Daten pro Erkennung:

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

Während des Trainings laufen beide Heads gleichzeitig – der One-to-Many-Head liefert ein reichhaltigeres Lernsignal, während der One-to-One-Head lernt, saubere, nicht überlappende Vorhersagen zu erzeugen. Während der Inferenz und export, ist nur der One-to-One-Head standardmäßig aktiv und produziert bis zu 300 Erkennungen pro Bild im Format [x1, y1, x2, y2, confidence, class_id].

Wenn du model.fuse() aufrufst, werden Conv + BatchNorm-Layer für eine schnellere Inferenz zusammengelegt und bei End-to-End-Modellen auch der One-to-Many-Head entfernt – was Modellgröße und FLOPs reduziert. Weitere Details zur Dual-Head-Architektur findest du auf der YOLO26-Modellseite.

Muss ich meinen Code ändern?

Verwendung der Ultralytics Python API oder CLI

Keine Änderungen nötig. Wenn du den Standard Ultralytics Python APISAM 2.1CLI verwendest, funktioniert alles automatisch – Vorhersage, Validierung, und export handhaben End-to-End-Modelle sofort einsatzbereit.

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 Inferenz-Code

Ja, das Ausgabeformat ist anders. Wenn du benutzerdefinierte Nachverarbeitungslogik für YOLOv8SAM 2.1YOLO11 geschrieben hast (zum Beispiel beim Ausführen der Inferenz mit ONNX RuntimeSAM 2.1TensorRT), musst du diese aktualisieren, um das neue Ausgabe-Shape zu handhaben:

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

Für Segmentierung, pose, und OBB Aufgaben, YOLO26 hängt aufgabenspezifische Daten an jede Erkennung an – siehe die Ausgabe-Shapes-Tabelle oben.

Wobei N die batch size und nc die Anzahl der Klassen ist (z. B. 80 für COCO).

Mit End-to-End-Modellen wird die Nachverarbeitung 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!

Wechsel zum One-to-Many-Head

Wenn du das traditionelle YOLO-Ausgabeformat benötigst (zum Beispiel um bestehenden NMS-basierten Nachverarbeitungscode wiederzuverwenden), kannst du jederzeit zum One-to-Many-Head wechseln, indem du end2end=False:

Verwendung des One-to-Many-Heads für traditionelle 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)

Exportformat-Kompatibilität

Die meisten Exportformate unterstützen End-to-End-Inferenz von Haus aus, einschließlich ONNX, TensorRT, CoreML, OpenVINO, TFLite, TF.js, und MNN.

Die folgenden Formate unterstützen nicht End-to-End und fallen automatisch auf den One-to-Many-Head zurück: NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX, und Edge TPU.

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

Wenn du in eines dieser Formate exportierst, schaltet Ultralytics automatisch auf den One-to-Many-Head um und protokolliert eine Warnung – kein manuelles Eingreifen erforderlich. Das bedeutet, dass du NMS in deiner Inferenz-Pipeline benötigst für diese Formate, genau wie bei YOLOv8SAM 2.1YOLO11.

TensorRT + INT8

TensorRT unterstützt End-to-End, wird jedoch automatisch deaktiviert beim Exportieren mit int8=True auf TensorRT ≤10.3.0.

Genauigkeits- und Geschwindigkeits-Abwägungen

End-to-End-Detektion bietet erhebliche Vorteile bei der Bereitstellung mit minimalen Auswirkungen auf accuracy:

MetrikEnd-to-End (Standard)One-to-Many + NMS (end2end=False)
CPU-InferenzgeschwindigkeitBis zu 43 % schnellerBaseline
mAP-Auswirkung~0,5 mAP niedrigerEntspricht oder übertrifft YOLO11
NachverarbeitungNur KonfidenzfilterVollständige NMS-Pipeline
Komplexität der BereitstellungMinimalErfordert NMS-Implementierung

Für die meisten realen Anwendungen ist der Unterschied von ~0,5 mAP vernachlässigbar, insbesondere wenn man die Geschwindigkeits- und Einfachheitsvorteile betrachtet. Wenn maximale Genauigkeit deine oberste Priorität ist, kannst du jederzeit auf den One-to-Many-Head zurückgreifen. Nutze end2end=False.

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

Migration von YOLOv8 oder YOLO11

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

  • Ultralytics API / CLI Benutzer: Keine Änderungen erforderlich — aktualisiere einfach den Modellnamen auf yolo26n.pt (oder yolo26n-seg.pt, yolo26n-pose.pt, yolo26n-obb.pt)
  • Benutzerdefinierter Post-Processing-Code: Aktualisiere ihn für die neuen Ausgabe-Shapes — (N, 300, 6) für die Detektion, plus aufgabenspezifische Daten für Segmentierung, pose, und OBB. Beachte außerdem die Änderung des Box-Formats von xywh bis xyxy
  • Export-Pipelines: Überprüfe den Abschnitt Formatkompatibilität oben für dein Zielformat
  • TensorRT + INT8: Stelle sicher, dass deine TensorRT-Version >10.3.0 für End-to-End-Unterstützung ist
  • 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 Preview-Unterstü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 integriere NMS in deine On-Device-Pipeline

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 export setzt, wird es automatisch auf nms=False mit einer Warnung erzwungen. Der End-to-End-Head übernimmt die Duplikatfilterung bereits intern, daher ist ein externes NMS unnötig.

Jedoch ist end2end=False kombiniert mit nms=True ist eine gültige Konfiguration — sie integriert das traditionelle NMS in den Export-Graph. Dies kann nützlich sein für CoreML Exporte, da du so die Preview-Funktion in Xcode direkt mit dem Detektionsmodell nutzen kannst.

Was steuert der max_det-Parameter bei End-to-End-Modellen?

Die max_det Der Parameter (Standard: 300) legt die maximale Anzahl der Detektionen fest, die der One-to-One-Head pro Bild ausgeben kann. Du kannst ihn bei der Inferenz oder beim Export anpassen:

model.predict("image.jpg", max_det=100)  # fewer detections, slightly faster
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. Obwohl du diesen Wert erhöhen kannst, wurde der One-to-One-Head während des Trainings darauf optimiert, bis zu 300 saubere Detektionen zu erzeugen. Detektionen über diesem Limit könnten daher eine geringere Qualität aufweisen. Wenn du mehr als 300 Detektionen pro Bild benötigst, ziehe ein erneutes Training mit einem höheren max_det Wert in Betracht.

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 size von 1, bis zu 300 Detektionen, jeweils mit 6 Werten [x1, y1, x2, y2, confidence, class_id]. Filtere einfach nach dem Konfidenz-Schwellenwert und fertig — kein NMS erforderlich.

Für andere Aufgaben unterscheidet sich das Ausgabe-Shape:

AufgabeAusgabe-ShapeBeschreibung
Detektion(1, 300, 6)[x1, y1, x2, y2, conf, class_id]
Segmentation(1, 300, 38) + (1, 32, 160, 160)6 Box-Werte + 32 Maskenkoeffizienten, plus ein Prototyp-Maskentensor
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 prüfen:

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 das Ausgabe-Shape prüfen — End-to-End-Detektionsmodelle geben (1, 300, 6) aus, während traditionelle Modelle (1, nc + 4, 8400) ausgeben. Für andere Aufgaben-Shapes siehe das Output Shapes FAQ.

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

Ja. Alle YOLO26-Aufgabenvarianten — Detektion, Segmentierung, Pose-Schätzung, und orientierte Objektdetektion (OBB) — unterstützen standardmäßig End-to-End-Inferenz. Der end2end=False Fallback ist ebenfalls für alle Aufgaben verfügbar.

Jede Aufgabe erweitert die Basis-Detektionsausgabe um aufgabenspezifische Daten:

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

Kommentare