On-device AI · LLM inference

Your users' conversations never leave the phone.

Run LLMs on Android with one Gradle line. Chat completion, embeddings, GGUF models — on-device, no cloud, no API key, no per-token billing. Private by design, works offline, real-time inference.

// llama.cpp · GGUF models · arm64-v8a · API 24+ · Android 15 ready · 16 KB aligned

MainActivity.kt
// load a GGUF model (downloaded separately)
val model = Llama.loadModel("qwen2.5-3b-q4_k_m.gguf")
// chat completion — on-device, no cloud
val result = Llama.complete(model,
  prompt = "Explain quantum computing simply",
  systemPrompt = "You are a helpful assistant."
)
Log.d("LLM", result.text)
Log.d("LLM", "${result.tokensPerSecond} tok/s")
On-device · no cloud · no API key GENERATED
Why on-device

Cloud LLM APIs see everything your users type.

Every prompt sent to ChatGPT, Claude, or Gemini APIs leaves the phone. For health, legal, financial, or personal use cases — that's a dealbreaker. On-device LLM runs locally: nothing uploaded, nothing stored, nothing billed per token. Private, offline, zero latency to a server.

On-device LLM · llama.cpp engine GGUF models · Llama, Qwen, Phi, Gemma, Mistral Private · conversations never leave the device Offline · no internet required No API key · no per-token billing Prebuilt .aar · no NDK, no CMake arm64-v8a · NEON optimized · 16 KB aligned Maven Central · dev.ffmpegkit-maintained
Free & Pro

Chat for free. Go Pro for GPU and streaming.

The free tier gives you full LLM inference on CPU. Pro adds Vulkan GPU acceleration (significantly faster on modern SoCs), streaming tokens via Kotlin Flow, and concurrent multi-session support.

Free MIT
$0 · Maven / JitPack / GitHub
  • llama.cpp prebuilt · CPU ARM NEON optimized
  • Chat completion (prompt → response)
  • Embeddings (text → vector)
  • System prompts + chat templates (auto-detect)
  • All GGUF models (Llama, Qwen, Phi, Gemma...)
  • arm64-v8a · single session
GPU
Pro MIT
$34 · $89 team (5)
  • Everything in Free
  • Vulkan GPU acceleration — faster on Snapdragon, Exynos, Tensor
  • Streaming tokens via Kotlin Flow (word by word)
  • JSON / Grammar mode — force structured output (GBNF)
  • Vision / Multimodal — image + text input (LLaVA, Llama Vision)
  • Context save/restore — resume conversations after app kill
  • LoRA adapters — specialize models without retraining
  • Function calling / tool use — structured agent actions
  • Concurrent multi-session (shared model, isolated KV caches)
  • arm64-v8a + x86_64 (emulators, Chromebooks)
Choose a model

Downloaded separately — pick what fits your app.

Models are not bundled in the AAR (too large, 400 MB to 8 GB). Download a GGUF model from HuggingFace and ship it with your app or download it at first launch.

Recommended models for Android
Qwen2.5 0.5B  Q4_K_M · ~400 MB  ultra-fast  · basic tasks, low RAM
Gemma 2 2B   Q4_K_M · ~1.6 GB fast      · compact and capable
Llama 3.2 3B Q4_K_M · ~2.0 GB balanced  · best for chat
Phi-3.5 Mini  Q4_K_M · ~2.2 GB slower    · high quality, needs 8+ GB RAM
// download from HuggingFace (GGUF format)
One Gradle line

No NDK. No Python. No build scripts. Just add the dependency.

The prebuilt AAR includes the compiled libllama.so and the Kotlin API. Add one line to your build file, download a model, chat.

app/build.gradle.kts
// Free — Maven Central
implementation("dev.ffmpegkit-maintained:llama-android:1.0.0")
// Free — JitPack (alternative)
implementation("com.github.ffmpegkit-maintained:llama-android:v1.0.0")
// Pro — Vulkan GPU + streaming + multi-session
implementation("dev.ffmpegkit-maintained:llama-android-pro:1.0.0")
Pro · Structured output

Force JSON output. Every time. Guaranteed.

Cloud APIs sometimes return malformed JSON. On-device LLMs are worse — unless you constrain them. Grammar mode forces the model to generate structurally valid output, defined by a GBNF grammar. JSON, XML, custom formats — if you can define it, the model will follow it.

JSON mode (Pro only)
val result = Llama.complete(model,
  prompt = "Extract: 'John is 30, lives in Montreal'",
  grammar = LlamaGrammar.json()
)
// result.text = {"name":"John","age":30,"city":"Montreal"}
// ↑ guaranteed valid JSON — parse without try/catch
Structurally valid · every time PARSED
Pro · Multimodal

Send an image. Get an answer.

With multimodal GGUF models (LLaVA, Llama 3.2 Vision), the Pro tier accepts image + text input. Describe photos, read receipts, analyze screenshots — all on-device, no cloud upload.

Vision input (Pro only)
val photo = BitmapFactory.decodeFile("receipt.jpg")
val result = Llama.complete(model,
  prompt = "What items are on this receipt?",
  image = photo
)
// result.text = "The receipt shows: 1x Coffee $4.50..."
Image understood · on-device ANALYZED
Pro · Persistence

Android killed your app. The conversation survives.

Android aggressively kills background apps to free memory. Without context persistence, every return to the app restarts the conversation from zero. Pro saves the KV cache to disk — the conversation resumes instantly, exactly where it left off.

Context persistence (Pro only)
// before app is killed
session.saveState("chat_state.bin")
// app restarts — conversation resumes instantly
session.loadState("chat_state.bin")
No re-processing · instant resume RESTORED
Pro · Streaming

Tokens arrive word by word. Just like ChatGPT.

The free tier returns the complete response at once. Pro streams tokens via Kotlin Flow — your UI updates in real time as the model generates, exactly like a cloud chat UI but running locally.

Streaming tokens (Pro only)
LlamaStreaming.stream(model, "Explain gravity")
  .collect { token ->
    textView.append(token) // updates word by word
  }
Works with Whisper

Voice assistant. Entirely on device.

Pair llama.cpp with Whisper for a complete voice AI pipeline. Whisper transcribes speech, llama.cpp generates the response, Android TTS reads it aloud. No cloud, no API, no subscription — a full assistant running on the phone.

Pipeline: Whisper → llama.cpp → TTS
// 1. Whisper: transcribe speech
val userSpeech = Whisper.transcribe(model, audioFile)
// 2. llama.cpp: generate AI response
val aiResponse = Llama.complete(llm, userSpeech.text)
// 3. Android TTS: speak the response
tts.speak(aiResponse.text, QUEUE_FLUSH, null, "reply")
Full voice assistant · 100% on-device SPEAKING