Meet YOLO26: next-gen vision AI.

Link to this sectionComprendere il rilevamento end-to-end in Ultralytics YOLO26#

Link to this sectionIntroduzione#

Se stai passando a YOLO26 da un modello precedente come YOLOv8 o YOLO11, uno dei cambiamenti più importanti che noterai è la rimozione della Non-Maximum Suppression (NMS). I modelli YOLO tradizionali producono migliaia di previsioni sovrapposte che richiedono un passaggio separato di post-elaborazione NMS per filtrare e arrivare ai rilevamenti finali. Questo aggiunge latenza, complica i grafi di esportazione e può comportarsi in modo incoerente su diverse piattaforme hardware.

YOLO26 adotta un approccio diverso. Produce i rilevamenti finali direttamente dal modello: non è richiesto alcun filtraggio esterno. Questo è noto come end-to-end object detection ed è abilitato di default in tutti i modelli YOLO26. Il risultato è una pipeline di distribuzione più semplice, una latenza inferiore e fino al 43% di inferenza più veloce su CPU.

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 senza problemi dai vecchi modelli YOLO.

Per uno sguardo più approfondito alla motivazione dietro questo cambiamento architetturale, consulta il post sul blog di Ultralytics sul perché YOLO26 rimuove la NMS.

Riepilogo rapido
  • Usi l'API o la CLI di Ultralytics? Nessuna modifica necessaria: basta cambiare il nome del tuo modello in yolo26n.pt.
  • Usi codice di inferenza personalizzato (ONNX Runtime, TensorRT, ecc.)? Aggiorna la tua post-elaborazione: l'output di rilevamento è ora (N, 300, 6) nel formato xyxy, senza bisogno di NMS. Altri task aggiungono dati extra (coefficienti della maschera, keypoint o angolo).
  • Stai esportando? La maggior parte dei formati supporta nativamente l'output end-to-end. Tuttavia, alcuni formati (NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX, Edge TPU e QNN) tornano automaticamente all'output tradizionale a causa di vincoli di operatori non supportati (ad esempio torch.topk). I flussi di lavoro Hailo HEF vengono compilati da ONNX con script specifici per Hailo, quindi verifica la testa di rilevamento e la configurazione NMS per il tuo modello.

Link to this sectionCome funziona il rilevamento end-to-end#

YOLO26 utilizza un'architettura a doppia testa durante l'addestramento. Entrambe le teste condividono la stessa backbone e neck, ma producono output in modi diversi:

TestaScopoOutput 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 indicate si riferiscono al rilevamento. Altri task estendono l'output one-to-one con dati aggiuntivi per ogni rilevamento:

TaskOutput End-to-EndDati Extra
Rilevamento(N, 300, 6)
Segmentazione istanze(N, 300, 6 + nm) + proto (N, nm, H, W)nm coefficienti maschera (predefinito 32)
Pose(N, 300, 57)17 keypoint × 3 (x, y, visibilità)
OBB(N, 300, 7)Angolo di rotazione

During training, both heads run simultaneously — the one-to-many head provides a richer learning signal, while the one-to-one head learns to produce clean, non-overlapping predictions. During inference and export, only the one-to-one head is active by default, producing up to 300 detections per image in the format [x1, y1, x2, y2, confidence, class_id].

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

Link to this sectionDevo cambiare il mio codice?#

Link to this sectionUso dell'API Python o della CLI di Ultralytics#

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

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")

Link to this sectionUso di codice di inferenza personalizzato#

Yes, the output format is different. If you wrote custom post-processing logic for YOLOv8 or YOLO11 (for example, when running inference with ONNX Runtime or TensorRT), you'll need to update it to handle the new output shape:

YOLOv8 / YOLO11YOLO26 (end-to-end)
Output di rilevamento(N, nc + 4, 8400)(N, 300, 6)
Formato Boxxywh (x centrale, y centrale, larghezza, altezza)xyxy (x in alto a sinistra, y in alto a sinistra, x in basso a destra, y in basso a destra)
LayoutCoordinate box + punteggi classe per anchor[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 per il task a ogni rilevamento: vedi la tabella delle forme di output qui sopra.

Dove N è la batch size e nc è il numero di classi (es. 80 per COCO).

Con i modelli end-to-end, la post-elaborazione diventa molto più semplice, ad esempio quando si usa 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!

Link to this sectionPassaggio alla testa One-to-Many#

Se hai bisogno del formato di output YOLO tradizionale (ad esempio, per riutilizzare il codice di post-elaborazione esistente basato su NMS), puoi passare alla testa one-to-many in qualsiasi momento impostando end2end=False:

Uso della testa 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)

Link to this sectionCompatibilità del formato di esportazione#

La maggior parte dei formati di esportazione supporta l'inferenza end-to-end immediatamente, inclusi ONNX, TensorRT, CoreML, OpenVINO, TFLite, TF.js e MNN.

I seguenti formati non supportano l'end-to-end e tornano automaticamente alla testa one-to-many: NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX, Edge TPU e Qualcomm QNN.

Cosa succede quando l'end-to-end non è supportato

When you export to one of these formats, Ultralytics automatically switches to the one-to-many head and logs a warning — no manual intervention needed. This means you'll need NMS in your inference pipeline for these formats, just like with YOLOv8 or YOLO11.

