Views
No views yet
.litertlm) format for on-device inference with
Google's LiteRT-LM runtime (the
engine behind the official litert-community/* models).| File | Ministral-3-3B-Instruct-2512_q4_block32_ekv4096.litertlm (~2.3 GB; embedding externalized so every section is <2 GiB → loads on iOS) |
| Quantization | int4 weights — blockwise (block 32), symmetric, OCTAV clipping; tied embedding/lm_head at INT8 |
| Compute | integer |
| Context (KV cache) | 4096 |
| Base model | mistralai/Ministral-3-3B-Instruct-2512 (Apache-2.0) |
| Decode speed | ~17.6 tok/s (iPhone 17 Pro, Metal GPU; loads 7.6 s) · ~80 tok/s (Mac M4 Max, greedy) |
1# build litert-lm from https://github.com/google-ai-edge/litert-lm, then:
2litert_lm_main \
3 --model_path Ministral-3-3B-Instruct-2512_q4_block32_ekv4096.litertlm \
4 --backend gpu \
5 --input_prompt "Explain on-device AI in one sentence.".litertlm bundle carries the tokenizer and the prompt template (Ministral's
native Mistral [INST] … [/INST] format, stop token </s>), so no separate
tokenizer files are needed. This is a direct-answering instruct model (no <think>
block) and terminates cleanly at </s>..litertlm models fully on-device and can import your own:com.google.ai.edge.gallery, APK from the repo's
releases — 1.0.15+ supports
.litertlm). Older 1.0.x builds (package com.google.aiedge.gallery) only accept the
legacy MediaPipe .task format and reject .litertlm.Ministral-3-3B-Instruct-2512_q4_block32_ekv4096.litertlm from this repo and push it to the device:
adb push Ministral-3-3B-Instruct-2512_q4_block32_ekv4096.litertlm /sdcard/Download/.litertlm bundle already carries the
tokenizer and prompt template, so the model uses its native Mistral [INST]
chat format automatically..litertlm), which runs
comfortably and can use the GPU.com.google.ai.edge.litertlm:litertlm-android,
getting started).#### <n>,
identical prompt and answer-extraction for both rows so the only variable is the
on-device quantization:| Configuration | GSM8K |
|---|---|
| bf16 (reference) | 89.0% |
| This model — LiteRT int4 | 85.0% |
</s>). 85% is a
strong on-device GSM8K for a 3B and far above a naive min-max int4 of the same model
(blockwise-32 + OCTAV optimal-clipping is what preserves the accuracy).litert-torch using a
blockwise int4 recipe (INT4 weights, block size 32, symmetric, OCTAV
optimal-clipping) with the tied embedding/lm_head kept at INT8, KV cache 4096, and
Ministral's native Mistral chat template. Ministral-3 is a standard dense decoder
(Ministral3ForCausalLM, YaRN RoPE), so it rides the existing converter and runtime
with no custom graph code; only the text decoder is exported (the vision tower is
dropped first).externalize_embedder=True (required for iPhone). This 3B's weights would otherwise
be a single ~2.55 GiB TFLite section, which exceeds the ~2 GiB single-section mmap limit
on iOS — engine creation fails with "Failed to map section: Cannot allocate memory".
Externalizing the (tied) embedding into its own section drops the main weights section to
~1.8 GiB (and dedups the tied matrix, ~2.74 GB → 2.34 GB total), so the model loads on
iPhone (Metal GPU) as well as Android/desktop. Same weights, so GSM8K parity is
unchanged. Verified on-device: iPhone 17 Pro loads in ~7.6 s and decodes at ~17.6 tok/s on the
Metal GPU (prefill 21.9 tok/s, TTFT 0.70 s, ~1.4 GB footprint) — the previously-failing
">2 GiB section / Cannot allocate memory" mmap error no longer occurs.[INST] … [/INST] template and real EOS </s> — not
ChatML. Mistral's tekken tokenizer has no <|im_end|> token, so under a ChatML
template the int4 model never hits a registered stop token and runs away after the
correct answer. With the Mistral template it stops cleanly.litert-torch and a blockwise-32 + OCTAV int4 recipe, forcing the simple
Mistral [INST] chat template (the model's full jinja template doesn't render in the
runtime's minimal jinja engine, so the structured [INST] prefixes are extracted
instead):1EXTERNALIZE_EMBEDDER=1 CACHE=4096 python scripts/export_simple_template.py \
2 src_models/ministral3-3b-text \
3 out/ministral3-3b-boctav4 \
4 templates/mistral_simple.jinja \
5 BOCTAV4 # blockwise-32 int4 + OCTAV, int8 embeddingsministral3_int4_block32_octav.json. The text decoder is extracted from the
multimodal checkpoint with scripts/extract_ministral3_text.py (drops the vision
tower; loads with missing=0/unexpected=0).