Ultralytics YOLO27: Iscriviti alla lista d'attesa.
Get Started
Addestra il tuo primo modello YOLO·Distribuisci·Lezione 10/10
Lezioneprincipiante

Esporta per la distribuzione

Esporta best.pt in ONNX, OpenVINO, TensorRT, CoreML, LiteRT o QNN, poi verifica che l'esportazione corrisponda al modello PyTorch prima di distribuirla.

Per funzionare, il tuo best.pt richiede Python e PyTorch; in genere telefoni, browser, Jetson e server di produzione non li hanno. La modalità Export converte il modello in un file autonomo per questi runtime con una sola chiamata. Attenzione: il fatto che un'esportazione venga caricata non significa che sia corretta; inoltre, un confronto eseguito senza la dovuta attenzione può far sembrare difettosa un'esportazione corretta o nascondere i problemi di una non corretta.

In questa lezione esporterai il modello per il rilevamento delle pillole in ONNX, lo eseguirai tramite la stessa API YOLO, verificherai che corrisponda a PyTorch nei riquadri e nella mAP di validazione con impostazioni uniformi e sceglierai il formato richiesto dalla piattaforma di destinazione: ONNX, OpenVINO, TensorRT, CoreML, LiteRT o QNN.

Esito

Puoi esportare un modello addestrato nel formato adatto alla piattaforma di distribuzione e verificare, con un confronto di parità a parità di condizioni e una validazione, che l'esportazione corrisponda a best.pt.

Percorso rapido
Se sai già come muoverti, ecco la versione breve.
  1. yolo export model=runs/detect/pills_v1/weights/best.pt format=onnx — inizia da qui.

  2. OpenVINO per CPU Intel; TensorRT per GPU NVIDIA e Jetson; CoreML per Apple; LiteRT per Android; QNN per NPU Snapdragon.

  3. Confronta .pt e l'esportazione sulla stessa immagine, usando rect=False dal lato .pt.

  4. Convalida entrambi con imgsz usato durante l'addestramento; mAP50-95 dovrebbe coincidere.

Pratico

Esempio svolto: esportare in ONNX#

Scheda Esporta modelli della Piattaforma Ultralytics, con l'elenco di formati per la distribuzione come ONNX, TensorRT, CoreML e OpenVINO

yolo export model=runs/detect/pills_v1/weights/best.pt format=onnx
PyTorch: starting from 'runs/detect/pills_v1/weights/best.pt' with input shape (1, 3, 320, 320) BCHW and output shape(s) (1, 5, 2100) (5.2 MB)
ONNX: export success ✅ 0.9s, saved as 'runs/detect/pills_v1/weights/best.onnx' (9.3 MB)
Predict:         yolo predict task=detect model=runs/detect/pills_v1/weights/best.onnx imgsz=320
Validate:        yolo val task=detect model=runs/detect/pills_v1/weights/best.onnx imgsz=320 data=my_dataset/data.yaml

Analisi riga per riga:

  • input shape (1, 3, 320, 320): un'immagine, 3 canali di colore, un quadrato fisso di 320×320: la dimensione imgsz usata durante l'addestramento, incorporata nel file.
  • output shape(s) (1, 5, 2100): 4 valori per il riquadro più 1 punteggio di classe per 2.100 riquadri candidati; per impostazione predefinita, NMS viene eseguita all'esterno del grafo.
  • 9.3 MB: il file ONNX memorizza i pesi FP32, quindi è più grande di .pt in FP16.
  • Predict: / Validate:: comandi già pronti per il file esportato, con il valore corretto di imgsz.

Bastano pochi argomenti per la maggior parte dei casi; la guida all'integrazione ONNX elenca gli altri.

ArgomentoPredefinitaA cosa serve
imgszDimensione di addestramentoEsporta con una dimensione di input fissa diversa, ad esempio imgsz=640
dynamicFalseAccetta dimensioni di input variabili invece di una sola forma fissa
quantizeNessuna (FP32)16 per i pesi FP16 (la dimensione di yolo26n.onnx passa da 9.5 MB a 4.8 MB); 8 per INT8, se supportato dal formato
nmsNessunanms=True incorpora NMS nel grafo, così il runtime restituisce i riquadri finali

Esempio svolto: verifica che l'esportazione corrisponda al modello#

Anche la classe YOLO carica i file esportati, quindi il codice di predict visto in precedenza funziona senza modifiche. Confronta entrambi i file sulla stessa immagine di validazione:

