TF Lite Delegate è un componente di TensorFlow Lite che reindirizza l'esecuzione delle operazioni di rete neurale a hardware specializzato: GPU, NPU, DSP o CPU ottimizzato. Senza un delegato, il modello viene eseguito sulla CPU in modalità di piena compatibilità — lento ma prevedibile. Il delegato accelera l'inferenza di 3–10 volte a seconda del chip e del modello. Secondo TensorFlow, 2025, i delegati GPU e NNAPI riducono la latenza di inferenza del 60–90% senza perdita significativa di precisione.
Punti Chiave
TF Lite Delegate è un adattatore software tra TensorFlow Lite Runtime e l'acceleratore hardware del dispositivo. Il delegato intercetta le operazioni del grafo del modello (convoluzioni, pooling, moltiplicazioni di matrici) e le esegue su un'unità di calcolo specializzata invece della CPU. Se il delegato non supporta un'operazione specifica, viene eseguita sulla CPU — questo si chiama delega parziale.
Architettura di TF Lite Delegate è costruita attorno all'interfaccia SimpleDelegate API e alla struttura TfLiteDelegate in C++. Ogni delegato implementa metodi di delega dei nodi del grafo, allocazione di memoria ed esecuzione sul dispositivo di destinazione. Lo sviluppatore collega il delegato tramite Interpreter::ModifyGraphWithDelegate prima di chiamare Invoke. Secondo la Guida TensorFlow, il delegato viene applicato automaticamente a tutte le operazioni supportate del modello.
Verifica di compatibilità è un passo obbligatorio. Non tutte le operazioni sono supportate da ogni delegato. TensorFlow Lite fornisce lo strumento Delegation Compatibility Check: esegui il modello con il delegato e controlla quante operazioni (ops) sono delegate. Se meno dell'80% sono delegate, considera di scegliere un altro delegato o di rimanere sulla CPU. Secondo TensorFlow (2025), GPU Delegate supporta 45 operazioni, NNAPI — 60+.
Nei progetti IT Sectr, utilizziamo i delegati GPU per iOS e XNNPACK per Android con verifica di compatibilità integrata: il modello viene testato su tutti i delegati, selezionando il più veloce con almeno il 90% di delega completa.
// Connessione GPU Delegate su Android
val gpuDelegate = GpuDelegate()
val options = Interpreter.Options().apply {
addDelegate(gpuDelegate)
setNumThreads(4)
}
val interpreter = Interpreter(modelBuffer, options)
interpreter.run(input, output)
gpuDelegate.close()
Verifica delle operazioni delegate — controllo di compatibilità tramite Interpreter. Per impostazione predefinita, il delegato accetta tutte le operazioni che supporta. Per il debug, utilizza la registrazione del numero di nodi delegati. Se il modello contiene operazioni personalizzate (custom ops), il delegato non le accelera ma non le rompe nemmeno — vengono eseguite sulla CPU.
// Controllare il conteggio delle operazioni delegate
val delegateCount = interpreter.getDelegateOpsCount(gpuDelegate)
val totalNodes = interpreter.getNodesCount()
Log.d("TFLite", "Delegate: $delegateCount / $totalNodes")
if (delegateCount < totalNodes * 0.8) {
// Soglia dell'80% — scegli un altro delegato
}
GPU Delegate è un delegato TensorFlow Lite per eseguire modelli sulla GPU tramite OpenGL ES 3.1+ (Android) o Metal (iOS). I processori grafici sono ottimizzati per operazioni matriciali parallele — Core ML e le reti neurali convolutive (CNN) ne traggono il maggior beneficio. GPU Delegate riduce la latenza di inferenza di 4–8 volte per modelli come MobileNet, EfficientNet, Inception.
Limitazioni di GPU Delegate: non supporta tutte le operazioni (solo 45 su ~120 in TF Lite), richiede OpenGL ES 3.1 o Metal, consuma più energia della CPU. La GPU è inefficiente per batch size > 1 in scenari mobili. Secondo i benchmark TensorFlow (2025), su Pixel 8 con GPU Adreno 740, MobileNetV2 viene eseguito in 4,2 ms sulla GPU contro 18,7 ms sulla CPU — un'accelerazione di 4,4x.
Configurazione di GPU Delegate include la selezione di precisione: float16 riduce la precisione ma accelera l'inferenza del 30–40% senza perdita di qualità evidente (per la maggior parte dei compiti). Abilita allow_precision_loss=true per le massime prestazioni GPU. Per compiti di alta precisione (medicina, finanza), utilizza float32.
// GPU Delegate con ottimizzazione della precisione
val gpuOptions = GpuDelegateFactory.Options().apply {
isPrecisionLossAllowed = true
inferencePreference = GpuDelegateFactory.Options.InferencePreference.SUSTAINED_SPEED
}
val delegate = GpuDelegateFactory.create(gpuOptions)
GPU Delegate su iOS utilizza Metal Performance Shaders tramite Metal Delegate. Su iOS, il delegato funziona tramite il delegato Core ML per Apple Neural Engine o direttamente Metal. Apple A17 Pro esegue MobileNetV2 in 1,3 ms — 6 volte più veloce della CPU. Metal delegate è disponibile da iOS 12 e supporta tutti i dispositivi con chip A7+.
NNAPI Delegate (Android Neural Networks API) è un delegato TF Lite che utilizza l'accelerazione hardware tramite Android NN HAL (Hardware Abstraction Layer). NNAPI reindirizza le operazioni del modello a NPU, DSP o GPU a seconda dei driver disponibili del dispositivo. Supportato su Android 8.1+ (API 27+) ed è il delegato raccomandato predefinito per Android.
Vantaggio di NNAPI — selezione automatica dell'acceleratore. Se il dispositivo ha una NPU (Qualcomm Hexagon, MediaTek APU, Samsung NPU), NNAPI vi delega le operazioni. Se non c'è NPU — alla GPU tramite OpenCL. Se anche la GPU non è supportata — alla CPU con ottimizzazioni DSP. Lo sviluppatore non specifica un acceleratore particolare — NNAPI seleziona quello ottimale. Secondo Google I/O 2024, il delegato NNAPI su Snapdragon 8 Gen 3 accelera i modelli LLM di 12 volte.
Limitazioni di NNAPI: supporto disuguale su diversi dispositivi. I dispositivi più vecchi (Android 8.1) hanno un insieme limitato di driver. Huawei con Kirin non supporta NNAPI tramite Google Services — usa GPU Delegate. Per compatibilità garantita, Google raccomanda NNAPI Delegate come prima scelta, con fallback a GPU o XNNPACK.
// NNAPI Delegate con fallback CPU
val nnApiOptions = NnApiDelegate.Options().apply {
acceleratorName = null // null = selezione automatica
allowFp16 = true
executionPreference = NnApiDelegate.ExecutionPreference.SUSTAINED_SPEED
}
val delegate = NnApiDelegate(nnApiOptions)
val interpreter = Interpreter(model, Interpreter.Options().apply {
addDelegate(delegate)
setNumThreads(4)
})
Nome dell'acceleratore NNAPI — un parametro per la selezione esplicita dell'acceleratore. Se viene passato null, NNAPI seleziona automaticamente. Per i test, specificane uno concreto: "qti", "google-edgetpu", "mediatek". L'elenco degli acceleratori disponibili viene ottenuto tramite NnApiDelegate.getAvailableAccelerators(). In produzione, utilizza la selezione automatica con una soglia di compatibilità.
XNNPACK Delegate è un delegato TensorFlow Lite per l'esecuzione ottimizzata sulla CPU tramite istruzioni SIMD (ARM NEON, SSE, AVX). XNNPACK non richiede GPU o NPU — è un delegato CPU puro, ma con accelerazione di 2–4 volte grazie a SIMD, fusione di operatori, prefetching della memoria e inferenza quantizzata (INT8). Ideale per dispositivi senza NPU dedicata o quando è necessaria una compatibilità garantita.
XNNPACK è stato sviluppato da Google come delegato TF Lite predefinito per la CPU (incluso in TFLite Runtime per impostazione predefinita). Supporta 90+ operazioni — più di GPU o NNAPI. XNNPACK è particolarmente efficace per modelli quantizzati (INT8, INT16): le operazioni vengono eseguite 2–3 volte più velocemente della versione float32. Secondo i benchmark Google (2025), XNNPACK accelera INT8 MobileNetV2 di 2,8x rispetto alla CPU di base.
XNNPACK vs GPU: su dispositivi senza NPU, XNNPACK è spesso più veloce di GPU Delegate per piccoli batch (1–4) — la GPU ha overhead nel trasferimento dati tra CPU e GPU. XNNPACK opera nello stesso spazio di indirizzi della CPU — nessuna copia di memoria. Per modelli fino a 5 MB, XNNPACK può essere più veloce della GPU. Per grandi modelli CNN, la GPU vince grazie al parallelismo.
// XNNPACK Delegate abilitato per impostazione predefinita in TFLite 2.18+
// Uso esplicito tramite XnnpackDelegate
val xnnpackOptions = XnnpackDelegate.Options().apply {
numThreads = 4
flags = XnnpackDelegate.Flags.USE_XNNPACK
}
val delegate = XnnpackDelegate(xnnpackOptions)
val interpreter = Interpreter(modelBuffer, Interpreter.Options().apply {
addDelegate(delegate)
})
Flag XNNPACK: USE_XNNPACK — abilita forzatamente il delegato, FLUSH_TO_ZERO — gestisce i numeri denormalizzati per l'accelerazione, ENABLE_XNNPACK_SHAPES — dimensioni di input dinamiche. Per la massima compatibilità, utilizza le opzioni predefinite. Se si verificano errori su dispositivi più vecchi, disabilita XNNPACK — il modello funziona ancora sulla CPU ma più lentamente.
Core ML Delegate è un delegato TensorFlow Lite per iOS che utilizza Apple Core ML Framework. Core ML converte il modello TF Lite nel formato .mlmodel e lo esegue su Apple Neural Engine (ANE), GPU (Metal) o CPU. Apple A17 Pro e M3 hanno un Neural Engine dedicato che Core ML utilizza automaticamente. Core ML Delegate accelera l'inferenza di 5–10 volte rispetto alla CPU sui dispositivi iOS moderni.
Core ML su iOS supporta flex delegate (delega dinamica delle operazioni disponibili per Core ML) e conversione completa del modello (conversione dell'intero modello in .mlmodel). Apple raccomanda flex delegate — è più veloce perché funziona a runtime senza conversione preventiva. Core ML Delegate supporta modelli float32, float16 e quantizzati (INT8).
Metal Delegate è un delegato di livello inferiore che funziona direttamente con Metal Performance Shaders. Usa Metal quando Core ML non supporta operazioni specifiche. Metal Delegate fornisce il massimo controllo sulla GPU ma richiede più codice. Secondo Apple (WWDC 2024), Metal Delegate per modelli Swift nativi può essere 15–20% più veloce di Core ML a causa dell'assenza di overhead di conversione.
// Core ML Delegate su iOS tramite TFLite Swift API
import TensorFlowLite
let coreMLDelegate = CoreMLDelegate()
var options = InterpreterOptions()
options.addDelegate(coreMLDelegate)
let interpreter = try Interpreter(modelPath: modelPath, options: options)
try interpreter.invoke(at: 0)
Scelta tra Core ML e Metal: Core ML per la produzione, Metal per casi estremi. Core ML gestisce automaticamente la memoria NE, supporta il fallback sulla CPU e non richiede conversione manuale. Metal fornisce controllo sui buffer ed è adatto per operazioni personalizzate. Nei progetti IT Sectr, utilizziamo Core ML Delegate per tutti i modelli iOS e Metal solo per compiti di analisi video in tempo reale.
Scelta di un TF Lite Delegate dipende dalla piattaforma di destinazione, dal modello e dai requisiti di latenza. Non esiste un delegato universalmente migliore — ognuno ha punti di forza e debolezza. La strategia ottimale: testare tutti i delegati disponibili sul dispositivo di destinazione e scegliere il minimamente veloce — non il più veloce, ma il minimamente sufficiente.
| Delegato | Piattaforma | Accelerazione | Compatibilità |
|---|---|---|---|
| GPU | Android, iOS | 4–8x | 45 ops |
| NNAPI | Android 8.1+ | 3–12x | 60+ ops |
| XNNPACK | Android, iOS | 2–4x | 90+ ops |
| Core ML | iOS 12+ | 5–10x | 50+ ops |
Raccomandazioni per la scelta: per Android con NPU (Snapdragon 8 Gen 2+, Dimensity 9000+) — NNAPI Delegate. Per Android senza NPU — XNNPACK Delegate (predefinito). Per iOS — Core ML Delegate. Per progetti multipiattaforma, utilizza la strategia: NNAPI su Android, Core ML su iOS, XNNPACK come fallback. GPU Delegate — quando NNAPI non è disponibile e XNNPACK non è abbastanza veloce.
Test di latenza sono un passo obbligatorio nella selezione. Misura l'inferenza a temperatura minima (dispositivo freddo) e dopo 5 minuti di funzionamento continuo (thermal throttling). GPU e NNAPI possono ridurre le prestazioni quando si scaldano. XNNPACK (CPU) è meno influenzato. Utilizza TensorFlow Lite Benchmark Tool per test automatici di tutti i delegati sul tuo dispositivo.
// Strategia di selezione del delegato
fun selectDelegate(): TfLiteDelegate {
return when {
NnApiDelegate.getAvailableAccelerators()?.isNotEmpty == true ->
NnApiDelegate()
GpuDelegateFactory.isGpuDelegateAvailable() ->
GpuDelegate()
else -> XnnpackDelegate()
}
}
Strategia di fallback — carica il modello senza eccezioni: se il delegato non è supportato, esegui sulla CPU. TensorFlow Lite lancia IllegalArgumentException in caso di errore di creazione del delegato. Avvolgi la creazione del delegato in try-catch ed esegui il modello senza delegato in caso di errore. Una IA lenta ma funzionante è meglio di un errore per l'utente.
Domande Frequenti
TF Lite Delegate è un acceleratore per reti neurali su un dispositivo mobile. Invece di eseguire il modello lentamente sulla CPU, il delegato invia i calcoli alla GPU o a un neurochip specializzato (NPU). Immagina che la CPU sia uno strumento universale e il delegato una macchina specializzata per compiti specifici: fa la stessa cosa ma molto più velocemente.
Il delegato più veloce dipende dal dispositivo. Su dispositivi con Neural Engine (Apple A17 Pro, Snapdragon 8 Gen 3) — NNAPI (Android) o Core ML (iOS) forniscono accelerazione massima fino a 10–12x. GPU Delegate è il secondo più veloce. XNNPACK (CPU) è il più lento dei delegati ma il più compatibile. Su dispositivi senza NPU, XNNPACK o GPU possono essere ottimali.
No, ogni delegato supporta un insieme limitato di operazioni. GPU Delegate — 45 ops, NNAPI — 60+, XNNPACK — 90+. Le operazioni non supportate vengono eseguite sulla CPU (delega parziale). Per le operazioni personalizzate (custom ops), il delegato non viene applicato. Prima dell'uso, verifica la compatibilità tramite getDelegateOpsCount — se meno dell'80% dei nodi è delegato, scegli un altro delegato.
Aggiungi una dipendenza in build.gradle: implementation 'org.tensorflow:tensorflow-lite-gpu-delegate:+' o 'org.tensorflow:tensorflow-lite:x.x.x' (XNNPACK è integrato). Crea un delegato (GpuDelegate(), NnApiDelegate(), XnnpackDelegate()) e passalo a Interpreter.Options.addDelegate(). Esegui l'interprete — il delegato viene applicato automaticamente. Dopo l'esecuzione, chiudi il delegato tramite close().
Sì, TF Lite supporta più delegati — vengono applicati sequenzialmente. L'interprete prova a delegare un'operazione al primo delegato, poi al secondo, e così via. Se nessun delegato supporta l'operazione, viene eseguita sulla CPU. Questo è utile per il fallback: prima NNAPI, poi GPU, poi XNNPACK. L'ordine di aggiunta influisce sulla priorità.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche