YOLO Vision 2026:

Comprendere il rilevamento end-to-end in Ultralytics YOLO26#

I modelli in stile di rilevamento YOLO26 — rilevamento, segmentazione, posa e OBB — sono senza NMS per impostazione predefinita: emettono i rilevamenti finali direttamente dal modello, senza alcun passaggio di post-elaborazione di Non-Maximum Suppression (NMS). I modelli precedenti come YOLOv8 e YOLO11 producono migliaia di previsioni sovrapposte che un passaggio NMS separato deve filtrare, il che aggiunge latenza, complica i grafici di esportazione e può comportarsi in modo incoerente tra le varie piattaforme hardware.

Questo è noto come rilevamento di oggetti end-to-end, ed è abilitato per impostazione predefinita. Il risultato è una pipeline di distribuzione più semplice e una minore latenza: YOLO26n è fino al 43% più veloce di YOLO11n sull'inferenza ONNX su CPU (Intel Xeon CPU @ 2.00 GHz).

Questa guida ti illustra cosa è cambiato, se devi aggiornare il tuo codice, quali formati di esportazione supportano l'inferenza end-to-end e come migrare agevolmente dai vecchi modelli YOLO.

Per un'analisi approfondita delle motivazioni alla base di questo cambiamento architetturale, consulta il post sul blog di Ultralytics sul motivo per cui YOLO26 rimuove NMS.

Riepilogo veloce
  • Usi l'API o la CLI di Ultralytics? Nessuna modifica necessaria: ti basta sostituire il nome del modello con yolo26n.pt.
  • Usi codice di inferenza personalizzato (ONNX Runtime, TensorRT, ecc.)? Aggiorna la post-elaborazione: l'output di rilevamento è ora (N, 300, 6) nel formato xyxy, senza bisogno di NMS. Altri task aggiungono dati extra (coefficienti delle maschere, keypoint o angolo).
  • Stai esportando? La maggior parte dei formati mantiene l'output end-to-end in modo nativo; pochi tornano all'output tradizionale e la quantizzazione può disabilitarlo: consulta Compatibilità dei formati di esportazione.

Come funziona il rilevamento end-to-end#

YOLO26 utilizza un'architettura a doppia testa durante l'addestramento. Entrambe le teste condividono lo stesso backbone e il collo, ma producono output in modi differenti:

HeadScopoOutput di rilevamentoPost-elaborazione
One-to-One (predefinito)Inferenza end-to-end(N, 300, 6)Solo soglia di confidenza
One-to-ManyOutput YOLO tradizionale(N, nc + 4, 8400)Richiede NMS

Le forme sopra sono per il rilevamento, dove N è la dimensione del batch, nc è il numero di classi (ad es. 80 per COCO) e il conteggio delle ancore di 8400 è il valore in imgsz=640. Altri task estendono l'output uno-a-uno con dati aggiuntivi per ciascun rilevamento:

CompitoOutput end-to-endDati extra
Rilevamento(N, 300, 6)
Segmentazione di istanze(N, 300, 6 + nm) + proto (N, nm, H, W)coefficienti della maschera nm (predefinito 32)
Pose(N, 300, 57)17 keypoint × 3 (x, y, visibilità)
OBB(N, 300, 7)Angolo di rotazione

Durante l'addestramento, entrambe le teste vengono eseguite contemporaneamente: la testa uno-a-molti fornisce un segnale di apprendimento più ricco, mentre la testa uno-a-uno impara a produrre previsioni pulite e senza sovrapposizioni. Durante l'inferenza e l'esportazione, solo la testa uno-a-uno è attiva per impostazione predefinita, producendo fino a 300 rilevazioni per immagine nel formato [x1, y1, x2, y2, confidence, class_id].

Quando richiami model.fuse(), vengono unite le Conv + BatchNorm layer per un'inferenza più rapida e, sui modelli end-to-end, viene rimossa anche la testa uno-a-molti, riducendo le dimensioni del modello e i FLOP. Per maggiori dettagli sull'architettura a doppia testa, consulta la pagina del modello YOLO26.

Devo modificare il mio codice?#

Utilizzo dell'API Python o della CLI di Ultralytics#

Nessuna modifica necessaria. Se utilizzi l'API Python di Ultralytics o la CLI standard, tutto funziona automaticamente: previsione, validazione ed esportazione gestiscono i modelli end-to-end predefiniti.

Nessuna modifica al codice richiesta con l'API Ultralytics
from ultralytics import YOLO

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

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

Utilizzo di codice di inferenza personalizzato#

