TF Lite Delegate: what it is, GPU and NNAPI delegates

Author: IT Sectr Published: 2026-07-18 Reading time: 10 min

TF Lite Delegate is a TensorFlow Lite component that redirects neural network operations to specialized hardware: GPU, NPU, DSP, or optimized CPU. Without a delegate, the model runs on the CPU in full compatibility mode — slow but predictable. The delegate speeds up inference by 3–10x depending on the chip and model. According to TensorFlow, 2025, GPU and NNAPI delegates reduce inference latency by 60–90% without significant loss of accuracy.

Key Takeaways

  • TF Lite Delegate — a hardware acceleration layer for TensorFlow Lite models
  • GPU Delegate — accelerates floating-point operations via OpenGL/Metal
  • NNAPI Delegate — uses Android Neural Networks API for NPU and DSP
  • XNNPACK Delegate — CPU optimization via SIMD instructions (ARM NEON, SSE)
  • Core ML Delegate — native integration with Apple Neural Engine on iOS

What is TF Lite Delegate: architecture and how it works

TF Lite Delegate is a software adapter between TensorFlow Lite Runtime and the device's hardware accelerator. The delegate intercepts model graph operations (convolutions, pooling, matrix multiplications) and executes them on a specialized compute unit instead of the CPU. If the delegate does not support a particular operation, it runs on the CPU — this is called partial delegation.

TF Lite Delegate Architecture is built around the SimpleDelegate API interface and the TfLiteDelegate structure in C++. Each delegate implements methods for delegating graph nodes, memory allocation, and execution on the target device. The developer connects the delegate via Interpreter::ModifyGraphWithDelegate before calling Invoke. According to the TensorFlow Guide, the delegate is applied to all supported model operations automatically.

Compatibility check is a mandatory step. Not all operations are supported by every delegate. TensorFlow Lite provides the Delegation Compatibility Check tool: run the model with the delegate and check how many operations (ops) are delegated. If less than 80% are delegated, consider choosing another delegate or sticking with CPU. According to TensorFlow (2025), GPU Delegate supports 45 operations, NNAPI — 60+.

At IT Sectr projects, we use GPU delegates for iOS and XNNPACK for Android with built-in compatibility verification: the model is tested on all delegates, selecting the fastest one with at least 90% delegation completeness.

kotlin
// GPU Delegate connection on Android
val gpuDelegate = GpuDelegate()
val options = Interpreter.Options().apply {
    addDelegate(gpuDelegate)
    setNumThreads(4)
}
val interpreter = Interpreter(modelBuffer, options)
interpreter.run(input, output)
gpuDelegate.close()

Checking delegated operations — compatibility control via Interpreter. By default, the delegate accepts all operations it supports. For debugging, use logging of the delegated node count. If the model contains custom ops, the delegate does not accelerate them but does not break them either — they run on the CPU.

kotlin
// Check delegated operations count
val delegateCount = interpreter.getDelegateOpsCount(gpuDelegate)
val totalNodes = interpreter.getNodesCount()
Log.d("TFLite", "Delegated: $delegateCount / $totalNodes")
if (delegateCount < totalNodes * 0.8) {
    // 80% threshold — choose another delegate
}

GPU Delegate: acceleration on the graphics processor

GPU Delegate is a TensorFlow Lite delegate for running models on the GPU via OpenGL ES 3.1+ (Android) or Metal (iOS). Graphics processors are optimized for parallel matrix operations — Core ML and convolutional neural networks (CNN) benefit the most. GPU Delegate reduces inference latency by 4–8x for models like MobileNet, EfficientNet, Inception.

GPU Delegate limitations: does not support all operations (only 45 out of ~120 in TF Lite), requires OpenGL ES 3.1 or Metal, consumes more power than CPU. GPU is inefficient for batch size > 1 in mobile scenarios. According to TensorFlow benchmarks (2025), on Pixel 8 with Adreno 740 GPU, MobileNetV2 runs in 4.2 ms on GPU vs 18.7 ms on CPU — a 4.4x acceleration.

GPU Delegate configuration includes precision selection: float16 reduces accuracy but speeds up inference by 30–40% without noticeable quality loss (for most tasks). Enable allow_precision_loss=true for maximum GPU performance. For high-precision tasks (medical, finance), use float32.

kotlin
// GPU Delegate with precision optimization
val gpuOptions = GpuDelegateFactory.Options().apply {
    isPrecisionLossAllowed = true
    inferencePreference = GpuDelegateFactory.Options.InferencePreference.SUSTAINED_SPEED
}
val delegate = GpuDelegateFactory.create(gpuOptions)

GPU Delegate on iOS uses Metal Performance Shaders via Metal Delegate. On iOS, the delegate works through Core ML delegate for Apple Neural Engine or Metal directly. Apple A17 Pro runs MobileNetV2 in 1.3 ms — 6x faster than CPU. Metal delegate is available since iOS 12 and supports all devices with A7+ chips.

