Einführung in die End-to-End-Erkennung in Ultralytics
Einführung
Wenn Sie von einem früheren Modell wie YOLOv8 oder YOLO11auf YOLO26 aktualisieren, ist eine der größten Änderungen, die Ihnen auffallen wird, die Entfernung von Non-Maximum Suppression (NMS). Herkömmliche YOLO erzeugen Tausende von sich überschneidenden Vorhersagen, die einen separaten NMS erfordern, um die endgültigen Erkennungen herauszufiltern. Dies erhöht die Latenz, verkompliziert Exportdiagramme und kann auf verschiedenen Hardwareplattformen zu inkonsistentem Verhalten führen.
YOLO26 verfolgt einen anderen Ansatz. Es gibt die endgültigen Erkennungsergebnisse direkt aus dem Modell aus – eine externe Filterung ist nicht erforderlich. Dies wird als „End-to-End-Objekterkennung“ bezeichnet und ist in allen YOLO26-Modellen standardmäßig aktiviert. Das Ergebnis sind eine einfachere Bereitstellungspipeline, geringere Latenzzeiten und eine bis zu 43 % schnellere Inferenz auf CPUs.
Dieser Leitfaden erklärt Ihnen, was sich geändert hat, ob Sie Ihren Code aktualisieren müssen, welche Exportformate End-to-End-Inferenz unterstützen und wie Sie reibungslos von älteren YOLO migrieren können.
Einen tieferen Einblick in die Beweggründe für diesen architektonischen Wandel bietet der Ultralytics darüber, warum YOLO26 auf NMS verzichtet.
Kurzzusammenfassung
- Nutzen Sie die Ultralytics oder CLI? Es sind keine Änderungen erforderlich – ersetzen Sie einfach Ihren Modellnamen durch
yolo26n.pt. - Verwenden Sie benutzerdefinierten Inferenzcode (ONNX , TensorRT usw.)? Aktualisieren Sie Ihre Nachbearbeitung – die Erkennungsergebnisse sind jetzt
(N, 300, 6)inxyxyFormat, kein NMS . Bei anderen Aufgaben werden zusätzliche Daten angehängt (Maskenkoeffizienten, Kontrollpunkte oder Winkel). - Exportieren? Die meisten Formate unterstützen die End-to-End-Ausgabe nativ. Einige wenige Formate (NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX und Edge TPU) greifen jedoch aufgrund nicht unterstützter Operatorbeschränkungen automatisch auf die herkömmliche Ausgabe zurück (z. B.
torch.topk), oder Auto-Modus mit angegebener Auslastungsfraktion (
So funktioniert die End-to-End-Erkennung
YOLO26 nutzt während des Trainings eine Dual-Head-Architektur. Beide Köpfe teilen sich denselben Backbone und denselben Neck, erzeugen ihre Ausgaben jedoch auf unterschiedliche Weise:
| Head | Zweck | Erkennungsausgabe | Nachbearbeitung |
|---|---|---|---|
| Eins-zu-eins (Standard) | End-to-End-Inferenz | (N, 300, 6) | Nur Konfidenzschwelle |
| Eins-zu-Viele | Traditionelle YOLO | (N, nc + 4, 8400) | Erfordert NMS |
Die oben gezeigten Formen dienen der Erkennung. Bei anderen Aufgaben wird die Eins-zu-Eins-Ausgabe um zusätzliche Daten pro Erkennung erweitert:
| Aufgabe | End-to-End-Ausgabe | Zusätzliche Daten |
|---|---|---|
| Erkennung | (N, 300, 6) | — |
| Segmentation | (N, 300, 6 + nm) + proto (N, nm, H, W) | nm Maskenkoeffizienten (Standardwert: 32) |
| Pose | (N, 300, 57) | 17 Kontrollpunkte × 3 (x, y, Sichtbarkeit) |
| OBB | (N, 300, 7) | Drehwinkel |
Während des Trainings laufen beide Köpfe gleichzeitig – der „One-to-Many“-Kopf liefert ein reichhaltigeres Lernsignal, während der „One-to-One“-Kopf lernt, klare, sich nicht überschneidende Vorhersagen zu erstellen. Während Inferenz und exportieren, nur die Einzelunterricht ist standardmäßig aktiviert und liefert bis zu 300 Erkennungen pro Bild im Format [x1, y1, x2, y2, confidence, class_id].
Wenn Sie anrufen model.fuse(), es fasst Conv- und BatchNorm-Schichten zusammen, um die Inferenz zu beschleunigen, und entfernt bei End-to-End-Modellen zudem den One-to-Many-Kopf – wodurch die Modellgröße und die FLOPs reduziert werden. Weitere Informationen zur Dual-Head-Architektur finden Sie in der YOLO26-Modellseite.
Muss ich meinen Code ändern?
Verwendung derPython oder CLI
Es sind keine Änderungen erforderlich. Wenn Sie die Python Ultralytics oder CLI, funktioniert alles automatisch – Vorhersage, Validierung und Export verarbeiten End-to-End-Modelle sofort nach der Installation.
Bei der Ultralytics sind keine Codeänderungen 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")
yolo predict model=yolo26n.pt source=image.jpg
Verwendung von benutzerdefiniertem Inferenzcode
Ja, das Ausgabeformat ist anders. Wenn Sie eine benutzerdefinierte Nachbearbeitungslogik für YOLOv8 oder YOLO11 (beispielsweise bei der Inferenz mit ONNX oder TensorRT), müssen Sie diese aktualisieren, um die neue Ausgabeform zu verarbeiten:
| YOLOv8 YOLO11 | YOLO26 (End-to-End) | |
|---|---|---|
| Erkennungsausgabe | (N, nc + 4, 8400) | (N, 300, 6) |
| Kastenformat | xywh (Mittelpunkt x, Mittelpunkt y, Breite, Höhe) | xyxy (x oben links, y oben links, x unten rechts, y unten rechts) |
| Layout | Box-Koordinaten + Klassenpunktzahlen pro Anker | [x1, y1, x2, y2, conf, class_id] |
| NMS | Ja | Nein |
| Nachbearbeitung | NMS Konfidenzfilter | Nur Konfidenzfilter |
Bei Segmentierungs-, Pose- und OBB-Aufgaben fügt YOLO26 jeder Erkennung aufgabenspezifische Daten hinzu – siehe die Tabelle mit den Ausgabeformaten oben.
Wo N ist das Batch-Größe und nc ist die Anzahl der Klassen (z. B. 80 für COCO), oder Auto-Modus mit angegebener Auslastungsfraktion (
Mit End-to-End-Modellen wird die Nachbearbeitung wesentlich einfacher – beispielsweise bei der Verwendung von ONNX :
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-Kopf
Wenn Sie das herkömmliche YOLO benötigen (beispielsweise, um vorhandenen NMS Nachbearbeitungscode wiederzuverwenden), können Sie jederzeit zum „One-to-Many“-Kopf wechseln, indem Sie end2end=False:
Verwendung des „One-to-Many“-Kopfes für die herkömmliche NMS 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)
yolo predict model=yolo26n.pt source=image.jpg end2end=False
yolo val model=yolo26n.pt data=coco.yaml end2end=False
yolo export model=yolo26n.pt format=onnx end2end=False
Kompatibilität der Exportformate
Die meisten Exportformate unterstützen von Haus aus End-to-End-Inferenz, darunter ONNX, TensorRT, CoreML, OpenVINO, TFLite, TF.js und MNN.
Die folgenden Formate unterstützen keine End-to-End-Verbindung und greifen automatisch auf den One-to-Many-Kopf zurück: NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX und Edge TPU.
Was passiert, wenn End-to-End nicht unterstützt wird?
Wenn Sie in eines dieser Formate exportieren, wechselt Ultralytics zum „One-to-Many“-Kopf und protokolliert eine Warnung – ein manueller Eingriff ist nicht erforderlich. Das bedeutet, dass Sie für diese Formate NMS Ihrer Inferenz-Pipeline benötigen, genau wie bei YOLOv8 oder YOLO11.
TensorRT INT8
TensorRT unterstützt End-to-End, aber es ist automatisch deaktiviert beim Exportieren mit int8=True unter TensorRT .3.0.
Abwägung zwischen Genauigkeit und Geschwindigkeit
Die durchgängige Erkennung bietet erhebliche Vorteile bei der Implementierung bei nur minimalen Auswirkungen auf die Genauigkeit:
| Metrik | End-to-End (Standard) | Eins-zu-Viele + NMSend2end=False) |
|---|---|---|
| Rechengeschwindigkeit CPU | Bis zu 43 % schneller | Ausgangswert |
| mAP | ~0,5 mAP | Entspricht YOLO11 oder übertrifft es |
| Nachbearbeitung | Nur Konfidenzfilter | Komplette NMS |
| Komplexität der Bereitstellung | Minimal | Erfordert NMS |
Für die meisten praktischen Anwendungen beträgt der Wert etwa 0,5 mAP Der Unterschied ist vernachlässigbar, insbesondere wenn man die Vorteile hinsichtlich Geschwindigkeit und Einfachheit berücksichtigt. Wenn höchste Genauigkeit für Sie oberste Priorität hat, können Sie jederzeit auf den „One-to-Many“-Kopf zurückgreifen, indem Sie end2end=False.
Ausführliche Benchmark-Ergebnisse für alle Modellgrößen (n, s, m, l, x) finden Sie in den YOLO26-Leistungskennzahlen.
Migration von YOLOv8 YOLO11
Wenn Sie ein bestehendes Projekt auf YOLO26 aktualisieren, finden Sie hier eine kurze Checkliste, um einen reibungslosen Übergang zu gewährleisten:
- CLI Ultralytics bzw. CLI : Es sind keine Änderungen erforderlich – aktualisieren Sie einfach den Modellnamen auf
yolo26n.pt(oderyolo26n-seg.pt,yolo26n-pose.pt,yolo26n-obb.pt) - Benutzerdefinierter Code für die Nachbearbeitung: Aktualisierung zur Unterstützung der neuen Ausgabeformate —
(N, 300, 6)zur Erkennung sowie aufgabenspezifische Daten für Segmentierung, Poseund OBB. Beachten Sie auch die Änderung des Box-Formats vonxywhzuxyxy - Export-Pipelines: Informationen zum Zielformat finden Sie im obigen Abschnitt zur Formatkompatibilität
- TensorRT INT8: Stellen Sie sicher, dass Ihre TensorRT höher als 10.3.0 ist, um eine vollständige Unterstützung zu gewährleisten
- FP16-Exporte: Wenn Sie alle Ausgaben im FP16-Format benötigen, exportieren Sie mit
end2end=False— siehe Warum bleibt output0 im FP32-Format? - iOS CoreML: End-to-End wird vollständig unterstützt. Wenn Sie Unterstützung für die Xcode-Vorschau benötigen, verwenden Sie
end2end=Falsemitnms=True - Edge-Geräte (NCNN, RKNN): Diese Formate wechseln automatisch auf „One-to-Many“-Modus um; beziehen Sie daher NMS Ihre geräteinterne Pipeline ein
FAQ
Kann ich „end2end=True“ und „nms=True“ zusammen verwenden?
Nein. Diese Optionen schließen sich gegenseitig aus. Wenn Sie nms=True im Rahmen eines End-to-End-Modells während exportieren, wird es automatisch dazu gezwungen, nms=False mit einer Warnung. Der End-to-End-Kopf übernimmt die Filterung von Duplikaten bereits intern, sodass NMS externes NMS nicht NMS .
Allerdings end2end=False in Verbindung mit nms=True ist eine gültige Konfiguration – sie integriert herkömmliche NMS den Exportgraphen. Dies kann nützlich sein für CoreML Exporte, da man damit die Vorschau-Funktion in Xcode direkt mit dem Erkennungsmodell nutzen kann.
Was steuert der Parameter „max_det“ in End-to-End-Modellen?
Die max_det Der Parameter (Standardwert: 300) legt die maximale Anzahl an Erkennungen fest, die der One-to-One-Kopf pro Bild ausgeben kann. Sie können diesen Wert 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
Beachten Sie, dass die Standard-Checkpoints von YOLO26 trainiert wurden mit max_det=300. Sie können diesen Wert zwar erhöhen, doch wurde das One-to-One-Modell während des Trainings darauf optimiert, bis zu 300 einwandfreie Erkennungen zu liefern, sodass Erkennungen, die über diese Grenze hinausgehen, möglicherweise von geringerer Qualität sind. Wenn Sie mehr als 300 Erkennungen pro Bild benötigen, sollten Sie ein erneutes Training mit einem höheren max_det Wert.
Mein exportiertes ONNX gibt (1, 300, 6) aus – ist das richtig?
Ja, das ist das erwartete End-to-End-Ausgabeformat für die Erkennung: Batch-Größe von 1 bis zu 300 Erfassungen, jeweils mit 6 Werten [x1, y1, x2, y2, confidence, class_id]. Filtern Sie einfach nach Konfidenzschwelle, und schon sind Sie fertig – NMS ohne NMS .
Bei anderen Aufgaben unterscheidet sich die Form der Ausgabe:
| Aufgabe | Ausgangsform | Beschreibung |
|---|---|---|
| Erkennung | (1, 300, 6) | [x1, y1, x2, y2, conf, class_id] |
| Segmentation | (1, 300, 38) + (1, 32, 160, 160) | 6 Box-Werte + 32 Maskenkoeffizienten sowie ein Prototyp-Masken tensor |
| Pose | (1, 300, 57) | 6 Box-Werte + 17 Schlüsselpunkte × 3 (x, y, Sichtbarkeit) |
| OBB | (1, 300, 7) | 6 Kastenwerte + 1 Drehwinkel |
Wie kann ich überprüfen, ob mein exportiertes Modell durchgängig ist?
Sie können dies entweder über diePython überprüfen oder indem Sie die Metadaten des exportierten ONNX direkt einsehen:
Prüfen, ob ein Modell durchgängig 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
import onnxruntime as ort
session = ort.InferenceSession("yolo26n.onnx")
metadata = session.get_modelmeta().custom_metadata_map
print(metadata.get("end2end")) # 'True' if end-to-end is enabled
Alternativ können Sie die Ausgabestruktur überprüfen – die Ausgabe von End-to-End-Erkennungsmodellen (1, 300, 6), während herkömmliche Modelle (1, nc + 4, 8400). Weitere Aufgabenformen finden Sie unter Häufig gestellte Fragen zu Ausgangsformen.
Wird End-to-End für Segmentierungs-, Posen- und OBB-Aufgaben unterstützt?
Ja. Alle YOLO26-Aufgabenvarianten — Erkennung, Segmentierung, Pose-Schätzungund orientierte Objekterkennung (OBB) — unterstützen standardmäßig End-to-End-Inferenz. Die end2end=False Die Fallback-Funktion ist ebenfalls für alle Aufgaben verfügbar.
Jede Aufgabe erweitert die Basis-Erkennungsausgabe um aufgabenspezifische Daten:
| Aufgabe | Modell | End-to-End-Ausgabe |
|---|---|---|
| Erkennung | yolo26n.pt | (N, 300, 6) |
| Segmentation | yolo26n-seg.pt | (N, 300, 38) + proto (N, 32, 160, 160) |
| Pose | yolo26n-pose.pt | (N, 300, 57) |
| OBB | yolo26n-obb.pt | (N, 300, 7) |