from ultralytics import YOLO

image = "my_dataset/images/val/Frame_144.jpg"
pt = YOLO("runs/detect/pills_v1/weights/best.pt")(image, rect=False, verbose=False)[0]  # square input, like ONNX
onnx = YOLO("runs/detect/pills_v1/weights/best.onnx")(image, verbose=False)[0]

print(f"pt:   {len(pt.boxes)} pills, mean conf {pt.boxes.conf.mean():.3f}")
print(f"onnx: {len(onnx.boxes)} pills, mean conf {onnx.boxes.conf.mean():.3f}")
print(f"max box difference: {(pt.boxes.xyxy - onnx.boxes.xyxy).abs().max():.4f} px")
pt:   25 pills, mean conf 0.870
onnx: 25 pills, mean conf 0.870
max box difference: 0.0002 px

Stesso conteggio, stessa confidenza, riquadri identici fino a una frazione di pixel. Ora esegui il controllo più rigoroso: la validazione sull'intero split:

from ultralytics import YOLO

pt = YOLO("runs/detect/pills_v1/weights/best.pt").val(data="my_dataset/data.yaml", rect=False, verbose=False)
onnx = YOLO("runs/detect/pills_v1/weights/best.onnx").val(data="my_dataset/data.yaml", verbose=False)
print(f".pt   mAP50-95 {pt.box.map:.4f}")
print(f".onnx mAP50-95 {onnx.box.map:.4f}")
.pt   mAP50-95 0.6570
.onnx mAP50-95 0.6570

Identici. (La validazione rettangolare predefinita del file .pt ha ottenuto 0.659: una piccola differenza dovuta al padding dell'input, non all'esportazione.)

Una volta verificata la corrispondenza, misura i tempi con yolo benchmark sul dispositivo di destinazione, così saprai quanto è veloce prima di distribuirlo.

Scegli un formato per la piattaforma di destinazione#

Il ciclo di vita della Piattaforma Ultralytics: annotazione con l'annotazione intelligente SAM, addestramento su GPU cloud e distribuzione in aree geografiche globali, con i loghi dei partner di integrazione

ObiettivoFormatoNote
Scelta predefinita portabile: server e computer desktop con Linux, Windows e MaconnxONNX Runtime su CPU o GPU; l'esportazione più rapida da verificare
GPU NVIDIA e Jetsonengine (TensorRT)Il più veloce su NVIDIA; esegui l'esportazione sul dispositivo. Vedi Ottimizzare con TensorRT
CPU e iGPU IntelopenvinoIncrementi reali di velocità della CPU grazie ai kernel Intel. Vedi OpenVINO su CPU
App per iPhone, iPad e MaccoremlNativo; usa l'Apple Neural Engine
Android e altri dispositivi mobili o embeddedlitertINT8 consigliato per dispositivi mobili
NPU SnapdragonqnnAccelerazione Hexagon HTP; pesi INT8 con attivazioni a 16 bit per impostazione predefinita; scegli l'architettura HTP con name
Browser webonnx con ONNX Runtime WebI modelli più piccoli sono una scelta concreta: n e s
from ultralytics import YOLO

model = YOLO("runs/detect/pills_v1/weights/best.pt")

model.export(format="onnx")  # multipiattaforma: ONNX Runtime
model.export(format="openvino")  # CPU / iGPU Intel
model.export(format="engine", quantize=16)  # NVIDIA TensorRT, FP16 (esegui sulla GPU di destinazione)
model.export(format="coreml")  # Apple iOS / macOS
model.export(format="litert", quantize=8, data="my_dataset/data.yaml")  # Android / edge, INT8
model.export(format="qnn", name="73", data="my_dataset/data.yaml")  # NPU Qualcomm Snapdragon (HTP v73); calibra sui tuoi dati

Ogni esportazione scrive i file accanto ai pesi: best.onnx, best_openvino_model/, best.engine e così via. Inizia con ONNX anche se alla fine userai un altro formato: è il più rapido da verificare e costituisce l'input per diverse altre toolchain. La guida alle opzioni di deployment confronta tutti i formati, mentre Scegliere una destinazione di deployment ti accompagna nella scelta.