NNAPI Delegate: neural networks on Android via Neural Networks API

NNAPI Delegate (Android Neural Networks API) is a TF Lite delegate that uses hardware acceleration through Android NN HAL (Hardware Abstraction Layer). NNAPI redirects model operations to NPU, DSP, or GPU depending on the available device drivers. Supported on Android 8.1+ (API 27+) and is the recommended default delegate for Android.

NNAPI advantage — automatic accelerator selection. If the device has an NPU (Qualcomm Hexagon, MediaTek APU, Samsung NPU), NNAPI delegates operations to it. If no NPU — to GPU via OpenCL. If GPU is also unsupported — to CPU with DSP optimizations. The developer does not specify a particular accelerator — NNAPI selects the optimal one. According to Google I/O 2024, the NNAPI delegate on Snapdragon 8 Gen 3 accelerates LLM models by 12x.

NNAPI limitations: uneven support across devices. Older devices (Android 8.1) have a limited set of drivers. Huawei with Kirin does not support NNAPI through Google Services — use GPU Delegate. For guaranteed compatibility, Google recommends NNAPI Delegate as the first choice, with a fallback to GPU or XNNPACK.

kotlin
// NNAPI Delegate with CPU fallback
val nnApiOptions = NnApiDelegate.Options().apply {
    acceleratorName = null // null = auto-select
    allowFp16 = true
    executionPreference = NnApiDelegate.ExecutionPreference.SUSTAINED_SPEED
}
val delegate = NnApiDelegate(nnApiOptions)
val interpreter = Interpreter(model, Interpreter.Options().apply {
    addDelegate(delegate)
    setNumThreads(4)
})

NNAPI Accelerator Name — a parameter for explicit accelerator selection. If null is passed, NNAPI selects automatically. For testing, specify a specific one: "qti", "google-edgetpu", "mediatek". The list of available accelerators is output via NnApiDelegate.getAvailableAccelerators(). In production, use auto-selection with a compatibility threshold.

XNNPACK Delegate: CPU optimization via SIMD

XNNPACK Delegate is a TensorFlow Lite delegate for optimized CPU execution via SIMD instructions (ARM NEON, SSE, AVX). XNNPACK does not require GPU or NPU — it is a pure CPU delegate, but with 2–4x acceleration through SIMD, operator fusion, memory pre-fetching, and quantized inference (INT8). Ideal for devices without a dedicated NPU or when guaranteed compatibility is needed.

XNNPACK was developed by Google as the default TF Lite delegate for CPU (included in TFLite Runtime by default). It supports 90+ operations — more than GPU or NNAPI. XNNPACK is especially effective for quantized models (INT8, INT16): operations run 2–3x faster than the float32 version. According to Google benchmarks (2025), XNNPACK accelerates INT8 MobileNetV2 by 2.8x relative to baseline CPU.

XNNPACK vs GPU: on devices without NPU, XNNPACK is often faster than GPU Delegate for small batch (1–4) — GPU has overhead on data transfer between CPU and GPU. XNNPACK operates in the same CPU address space — no memory copying. For models up to 5MB, XNNPACK can be faster than GPU. For large CNN models, GPU wins due to parallelism.

kotlin
// XNNPACK Delegate enabled by default in TFLite 2.18+
// Explicit usage via 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)
})

XNNPACK Flags: USE_XNNPACK — forcibly enables the delegate, FLUSH_TO_ZERO — handles denormalized numbers for acceleration, ENABLE_XNNPACK_SHAPES — dynamic input sizes. For maximum compatibility, use default options. If errors occur on older devices, disable XNNPACK — the model still runs on CPU but slower.

Core ML and Metal Delegate: acceleration on iOS

Core ML Delegate is a TensorFlow Lite delegate for iOS that uses Apple Core ML Framework. Core ML converts the TF Lite model to .mlmodel format and executes it on Apple Neural Engine (ANE), GPU (Metal), or CPU. Apple A17 Pro and M3 have a dedicated Neural Engine that Core ML uses automatically. Core ML Delegate accelerates inference by 5–10x compared to CPU on modern iOS devices.

Core ML on iOS supports flex delegate (dynamic delegation of operations available to Core ML) and full model conversion (converting the entire model to .mlmodel). Apple recommends flex delegate — it is faster as it works at runtime without prior conversion. Core ML Delegate supports float32, float16, and quantized models (INT8).

Metal Delegate is a lower-level delegate that works directly with Metal Performance Shaders. Use Metal when Core ML does not support certain operations. Metal Delegate provides maximum GPU control but requires more code. According to Apple (WWDC 2024), Metal Delegate for native Swift models can be 15–20% faster than Core ML due to no conversion overhead.

swift
// Core ML Delegate on iOS via 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)