Per Hailo HEF, il passaggio di compilazione avviene al di fuori di model.export(format=...) dopo un'esportazione ONNX. Utilizza i log DFC di Hailo, lo script del modello .alls e il JSON NMS che corrispondono esattamente al tuo modello di rilevamento; se un grafo YOLO26 end-to-end non è supportato dalla tua toolchain Hailo, esporta il modello ONNX con end2end=False e compila la testa di rilevamento tradizionale.

TensorRT + INT8

TensorRT supporta l'end-to-end, ma è disabilitato automaticamente quando si esporta con int8=True su TensorRT ≤10.3.0.

Link to this sectionCompromessi tra precisione e velocità#

Il rilevamento end-to-end offre significativi vantaggi di distribuzione con un impatto minimo sulla precisione:

MetricaEnd-to-End (predefinito)One-to-Many + NMS (end2end=False)
Velocità inferenza CPUFino al 43% più veloceBaseline
Impatto mAP~0.5 mAP in menoEguaglia o supera YOLO11
Post-elaborazioneSolo filtro di confidenzaPipeline NMS completa
Complessità di distribuzioneMinimaRichiede implementazione NMS

Per la maggior parte delle applicazioni reali, la differenza di ~0.5 mAP è trascurabile, specialmente se si considerano i guadagni in velocità e semplicità. Se la massima precisione è la tua priorità assoluta, puoi sempre tornare alla testa one-to-many usando end2end=False.

Consulta le metriche delle prestazioni di YOLO26 per benchmark dettagliati su tutte le dimensioni del modello (n, s, m, l, x).

Link to this sectionMigrazione da YOLOv8 o YOLO11#

Se stai aggiornando un progetto esistente a YOLO26, ecco una rapida lista di controllo per garantire una transizione fluida:

  • Utenti API / CLI di Ultralytics: Nessuna modifica necessaria: aggiorna semplicemente il nome del modello in 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, oltre ai dati specifici per segmentazione, pose e OBB. Nota anche il cambio di formato delle box da xywh a xyxy
  • Pipeline di esportazione: Controlla la sezione compatibilità del formato sopra per il tuo formato di destinazione
  • TensorRT + INT8: Verifica che la tua versione di TensorRT sia >10.3.0 per il supporto end-to-end
  • Esportazioni FP16: Se ti servono tutti gli output in FP16, esporta con end2end=False — vedi perché output0 rimane FP32
  • iOS / CoreML: L'end-to-end è pienamente supportato. Se hai bisogno del supporto per Xcode Preview, usa end2end=False con nms=True
  • Dispositivi Edge (NCNN, RKNN): Questi formati ripiegano automaticamente su one-to-many, quindi includi NMS nella tua pipeline sul dispositivo

Link to this sectionFAQ#

Link to this sectionPosso usare end2end=True e nms=True insieme?#

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

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

Link to this sectionCosa controlla il parametro max_det nei modelli end-to-end?#

Il parametro max_det (predefinito: 300) imposta il numero massimo di rilevamenti che la head one-to-one può produrre per immagine. Puoi regolarlo durante l'inferenza o al momento dell'esportazione:

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

Nota che i checkpoint predefiniti di YOLO26 sono stati addestrati con max_det=300. Sebbene tu possa aumentare questo valore, la head one-to-one è stata ottimizzata durante l'addestramento per produrre fino a 300 rilevamenti puliti, quindi rilevamenti oltre tale limite potrebbero essere di qualità inferiore. Se ti servono più di 300 rilevamenti per immagine, valuta di riaddestrare con un valore max_det più elevato.

Link to this sectionIl mio modello ONNX esportato restituisce (1, 300, 6) — è corretto?#

Sì, è il formato di output end-to-end previsto per il rilevamento: batch size di 1, fino a 300 rilevamenti, ciascuno con 6 valori [x1, y1, x2, y2, confidence, class_id]. Filtra semplicemente in base alla soglia di confidenza e il gioco è fatto — non serve alcun NMS.

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

TaskForma dell'OutputDescrizione
Rilevamento(1, 300, 6)[x1, y1, x2, y2, conf, class_id]
Segmentazione(1, 300, 38) + (1, 32, 160, 160)6 valori box + 32 coefficienti maschera, più un tensore maschera prototipo
Posa(1, 300, 57)6 valori box + 17 keypoint × 3 (x, y, visibilità)
OBB(1, 300, 7)6 valori box + 1 angolo di rotazione

Link to this sectionCome faccio a verificare se il mio modello esportato è end-to-end?#

Puoi controllare utilizzando l'API Python di Ultralytics o ispezionando direttamente i 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

In alternativa, controlla la forma dell'output — i modelli di rilevamento end-to-end restituiscono (1, 300, 6), mentre i modelli tradizionali restituiscono (1, nc + 4, 8400). Per le forme di altre attività, vedi le FAQ sulle forme di output.

Link to this sectionL'end-to-end è supportato per segmentazione di istanze, posa e attività OBB?#

Sì. Le varianti delle attività in stile rilevamento di YOLO26 — rilevamento, segmentazione di istanze, stima della posa e rilevamento orientato di oggetti (OBB) — supportano l'inferenza end-to-end per impostazione predefinita. Il ripiegamento end2end=False è disponibile anche per queste attività.

Ogni attività estende l'output di rilevamento di base con dati specifici dell'attività:

TaskModelloOutput End-to-End
Rilevamentoyolo26n.pt(N, 300, 6)
Segmentazione di Istanzeyolo26n-seg.pt(N, 300, 38) + proto (N, 32, 160, 160)
Posayolo26n-pose.pt(N, 300, 57)
OBByolo26n-obb.pt(N, 300, 7)

Commenti