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ù significativi che noterai è la rimozione della Non-Maximum Suppression (NMS). I modelli YOLO tradizionali producono migliaia di previsioni sovrapposte che richiedono un passaggio di post-elaborazione NMS separato per filtrare le rilevazioni finali. Ciò aumenta la latenza, complica i grafi di esportazione e può comportarsi in modo incoerente su diverse piattaforme hardware.

YOLO26 adotta un approccio diverso. Produce le rilevazioni finali direttamente dal modello: non è richiesto alcun filtraggio esterno. Questo è noto come object detection end-to-end ed è abilitato per impostazione predefinita in tutti i modelli YOLO26. Il risultato è una pipeline di distribuzione più semplice, una latenza inferiore e fino al 43% di inferenza più veloce sulle 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 agevolmente dai vecchi modelli YOLO.

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

Riepilogo veloce
  • Stai usando l'API o la CLI di Ultralytics? Nessuna modifica necessaria: basta cambiare il nome del tuo modello in yolo26n.pt.
  • Stai usando un codice di inferenza personalizzato (ONNX Runtime, TensorRT, ecc.)? Aggiorna la tua post-elaborazione: l'output di rilevamento ora è (N, 300, 6) in formato xyxy, senza necessità di NMS. Altri task aggiungono dati extra (coefficienti di maschera, keypoint o angolo).
  • Stai esportando? La maggior parte dei formati supporta l'output end-to-end nativamente. Tuttavia, alcuni formati (NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX, Edge TPU e QNN) tornano automaticamente all'output tradizionale a causa di vincoli degli operatori non supportati (ad esempio torch.topk). I flussi di lavoro Hailo HEF compilano da ONNX con script specifici per Hailo, quindi verifica la head 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 head durante l'addestramento. Entrambe le head condividono lo stesso backbone e neck, ma producono output in modi diversi:

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

CompitoOutput end-to-endDati extra
Rilevamento(N, 300, 6)
Segmentazione di istanze(N, 300, 6 + nm) + proto (N, nm, H, W)Coefficienti di 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 head funzionano simultaneamente: la head one-to-many fornisce un segnale di apprendimento più ricco, mentre la head one-to-one impara a produrre previsioni pulite e non sovrapposte. Durante l'inferenza e l'esportazione, solo la one-to-one head è attiva per impostazione predefinita, producendo fino a 300 rilevazioni per immagine nel formato [x1, y1, x2, y2, confidence, class_id].

Quando chiami model.fuse(), esso combina i livelli Conv + BatchNorm per un'inferenza più rapida e, nei modelli end-to-end, rimuove anche la head one-to-many, riducendo le dimensioni del modello e i FLOP. Per maggiori dettagli sull'architettura a doppia head, vedi la pagina del modello YOLO26.

Link to this sectionDevo modificare il mio codice?#

Link to this sectionUtilizzo 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: previsione, validazione ed esportazione gestiscono tutti i modelli end-to-end senza configurazioni aggiuntive.

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 sectionUtilizzo 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 (x in alto a sinistra, y in alto a sinistra, x in basso a destra, y in basso a destra)
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 ogni rilevamento: vedi la tabella delle forme di output qui sopra.

Dove N è la dimensione del batch e nc è il numero di classi (ad esempio 80 per COCO).

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] > conf_threshold]  # confidence filter — that's it!

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

Se hai bisogno del formato di output YOLO tradizionale (ad esempio, per riutilizzare il codice di post-elaborazione basato su NMS esistente), puoi passare alla head one-to-many in qualsiasi momento 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)

Link to this sectionCompatibilità del formato di esportazione#

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

I seguenti formati non supportano end-to-end e tornano automaticamente alla head one-to-many: 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 head one-to-many e registra un avviso: nessun intervento manuale necessario. Ciò significa che avrai bisogno di NMS nella tua pipeline di inferenza per questi formati, proprio come con YOLOv8 o YOLO11.

Per Hailo HEF, il passaggio di compilazione avviene al di fuori di model.export(format=...) dopo un'esportazione ONNX. Utilizza i log di Hailo DFC, 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 head di rilevamento tradizionale.

TensorRT + INT8

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

Link to this sectionCompromessi tra precisione e velocità#

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

MetricaEnd-to-End (predefinito)One-to-Many + NMS (end2end=False)
Velocità di inferenza CPUFino al 43% più veloceBaseline
Impatto mAP~0.5 mAP inferioreEguaglia 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 consideri i guadagni in termini di velocità e semplicità. Se la massima accuratezza è la tua priorità assoluta, puoi sempre tornare alla head one-to-many usando end2end=False.

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

Link to this sectionMigrazione da YOLOv8 o YOLO11#

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

  • 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, più dati specifici del task per segmentazione, pose e OBB. Nota anche il cambio di formato del box da xywh a xyxy
  • Pipeline di esportazione: Controlla la sezione sulla compatibilità del formato sopra per il tuo formato di destinazione
  • TensorRT + INT8: Su JetPack 6, TensorRT 10.3.0 disabilita automaticamente end-to-end con int8=True: usa una versione diversa di TensorRT per mantenere end-to-end
  • Esportazioni FP16: Se hai bisogno di tutti gli output in FP16, esporta con end2end=False: vedi perché output0 rimane FP32
  • iOS / CoreML: End-to-end è completamente supportato. Se hai bisogno del supporto per l'anteprima di Xcode, 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

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à forzato automaticamente a nms=False con un avviso. La head end-to-end gestisce già internamente il filtraggio dei duplicati, quindi una NMS esterna non è necessaria.

Tuttavia, end2end=False combinato con nms=True è una configurazione valida: incorpora la NMS tradizionale nel grafo di esportazione. Questo può essere utile per le esportazioni CoreML perché ti consente di utilizzare direttamente la funzione di anteprima in Xcode 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 al momento dell'inferenza o 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 i rilevamenti oltre tale limite potrebbero avere una qualità inferiore. Se ti servono più di 300 rilevamenti per immagine, valuta la possibilità di riaddestrare con un valore di 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 è 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

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

Puoi verificare 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à, consulta le FAQ sulle forme di output.

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

Sì. Le varianti delle attività in stile rilevamento di YOLO26 — rilevamento, segmentazione dell'istanza, stima della posa e rilevamento di oggetti orientati (OBB) — supportano l'inferenza end-to-end per impostazione predefinita. Anche il fallback end2end=False è disponibile per queste attività.

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

CompitoModelloOutput end-to-end
Rilevamentoyolo26n.pt(N, 300, 6)
Segmentazione dell'istanzayolo26n-seg.pt(N, 300, 38) + proto (N, 32, 160, 160)
Poseyolo26n-pose.pt(N, 300, 57)
OBByolo26n-obb.pt(N, 300, 7)

Commenti