Choosing between Core ML and Metal: Core ML for production, Metal for edge cases. Core ML automatically manages NE memory, supports CPU fallback, and does not require manual conversion. Metal provides buffer control and is suitable for custom operations. At IT Sectr projects, we use Core ML Delegate for all iOS models and Metal only for real-time video analytics tasks.

How to choose a delegate for your project

Choosing a TF Lite Delegate depends on the target platform, model, and latency requirements. There is no universal best delegate — each has strengths and weaknesses. The optimal strategy: test all available delegates on the target device and choose the minimally fast one — not the fastest, but minimally sufficient.

DelegatePlatformAccelerationCompatibility
GPUAndroid, iOS4–8x45 ops
NNAPIAndroid 8.1+3–12x60+ ops
XNNPACKAndroid, iOS2–4x90+ ops
Core MLiOS 12+5–10x50+ ops

Recommendations by choice: for Android with NPU (Snapdragon 8 Gen 2+, Dimensity 9000+) — NNAPI Delegate. For Android without NPU — XNNPACK Delegate (default). For iOS — Core ML Delegate. For cross-platform projects, use the strategy: NNAPI on Android, Core ML on iOS, XNNPACK as fallback. GPU Delegate — when NNAPI is unavailable and XNNPACK is not fast enough.

Latency testing is a mandatory selection step. Measure inference at minimum temperature (cold device) and after 5 minutes of continuous operation (thermal throttling). GPU and NNAPI may degrade performance when heated. XNNPACK (CPU) is less affected. Use TensorFlow Lite Benchmark Tool for automatic testing of all delegates on your device.

kotlin
// Delegate selection strategy
fun selectDelegate(): TfLiteDelegate {
    return when {
        NnApiDelegate.getAvailableAccelerators()?.isNotEmpty == true ->
            NnApiDelegate()
        GpuDelegateFactory.isGpuDelegateAvailable() ->
            GpuDelegate()
        else -> XnnpackDelegate()
    }
}

Fallback strategy — load the model without exceptions: if the delegate is not supported, run on CPU. TensorFlow Lite throws IllegalArgumentException on delegate creation error. Wrap delegate creation in try-catch and run the model without delegate on error. Slow but working AI is better than an error for the user.

Frequently Asked Questions

What is TF Lite Delegate in simple terms?

TF Lite Delegate is an accelerator for neural networks on a mobile device. Instead of running the model slowly on the CPU, the delegate sends computations to the GPU or a specialized neural chip (NPU). Think of the CPU as a universal tool and the delegate as a specialized machine for specific tasks: it does the same thing but many times faster.

Which TF Lite delegate is the fastest?

The fastest delegate depends on the device. On devices with Neural Engine (Apple A17 Pro, Snapdragon 8 Gen 3) — NNAPI (Android) or Core ML (iOS) provide maximum acceleration up to 10–12x. GPU Delegate is second fastest. XNNPACK (CPU) is the slowest among delegates but the most compatible. On devices without NPU, XNNPACK or GPU may be optimal.

Does TF Lite Delegate support all operations?

No, each delegate supports a limited set of operations. GPU Delegate — 45 ops, NNAPI — 60+, XNNPACK — 90+. Unsupported operations run on CPU (partial delegation). For custom ops, the delegate is not applied. Before use, check compatibility via getDelegateOpsCount — if less than 80% of nodes are delegated, choose another delegate.

How to set up TF Lite Delegate on Android?

Add a dependency to build.gradle: implementation 'org.tensorflow:tensorflow-lite-gpu-delegate:+' or 'org.tensorflow:tensorflow-lite:x.x.x' (XNNPACK is built-in). Create a delegate (GpuDelegate(), NnApiDelegate(), XnnpackDelegate()) and pass it to Interpreter.Options.addDelegate(). Run the interpreter — the delegate is applied automatically. After execution, close the delegate via close().

Can multiple delegates be used simultaneously?

Yes, TF Lite supports multiple delegates — they are applied sequentially. The interpreter tries to delegate an operation to the first delegate, then the second, and so on. If no delegate supports the operation, it runs on CPU. This is useful for fallback: first NNAPI, then GPU, then XNNPACK. The order of addition affects priority.

Summary

  • TF Lite Delegate — hardware accelerator for TensorFlow Lite models on mobile devices
  • GPU Delegate — acceleration via OpenGL ES (Android) or Metal (iOS), 4–8x faster than CPU
  • NNAPI Delegate — via Android Neural Networks API, uses NPU/DSP/GPU, 3–12x
  • XNNPACK Delegate — CPU optimization via SIMD, 2–4x, maximum compatibility (90+ ops)
  • Core ML Delegate — iOS acceleration via Neural Engine and Metal, 5–10x
  • Delegate selection — test on the target device, use CPU fallback
  • Partial delegation — unsupported operations run on CPU automatically

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also