La quantizzazione del modello scambia precisione con dimensioni e velocità. FP16 (quantize=16) dimezza le dimensioni del file con una precisione quasi invariata. INT8 (quantize=8) riduce ulteriormente le dimensioni e aumenta la velocità, ma richiede immagini di calibrazione: fotogrammi rappresentativi che l'esportazione elabora per scegliere gli intervalli dei valori; Ultralytics ne consiglia almeno 300. Convalida sempre un modello INT8 prima della distribuzione: la perdita può essere trascurabile o notevole, a seconda del modello e del set di calibrazione.

Evita questi errori#

Confrontare input diversi

Sintomo: il modello .pt rileva 35 pillole su Frame_144.jpg, mentre il file ONNX ne rileva 25, e l'esportazione sembra non funzionare. Causa: l'inferenza PyTorch riempie ogni immagine fino al rettangolo più piccolo allineato allo stride (192×320 per questi frame in formato 16:9), mentre un modello ONNX statico accetta sempre un quadrato di 320×320. Input diversi producono rilevazioni diverse a bassa confidenza. Soluzione: durante il confronto passa rect=False al modello .pt, come in parity.py.

Un'esportazione statica ignora imgsz

Sintomo: passi imgsz=640 a best.onnx, ma il log indica ancora 320x320. Causa: un'esportazione statica ha un'unica dimensione di input, impostata al momento dell'esportazione. Soluzione: esporta alla dimensione che userai (imgsz=640) oppure esporta con dynamic=True.

I motori TensorRT sono specifici per dispositivo

Un .engine creato su un A100 non funzionerà su un Jetson Orin e potrebbe non essere compatibile con un aggiornamento di TensorRT. Esporta sul dispositivo di destinazione, usando la versione di TensorRT che verrà eseguita. ONNX è portabile; i motori non lo sono.

INT8 usa COCO8 per la calibrazione, a meno che tu non specifichi diversamente

Se ometti data da un'esportazione INT8, Ultralytics mostra un avviso e poi esegue la calibrazione sul campione COCO8 predefinito: otto immagini che non assomigliano affatto alle tue pillole. Passa il tuo campione: model.export(format="litert", quantize=8, data="my_dataset/data.yaml").

Hai completato la distribuzione#

Ora hai un best.pt addestrato, i risultati della convalida accanto a un valore di riferimento, un file esportato per il tuo runtime e la prova che l'esportazione corrisponde all'originale. Hai completato l'intero ciclo — dati, addestramento, convalida, esportazione, deployment — che i team di produzione eseguono secondo una pianificazione. Ultralytics YOLO in Production riparte dalla tua esportazione verificata e tratta runtime ottimizzati, pipeline di tracking, gestione di più flussi e monitoraggio.

Provalo

Esporta il tuo pills_v1/weights/best.pt in ONNX, poi esegui parity.py e val_export.py. Esegui di nuovo parity.py senza rect=False e registra come cambia il conteggio di .pt. Consegna quattro elementi: il conteggio delle rilevazioni corrispondenti, la differenza massima tra i box, i due valori mAP50-95 e una riga che indichi il formato richiesto dalla tua destinazione di deployment reale e il motivo.

Conferma
git add -A && git commit -m "feat(deploy): exported best.pt to onnx for production runtime"
Criteri di completamento
La lezione è completata quando tutte le seguenti condizioni sono soddisfatte.
  • runs/detect/pills_v1/weights/best.onnx esiste e genera previsioni tramite YOLO().

  • Con rect=False, i conteggi delle rilevazioni corrispondono e la differenza massima tra i box è inferiore a 1 px.

  • I valori mAP50-95 di convalida di ONNX e .pt corrispondono a impostazioni identiche e hai indicato il formato di destinazione con una motivazione.

Mostra la soluzione
from ultralytics import YOLO

# Train
model = YOLO("yolo26n.pt")
model.train(data="my_dataset/data.yaml", epochs=10, imgsz=320, name="pills_e2e")

# Validate
metrics = model.val()
print(f"mAP50-95 = {metrics.box.map:.3f}")  # 0.659

# Export
model.export(format="onnx")
parity.py:      pt 25 pills, onnx 25 pills, max box difference 0.0002 px
without rect:   pt 35 pills (192x320 input) vs onnx 25 (320x320): input mismatch, not an export bug
val_export.py:  .pt 0.6570, .onnx 0.6570
Target:         Intel laptop CPU -> openvino, for faster CPU inference than ONNX Runtime
Prossimi passi

Corso completato: supera il quiz finale per ottenere il certificato Train your first YOLO model, poi continua con Ultralytics YOLO in Production.

Accedi per salvare i progressi