TensorFlow Lite: Deploying on Mobile
TensorFlow Lite: Deploying on Mobile
A model that runs beautifully on a desktop GPU is not automatically usable on a phone. Mobile devices have limited memory, limited compute, and battery constraints that desktop training never has to consider. TensorFlow Lite (TFLite) is the toolkit built specifically to shrink and run TensorFlow models efficiently on mobile and embedded hardware.
Introduction to TensorFlow Lite
TensorFlow Lite is a lightweight runtime designed for on-device inference. Instead of sending user data to a server and waiting for a response, a TFLite model runs directly on the device, which gives you three big advantages:
• Lower latency: predictions happen instantly, with no network round-trip.
• Offline capability: the app works even with no internet connection.
• Better privacy: sensitive data, like camera frames or voice recordings, never has to leave the device.
The trade-off is that mobile hardware is far more constrained than a training server, so TFLite focuses heavily on making models smaller and faster, sometimes at a small cost in accuracy.
Converting Models to TFLite Format
The TFLite Converter takes a trained Keras or SavedModel and converts it into a .tflite FlatBuffer file, a compact binary format optimised for fast loading and low memory overhead.
import tensorflow as tf
# Starting from a trained Keras model
model = tf.keras.models.load_model('my_model.h5')
converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()
with open('model.tflite', 'wb') as f:
f.write(tflite_model)
You can also convert directly from a SavedModel directory, which is the more common path in production pipelines:
converter = tf.lite.TFLiteConverter.from_saved_model('saved_model_dir')
tflite_model = converter.convert()
Model Quantization
Quantization reduces the precision used to store and compute weights, typically from 32-bit floats down to 8-bit integers. This shrinks the model size by roughly 4x and speeds up inference, since integer arithmetic is cheaper than floating-point arithmetic on most mobile CPUs.
Quantization Type | What Changes | Trade-off |
Dynamic range | Weights quantized to int8; activations stay float, quantized at inference time | Easy to apply, modest speedup, minimal accuracy loss |
Full integer | Both weights and activations quantized to int8 | Best performance and size reduction, requires a representative dataset |
Float16 | Weights stored as 16-bit floats instead of 32-bit | Halves model size, GPU-friendly, smaller accuracy impact than int8 |
converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
# Full integer quantization needs a representative dataset
def representative_dataset():
for sample in x_train[:500]:
yield [sample.reshape(1, 784).astype('float32')]
converter.representative_dataset = representative_dataset
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
tflite_quant_model = converter.convert()
The representative dataset is used to calibrate the quantization ranges, TFLite observes the typical range of activation values on real samples so it can choose integer scales that minimise information loss.
Running Inference on Android
On Android, the TFLite Interpreter loads the .tflite file and runs predictions using Kotlin or Java. The model file is typically placed in the app's assets folder.
// Kotlin
val model = FileUtil.loadMappedFile(context, "model.tflite")
val interpreter = Interpreter(model)
val input = arrayOf(floatArrayOf(/* 784 normalised pixel values */))
val output = Array(1) { FloatArray(10) }
interpreter.run(input, output)
val predictedClass = output[0].indices.maxByOrNull { output[0][it] }
println("Predicted digit: $predictedClass")
For common tasks like image classification or object detection, the TFLite Task Library wraps this boilerplate into a few lines, handling input pre-processing and output parsing automatically.
Running Inference on iOS
On iOS, the same .tflite file is loaded through the TensorFlowLiteSwift pod, with a near-identical API shape to the Android interpreter.
// Swift
import TensorFlowLite
let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite")!
let interpreter = try Interpreter(modelPath: modelPath)
try interpreter.allocateTensors()
let inputData = Data(copyingBufferOf: inputPixels)
try interpreter.copy(inputData, toInputAt: 0)
try interpreter.invoke()
let outputTensor = try interpreter.output(at: 0)
let probabilities = outputTensor.data.toArray(type: Float32.self)
Quick Tip
Both platforms support hardware delegates, GPU delegate, NNAPI on Android, and Core ML delegate on iOS, that offload computation to specialised hardware. Enabling a delegate can speed up inference significantly with no changes to the model itself.










