← All courses

EDGE FDE

Advanced

Ship an LLM on Android and iOS with LiteRT-LM

Ship a LiteRT-LM chat feature that passes release builds and does not give users wrong answers with no error.

Conversation lifecycle, R8 keep rules, maxNumTokens vs the baked KV cache, NPU prefill loss, a CPU vs GPU parity harness, and an iOS release checklist.

Close Conversations safely, keep R8 from breaking JNI, size the context to the model file, catch silent NPU and GPU errors with a golden test, and pass the iOS release checks.

Who this is for

You have a LiteRT-LM model that answers on your test phone. Now you want to ship it to many phones. This course collects the problems that show up after that point, from real LiteRT-LM GitHub issues, and turns each one into a check you can run. Every issue link was read on 15 Oct 2026. Many are still open, so check them again before you ship.

If you are new to LiteRT, start with PyTorch to Android with LiteRT. Android code here is Kotlin. iOS code is Swift.

Lessons

  1. Close a Conversation safely
  2. Make release builds work
  3. Match maxNumTokens to the model
  4. Catch silent GPU errors with a parity test
  5. Pass the iOS release checklist

Sources we checked

Key concepts

Takeaways

Agent briefs

FAQ

Why does LiteRT-LM crash when I close a Conversation?

Issue 3771: closing during prefill can crash because the prefill callback uses a session that was already reset. Call cancelProcess(), wait for onDone or onError, then close the Conversation, then the Engine.

Why does my LiteRT-LM release build crash with mid == null?

Issue 3739: R8 removes Kotlin members that the native library looks up by name. Add -keep class com.google.ai.edge.litertlm.** { *; } to proguard-rules.pro and test the minified build on a device.

What should I set maxNumTokens to?

maxNumTokens is the KV cache size for input plus output. Use the cache length the bundle was exported with, not the model card context length, and roll the chat over before you reach it.

Why does LiteRT-LM give wrong answers on GPU but not on CPU?

Several open issues show GPU paths producing wrong text with no error, often on long prompts with float16 activations. Compare CPU, GPU float16, and GPU float32 on a golden set and allow GPU per SoC.

Does LiteRT-LM need a privacy manifest on iOS?

Issue 3863 found required-reason API use and no PrivacyInfo.xcprivacy in v0.17.1 binaries. A fix merged after v0.18.0. Scan your archive and declare any categories the binaries use.

Related courses

PyTorch to Android with LiteRT · Keep On-Device LLMs Alive on Real Phones · On-Device AI Eval Harness for CI · Core AI vs Core ML vs MLX · Core AI Fast First Token and the Right Compute Unit