Sì, il formato di output è diverso. Se hai scritto una logica di post-elaborazione personalizzata per YOLOv8 o YOLO11 (ad esempio, durante l'esecuzione dell'inferenza con ONNX Runtime o TensorRT), dovrai aggiornarla per gestire la nuova forma di output:

YOLOv8 / YOLO11YOLO26 (end-to-end)
Output di rilevamento(N, nc + 4, 8400)(N, 300, 6)
Formato bboxxywh (centro x, centro y, larghezza, altezza)xyxy (in alto a sinistra x, in alto a sinistra y, in basso a destra x, in basso a destra y)
LayoutCoordinate box + punteggi di classe per ancoraggio[x1, y1, x2, y2, conf, class_id]
NMS richiestaNo
Post-elaborazioneNMS + filtro di confidenzaSolo filtro di confidenza

Per i task di segmentazione, pose e OBB, YOLO26 aggiunge dati specifici del task a ciascuna rilevazione: consulta la tabella delle forme di output.

Con i modelli end-to-end, la post-elaborazione diventa molto più semplice; ad esempio, quando si utilizza 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] > 0.25]  # confidence filter, no NMS

Passaggio alla Head One-to-Many#

Se hai bisogno del formato di output YOLO tradizionale (ad esempio, per riutilizzare codice di post-elaborazione basato su NMS esistente), puoi passare alla testa uno-a-molti quando disponibile impostando end2end=False:

Utilizzo della head one-to-many per l'output tradizionale basato su NMS
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)

Compatibilità del formato di esportazione#

La maggior parte dei formati di esportazione supporta l'inferenza end-to-end nativamente, inclusi ONNX, TensorRT, CoreML, OpenVINO, LiteRT e MNN.

I seguenti formati non supportano l'end-to-end e passano automaticamente alla testa uno-a-molti: NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX, Edge TPU e Qualcomm QNN.

Cosa succede quando end-to-end non è supportato

Quando esporti in uno di questi formati, Ultralytics passa automaticamente alla testa uno-a-molti e registra un avviso. Ciò significa che avrai bisogno di NMS nella tua pipeline di inferenza per questi formati, proprio come con YOLOv8 o YOLO11.

Per Hailo, l'esportatore sceglie il percorso di output dalla testa caricata anziché da un argomento, quindi end2end viene rifiutato se passato: un modello di rilevamento YOLO26 predefinito mantiene i suoi output uno-a-uno senza NMS, mentre un checkpoint la cui testa è già end2end=False compila il percorso tradizionale con HailoRT NMS.

La quantizzazione e la versione del runtime possono disabilitare l'end-to-end

TensorRT e LiteRT supportano l'end-to-end, ma il ramo viene disabilitato automaticamente su TensorRT precedente alla versione 8.5.0, su TensorRT 10.3.0 con quantize=8 su JetPack 6 e su LiteRT con quantize=8 o quantize="w8a16". Ogni caso registra un avviso ed esporta la testa uno-a-molti.

Compromessi tra precisione e velocità#

Il rilevamento end-to-end offre significativi vantaggi di distribuzione con un impatto minimo sull'accuratezza:

MetricaEnd-to-End (predefinito)Uno-a-molti + NMS (end2end=False)
COCO mAPval0,6-0,8 inferioreBaseline
Post-elaborazioneSolo filtro di confidenzaPipeline NMS completa
Complessità di distribuzioneMinimaRichiede implementazione NMS

Su tutte e cinque le scale di rilevamento, la testa uno-a-uno costa 0,6-0,8 di mAP su COCO — da 40,9 a 40,1 per YOLO26n e da 57,5 a 56,9 per YOLO26x — in cambio dell'eliminazione totale del passaggio NMS. Se la massima precisione è la tua priorità, torna alla testa uno-a-molti con end2end=False.

Consulta le metriche di prestazione di YOLO26 per benchmark dettagliati su tutte le dimensioni dei modelli (n, s, m, l, x).

Migrazione da YOLOv8 o YOLO11#

