TF Lite Delegate — to komponent TensorFlow Lite, który kieruje wykonywanie operacji sieci neuronowej na specjalistyczny sprzęt: GPU, NPU, DSP lub zoptymalizowany CPU. Bez delegata model działa na CPU w trybie pełnej zgodności — wolno, ale przewidywalnie. Delegat przyspiesza inferencję 3–10 razy w zależności od układu i modelu. Według danych TensorFlow, 2025, delegaty GPU i NNAPI zmniejszają opóźnienie inferencji o 60–90% bez znaczącej utraty dokładności.
Najważniejsze
TF Lite Delegate — to programowy adapter między TensorFlow Lite Runtime a akceleratorem sprzętowym urządzenia. Delegat przechwytuje operacje grafu modelu (sploty, pooling, mnożenie macierzy) i wykonuje je na specjalizowanym obliczeniowo układzie zamiast CPU. Jeśli delegat nie obsługuje konkretnej operacji, jest ona wykonywana na CPU — nazywa się to partial delegation.
Architektura TF Lite Delegate opiera się na interfejsie SimpleDelegate API i strukturze TfLiteDelegate w C++. Każdy delegat implementuje metody delegowania węzłów grafu, alokacji pamięci i wykonywania na docelowym urządzeniu. Programista podłącza delegat przez Interpreter::ModifyGraphWithDelegate przed wywołaniem Invoke. Według TensorFlow Guide, delegat jest stosowany automatycznie do wszystkich obsługiwanych operacji modelu.
Sprawdzanie zgodności — obowiązkowy etap. Nie wszystkie operacje są obsługiwane przez każdy delegat. TensorFlow Lite udostępnia narzędzie Delegation Compatibility Check: uruchom model z delegatem i sprawdź, ile operacji (ops) zostało zdelegowanych. Jeśli mniej niż 80% — warto wybrać inny delegat lub pozostać przy CPU. Według TensorFlow (2025), GPU Delegate obsługuje 45 operacji, NNAPI — 60+.
W projektach IT Sectr używamy delegatów GPU dla iOS i XNNPACK dla Androida z wbudowanym sprawdzaniem zgodności: model testowany jest na wszystkich delegatach, wybierany jest najszybszy z kompletnością delegacji co najmniej 90%.
// Połączenie GPU Delegate na Androidzie
val gpuDelegate = GpuDelegate()
val options = Interpreter.Options().apply {
addDelegate(gpuDelegate)
setNumThreads(4)
}
val interpreter = Interpreter(modelBuffer, options)
interpreter.run(input, output)
gpuDelegate.close()
Sprawdzanie zdelegowanych operacji — kontrola zgodności przez Interpreter. Domyślnie delegat przyjmuje wszystkie operacje, które obsługuje. Do debugowania użyj logowania liczby zdelegowanych węzłów. Jeśli model zawiera operacje niestandardowe (custom ops), delegat ich nie przyspiesza, ale też ich nie psuje — są wykonywane na CPU.
// Sprawdź liczbę zdelegowanych operacji
val delegateCount = interpreter.getDelegateOpsCount(gpuDelegate)
val totalNodes = interpreter.getNodesCount()
Log.d("TFLite", "Zdelegowano: $delegateCount / $totalNodes")
if (delegateCount < totalNodes * 0.8) {
// Próg 80% — wybierz inny delegat
}
GPU Delegate — delegat TensorFlow Lite do wykonywania modelu na GPU przez OpenGL ES 3.1+ (Android) lub Metal (iOS). Procesory graficzne są zoptymalizowane do równoległych operacji macierzowych — Core ML i splotowe sieci neuronowe (CNN) uzyskują największy przyrost. GPU Delegate zmniejsza opóźnienie inferencji 4–8 razy dla modeli takich jak MobileNet, EfficientNet, Inception.
Ograniczenia GPU Delegate: nie obsługuje wszystkich operacji (tylko 45 z ~120 w TF Lite), wymaga OpenGL ES 3.1 lub Metal, zużywa więcej energii niż CPU. GPU jest nieefektywny dla batch size > 1 w scenariuszach mobilnych. Według benchmarków TensorFlow (2025), na urządzeniu Pixel 8 z GPU Adreno 740 model MobileNetV2 działa w 4.2 ms na GPU wobec 18.7 ms na CPU — przyspieszenie 4.4x.
Konfiguracja GPU Delegate obejmuje wybór precyzji: float16 zmniejsza dokładność, ale przyspiesza inferencję o 30–40% bez zauważalnej utraty jakości (dla większości zadań). Włącz allow_precision_loss=true dla maksymalnej wydajności na GPU. Dla zadań wymagających wysokiej dokładności (medycyna, finanse) używaj float32.
// GPU Delegate z optymalizacją precyzji
val gpuOptions = GpuDelegateFactory.Options().apply {
isPrecisionLossAllowed = true
inferencePreference = GpuDelegateFactory.Options.InferencePreference.SUSTAINED_SPEED
}
val delegate = GpuDelegateFactory.create(gpuOptions)
GPU Delegate na iOS używa Metal Performance Shaders przez Metal Delegate. W iOS delegat działa przez Core ML delegate dla Apple Neural Engine lub bezpośrednio przez Metal. Apple A17 Pro wykonuje MobileNetV2 w 1.3 ms — 6 razy szybciej niż CPU. Metal delegate jest dostępny od iOS 12 i obsługuje wszystkie urządzenia z układem A7+.
NNAPI Delegate (Android Neural Networks API) — delegat TF Lite, który wykorzystuje akcelerację sprzętową przez Android NN HAL (Hardware Abstraction Layer). NNAPI kieruje operacje modelu na NPU, DSP lub GPU w zależności od dostępnych sterowników urządzenia. Obsługiwany od Android 8.1+ (API 27+) i jest zalecanym delegatem dla Androida domyślnie.
Zaleta NNAPI — automatyczny wybór akceleratora. Jeśli urządzenie ma NPU (Qualcomm Hexagon, MediaTek APU, Samsung NPU), NNAPI deleguje operacje na niego. Jeśli NPU nie ma — na GPU przez OpenCL. Jeśli GPU też nie obsługuje — na CPU z optymalizacjami DSP. Programista nie wskazuje konkretnego akceleratora — NNAPI wybiera optymalny. Według Google I/O 2024, NNAPI delegate na Snapdragon 8 Gen 3 przyspiesza modele LLM 12 razy.
Ograniczenia NNAPI: nierównomierne wsparcie na różnych urządzeniach. Stare urządzenia (Android 8.1) mają ograniczony zestaw sterowników. Huawei z Kirin nie obsługuje NNAPI przez Google Services — użyj GPU Delegate. Dla gwarantowanej zgodności Google zaleca NNAPI Delegate jako pierwszy wybór, z fallback na GPU lub XNNPACK.
// NNAPI Delegate z fallback na CPU
val nnApiOptions = NnApiDelegate.Options().apply {
acceleratorName = null // null = automatyczny wybór
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 — parametr do jawnego wyboru akceleratora. Jeśli przekażesz null, NNAPI wybiera automatycznie. Do testowania wskaż konkretny: "qti", "google-edgetpu", "mediatek". Lista dostępnych akceleratorów jest wyświetlana przez NnApiDelegate.getAvailableAccelerators(). W produkcji używaj automatycznego wyboru z progiem zgodności.
XNNPACK Delegate — delegat TensorFlow Lite do zoptymalizowanego wykonywania na CPU przez instrukcje SIMD (ARM NEON, SSE, AVX). XNNPACK nie wymaga GPU ani NPU — to czysty delegat CPU, ale z 2–4x przyspieszeniem dzięki SIMD, operator fusion, memory pre-fetching i quantized inference (INT8). Idealny dla urządzeń bez dedykowanego NPU lub gdy potrzebna jest gwarantowana zgodność.
XNNPACK został opracowany przez Google jako domyślny delegat TF Lite dla CPU (wbudowany w TFLite Runtime domyślnie). Obsługuje 90+ operacji — więcej niż GPU lub NNAPI. XNNPACK jest szczególnie efektywny dla modeli kwantyzowanych (INT8, INT16): operacje działają 2–3 razy szybciej niż wersja float32. Według benchmarków Google (2025), XNNPACK przyspiesza INT8 MobileNetV2 2.8x względem bazowego CPU.
XNNPACK vs GPU: na urządzeniach bez NPU XNNPACK często jest szybszy niż GPU Delegate dla małych batchy (1–4) — GPU ma narzut na przesyłanie danych między CPU a GPU. XNNPACK działa w tej samej przestrzeni adresowej CPU — nie ma kopiowania pamięci. Dla modeli do 5MB XNNPACK może być szybszy niż GPU. Dla dużych modeli CNN GPU wygrywa dzięki równoległości.
// XNNPACK Delegate włączony domyślnie w TFLite 2.18+
// Jawne użycie przez 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 — wymusza włączenie delegata, FLUSH_TO_ZERO — obsługa liczb zdenormalizowanych dla przyspieszenia, ENABLE_XNNPACK_SHAPES — dynamiczne rozmiary wejścia. Dla maksymalnej zgodności używaj domyślnych opcji. W przypadku błędów na starych urządzeniach wyłącz XNNPACK — model nadal działa na CPU, ale wolniej.
Core ML Delegate — delegat TensorFlow Lite dla iOS, wykorzystujący Apple Core ML Framework. Core ML konwertuje model TF Lite do formatu .mlmodel i wykonuje na Apple Neural Engine (ANE), GPU (Metal) lub CPU. Apple A17 Pro i M3 mają dedykowany Neural Engine, który Core ML wykorzystuje automatycznie. Core ML Delegate przyspiesza inferencję 5–10 razy względem CPU na nowoczesnych urządzeniach iOS.
Core ML na iOS obsługuje flex delegate (dynamiczne delegowanie operacji dostępnych w Core ML) i full model conversion (konwersja całego modelu do .mlmodel). Apple zaleca flex delegate — jest szybszy, ponieważ działa w czasie wykonania bez wcześniejszej konwersji. Core ML Delegate obsługuje modele float32, float16 i kwantyzowane (INT8).
Metal Delegate — delegat niższego poziomu, działający bezpośrednio z Metal Performance Shaders. Używaj Metal, gdy Core ML nie obsługuje poszczególnych operacji. Metal Delegate daje maksymalną kontrolę nad GPU, ale wymaga więcej kodu. Według Apple (WWDC 2024), Metal Delegate dla natywnych modeli Swift może być o 15–20% szybszy niż Core ML z powodu braku narzutu konwersji.
// Core ML Delegate na iOS przez 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)
Wybór między Core ML a Metal: Core ML — do produkcji, Metal — do przypadków brzegowych. Core ML automatycznie zarządza pamięcią NE, obsługuje spadek na CPU (fallback) i nie wymaga ręcznej konwersji. Metal daje kontrolę nad buforami i nadaje się do niestandardowych operacji. W projektach IT Sectr używamy Core ML Delegate dla wszystkich modeli iOS, a Metal tylko do zadań analizy wideo w czasie rzeczywistym.
Wybór TF Lite Delegate zależy od docelowej platformy, modelu i wymagań dotyczących opóźnienia. Nie ma uniwersalnego najlepszego delegata — każdy ma mocne i słabe strony. Optymalna strategia: testuj wszystkie dostępne delegaty na docelowym urządzeniu i wybierz minimalnie wystarczająco szybki — nie najszybszy, ale minimalnie wystarczający.
| Delegat | Platforma | Przyspieszenie | Zgodność |
|---|---|---|---|
| GPU | Android, iOS | 4–8x | 45 operacji |
| NNAPI | Android 8.1+ | 3–12x | 60+ operacji |
| XNNPACK | Android, iOS | 2–4x | 90+ operacji |
| Core ML | iOS 12+ | 5–10x | 50+ operacji |
Zalecenia dotyczące wyboru: dla Androida z NPU (Snapdragon 8 Gen 2+, Dimensity 9000+) — NNAPI Delegate. Dla Androida bez NPU — XNNPACK Delegate (domyślny). Dla iOS — Core ML Delegate. Dla projektów wieloplatformowych użyj strategii: NNAPI na Androidzie, Core ML na iOS, XNNPACK jako fallback. GPU Delegate — gdy NNAPI jest niedostępny, a XNNPACK jest niewystarczająco szybki.
Testowanie opóźnienia — obowiązkowy etap wyboru. Zmierz inferencję na minimalnej temperaturze (urządzenie zimne) i po 5 minutach ciągłej pracy (thermal throttling). GPU i NNAPI mogą obniżać wydajność przy nagrzewaniu. XNNPACK (CPU) cierpi mniej. Użyj TensorFlow Lite Benchmark Tool do automatycznego testowania wszystkich delegatów na twoim urządzeniu.
// Strategia wyboru delegata
fun selectDelegate(): TfLiteDelegate {
return when {
NnApiDelegate.getAvailableAccelerators()?.isNotEmpty == true ->
NnApiDelegate()
GpuDelegateFactory.isGpuDelegateAvailable() ->
GpuDelegate()
else -> XnnpackDelegate()
}
}
Strategia fallback — ładuj model bez wyjątków: jeśli delegat nie jest obsługiwany, uruchom na CPU. TensorFlow Lite zgłasza IllegalArgumentException przy błędzie tworzenia delegata. Owiń tworzenie delegata w try-catch i przy błędzie uruchom model bez delegata. Wolny, ale działający AI jest lepszy niż błąd dla użytkownika.
Często zadawane pytania
TF Lite Delegate — to akcelerator dla sieci neuronowych na urządzeniu mobilnym. Zamiast wykonywać model wolno na CPU, delegat wysyła obliczenia na GPU lub specjalny układ neuronowy (NPU). Wyobraź sobie, że CPU to uniwersalne narzędzie, a delegat to specjalistyczna maszyna do konkretnych zadań: robi to samo, ale wielokrotnie szybciej.
Najszybszy delegat zależy od urządzenia. Na urządzeniach z Neural Engine (Apple A17 Pro, Snapdragon 8 Gen 3) — NNAPI (Android) lub Core ML (iOS) dają maksymalne przyspieszenie do 10–12x. GPU Delegate jest drugi pod względem szybkości. XNNPACK (CPU) jest najwolniejszym z delegatów, ale najbardziej zgodnym. Na urządzeniach bez NPU XNNPACK lub GPU mogą być optymalne.
Nie, każdy delegat obsługuje ograniczony zestaw operacji. GPU Delegate — 45 operacji, NNAPI — 60+, XNNPACK — 90+. Nieobsługiwane operacje są wykonywane na CPU (partial delegation). Dla operacji niestandardowych (custom ops) delegat nie jest stosowany. Przed użyciem sprawdź zgodność przez getDelegateOpsCount — jeśli zdelegowano mniej niż 80% węzłów, wybierz inny delegat.
Dodaj zależność w build.gradle: implementation 'org.tensorflow:tensorflow-lite-gpu-delegate:+' lub 'org.tensorflow:tensorflow-lite:x.x.x' (XNNPACK wbudowany). Utwórz delegat (GpuDelegate(), NnApiDelegate(), XnnpackDelegate()) i przekaż do Interpreter.Options.addDelegate(). Uruchom interpreter — delegat stosuje się automatycznie. Po wykonaniu zamknij delegat przez close().
Tak, TF Lite obsługuje multiple delegates — są stosowane sekwencyjnie. Interpreter próbuje delegować operację pierwszemu delegatowi, potem drugiemu i tak dalej. Jeśli żaden delegat nie obsługuje operacji — jest wykonywana na CPU. Jest to przydatne dla fallback: najpierw NNAPI, potem GPU, potem XNNPACK. Kolejność dodawania wpływa na priorytet.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również