Inference Engine
Un motore di inferenza esegue modelli addestrati sull'hardware di destinazione usando livelli fusi, precisione ridotta e kernel ottimizzati. Come funziona e quali sono i motori più comuni.
Un motore di inferenza è un software che esegue una rete neurale addestrata per generare previsioni su nuovi dati. Prende un modello esportato da un framework di addestramento, in genere sotto forma di grafo computazionale, ad esempio un file ONNX, ottimizza il grafo per uno specifico processore e lo esegue con la minima latenza di inferenza e il minor consumo di memoria possibili. Esistono motori per ogni tipo di hardware, dalle GPU dei data center a telefoni e microcontrollori; nella distribuzione dei modelli, il motore è il componente che calcola ogni previsione.
Come i motori di inferenza velocizzano i modelli#
Un modello distribuito non aggiorna mai i suoi pesi, quindi un motore può eliminare tutto ciò che serve all'addestramento, come le attivazioni memorizzate per la retropropagazione, e riscrivere liberamente il grafo. Precalcola le parti che dipendono solo da costanti, fonde sequenze di livelli, come convoluzione, normalizzazione e attivazione, in singoli kernel, così i risultati intermedi restano nella veloce memoria on-chip, e pianifica la memoria in modo da riutilizzare i buffer. Può ridurre la precisione numerica a FP16 o INT8 tramite la quantizzazione del modello, misurando gli intervalli di attivazione su dati campione per INT8. Motori come TensorRT misurano quindi i tempi di esecuzione di diversi kernel candidati per ogni livello sul dispositivo effettivo e mantengono quello più veloce, perciò il risultato è legato a quell'hardware:
La fusione della normalizzazione batch nella convoluzione precedente è una delle riscritture più comuni. Durante l'inferenza, la normalizzazione applica soltanto una scala e uno spostamento fissi a ciascun canale, quindi questi valori possono essere incorporati nei pesi e nel bias della convoluzione. PyTorch espone la stessa trasformazione come fuse_conv_bn_eval:
import torch
from torch.nn.utils.fusion import fuse_conv_bn_eval
torch.manual_seed(0)
# A trained convolution followed by batch normalization (random statistics here)
conv = torch.nn.Conv2d(16, 32, kernel_size=3, padding=1).eval()
bn = torch.nn.BatchNorm2d(32).eval()
bn.running_mean.uniform_(-1, 1)
bn.running_var.uniform_(0.5, 2.0)
# Fold the normalization's scale and shift into the convolution's weights and bias
fused = fuse_conv_bn_eval(conv, bn)
# One layer now replaces two and produces the same output
x = torch.randn(1, 16, 64, 64)
with torch.inference_mode():
diff = (bn(conv(x)) - fused(x)).abs().max().item()
print(f"Max difference after fusing: {diff:.1e}")Stampa una differenza massima pari a 2.1e-06, dovuta all'arrotondamento in virgola mobile: il singolo livello fuso calcola la stessa funzione dei due livelli originali, ma con un solo passaggio in memoria anziché due.
Motori di inferenza comuni#
- TensorRT: il motore di NVIDIA per le GPU dei suoi data center e i moduli Jetson. Crea un piano per un singolo modello di GPU e una singola versione di TensorRT, quindi i motori vanno ricreati quando cambia uno dei due.
- OpenVINO: il toolkit di Intel per CPU, GPU integrate e discrete e NPU.
- ONNX Runtime: il motore multipiattaforma di Microsoft per i modelli ONNX, che affida il lavoro a backend hardware chiamati provider di esecuzione, tra cui CUDA, TensorRT, OpenVINO e Core ML.
- LiteRT: il runtime di Google, precedentemente TensorFlow Lite, per Android, Linux embedded e microcontrollori, con delegati per GPU mobili e NPU.
- Core ML: il framework di Apple eseguito sul dispositivo, che distribuisce il lavoro tra CPU, GPU e Neural Engine.
- vLLM: un motore open source per i modelli linguistici di grandi dimensioni, che aggiunge la pianificazione delle richieste e la memoria paginata per la cache di attenzione, così da gestire molti utenti contemporaneamente.
L'API Ultralytics YOLO sceglie il motore in base al file caricato, quindi la stessa chiamata predict esegue un checkpoint .pt in PyTorch, un file .onnx in ONNX Runtime, un file .engine in TensorRT oppure una cartella OpenVINO in OpenVINO. Esportare Ultralytics YOLO26 in OpenVINO e caricare il risultato cambia motore senza richiedere altre modifiche al codice:
from ultralytics import YOLO
# Esporta il modello PyTorch nel formato OpenVINO
model = YOLO("yolo26n.pt")
path = model.export(format="openvino") # creates 'yolo26n_openvino_model/'
# Il caricamento della cartella esportata esegue le previsioni tramite il motore OpenVINO
ov_model = YOLO(path)
results = ov_model("https://ultralytics.com/images/bus.jpg")
results[0].save(filename="bus_openvino.jpg")Motori di inferenza e termini correlati#
- PyTorch e altri framework di addestramento: mantengono il grafo flessibile e registrano le operazioni per i gradienti, così da poter progettare e addestrare i modelli. Eseguono anche l'inferenza, ma con un sovraccarico maggiore rispetto a un motore creato per un singolo dispositivo.
- ONNX: un formato di file che descrive il grafo e i pesi di un modello. ONNX Runtime e TensorRT sono motori in grado di leggerlo.
- Distribuzione dei modelli: racchiude uno o più motori in un servizio di rete con API, raggruppamento delle richieste e gestione delle versioni, come fa NVIDIA Dynamo-Triton, in precedenza Triton Inference Server, per i modelli TensorRT, ONNX Runtime e PyTorch.
- Motore di inferenza dei sistemi esperti: il significato più datato del termine, derivato dall'IA basata su regole, in cui il motore di inferenza applica regole «se-allora» a una base di conoscenza mediante concatenazione in avanti o all'indietro.