Se stai aggiornando un progetto esistente a YOLO26:

  • Utenti dell'API / CLI di Ultralytics: Nessuna modifica necessaria: basta aggiornare il nome del modello a yolo26n.pt (o yolo26n-seg.pt, yolo26n-pose.pt, yolo26n-obb.pt)
  • Codice di post-elaborazione personalizzato: Aggiorna per gestire le nuove forme di output: (N, 300, 6) per il rilevamento, più dati specifici del task per segmentazione, pose e OBB. Nota anche il cambiamento del formato dei riquadri da xywh a xyxy
  • Pipeline di esportazione: Controlla la sezione di compatibilità dei formati per il tuo formato di destinazione
  • TensorRT inferiore a 8.5.0: l'end-to-end è disabilitato a ogni precisione; aggiorna TensorRT alla versione 8.5.0 o successiva per mantenerlo
  • Esportazioni quantizzate: TensorRT 10.3.0 con quantize=8 su JetPack 6 e LiteRT con quantize=8 o quantize="w8a16" disabilitano automaticamente l'end-to-end; esporta a una precisione superiore per mantenerlo
  • Esportazioni FP16: Se hai bisogno di tutti gli output in FP16, esporta con end2end=False; consulta il motivo per cui output0 rimane FP32
  • iOS / CoreML: L'end-to-end è completamente supportato. Se hai bisogno del supporto per Xcode Preview, usa end2end=False con nms=True
  • Dispositivi edge (NCNN, RKNN): Questi formati tornano automaticamente a one-to-many, quindi includi NMS nella tua pipeline on-device

Conclusione#

Il rilevamento end-to-end è predefinito in YOLO26 e non richiede modifiche al codice se usi l'API Python di Ultralytics o la CLI. Solo le pipeline di post-elaborazione personalizzate devono essere aggiornate per leggere il nuovo output (N, 300, 6) ed eliminare la fase NMS, ad eccezione dei formati di esportazione che passano all'output uno-a-molti (come NCNN e RKNN), che richiedono ancora NMS sul dispositivo. Per benchmark dettagliati su velocità e accuratezza di tutte le dimensioni dei modelli, consulta la pagina del modello YOLO26, mentre per l'insieme completo di opzioni e formati di esportazione, consulta la documentazione della modalità di esportazione.

FAQ#

  • No. Queste opzioni si escludono a vicenda. Se imposti nms=True su un modello end-to-end durante l'esportazione, questo verrà forzato automaticamente a nms=False con un avviso. La testa end-to-end gestisce già internamente il filtraggio dei duplicati, quindi l'NMS esterno non è necessario.

    Tuttavia, end2end=False combinato con nms=True è una configurazione valida: incorpora l'NMS tradizionale nel grafico di esportazione. Questo può essere utile per le esportazioni CoreML perché consente di utilizzare direttamente la funzione Preview in Xcode con il modello di rilevamento.

  • Il parametro max_det (predefinito: 300) imposta il numero massimo di rilevazioni restituite per immagine. Puoi regolarlo al momento dell'inferenza o dell'esportazione:

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

    Il valore è incorporato in un grafico esportato come top-k della testa, quindi max_det=500 allarga il tensore di output fino a (1, 500, 6), limitato dal conteggio delle ancore.

  • Sì, questo è il formato di output end-to-end previsto per il rilevamento: dimensione del batch pari a 1, fino a 300 rilevamenti, ciascuno con 6 valori [x1, y1, x2, y2, confidence, class_id]. Filtra semplicemente per soglia di confidenza; non è necessario alcun NMS.

    Per altre attività, la forma dell'output varia:

    CompitoForma dell'outputDescrizione
    Rilevamento(1, 300, 6)[x1, y1, x2, y2, conf, class_id]
    Segmentazione(1, 300, 38) + (1, 32, 160, 160)6 valori del box + 32 coefficienti di maschera, più un tensore di maschera prototipo
    Pose(1, 300, 57)6 valori del box + 17 keypoints × 3 (x, y, visibilità)
    OBB(1, 300, 7)6 valori del box + 1 angolo di rotazione
  • Puoi verificarlo dall'API Python di Ultralytics o dai metadati del modello ONNX esportato:

    Verifica se un modello è end-to-end
    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

    I due controlli rispondono a domande diverse: i metadati ONNX registrano la testa che è stata esportata, mentre predictor.model.end2end segnala che l'output del backend è già post-elaborato e non richiede NMS esterno. Non concordano per un modello esportato con end2end=False, nms=True, che utilizza la testa uno-a-molti ma incorpora NMS nel grafico ed emette anche (1, 300, 6), quindi né il flag né la forma di output da soli identificano la testa. Per le forme di altri task, consulta le FAQ sulle forme di output.

  • Sì. Le varianti di task in stile rilevamento di YOLO26: rilevamento, segmentazione di istanze, stima della pose e rilevamento di oggetti orientati (OBB) supportano l'inferenza end-to-end per impostazione predefinita. Il fallback end2end=False è disponibile anche per questi task.

    Ciascun task estende l'output di rilevamento di base con dati specifici del task; le forme di output di yolo26n.pt, yolo26n-seg.pt, yolo26n-pose.pt e yolo26n-obb.pt sono elencate in Come funziona il rilevamento end-to-end.

Commenti