Views
No views yet
.litertlm format for Google's
LiteRT-LM runtime
(Android / iOS / desktop / embedded).| File | Thinking | Best for |
|---|---|---|
qwen3_0.6b_q4_block32_ekv1280.litertlm | ON (default Qwen3) | quality / reasoning; emits <think>…</think> then the answer |
qwen3_0.6b_nothink_q4_block32_ekv1280.litertlm | OFF | fast, short, direct answers — ~2× quicker on a CPU backend; no chain-of-thought to filter out |
enable_thinking, it stays controllable).<think></think> into the
assistant turn, so the model answers directly. This was built for a wearable
health-assistant where a phone streams short replies to a watch.litert-torch
(the generative API, formerly ai-edge-torch) from the original PyTorch checkpoint.| Setting | Value |
|---|---|
| Source checkpoint | Qwen/Qwen3-0.6B (bf16) |
| Quantization | dynamic_int4_block32 (INT4 weights, block size 32, fp32 activations) |
| Size | ~2.2 GiB → 329 MiB (≈6.9× smaller) |
| Prefill signatures | 8, 64, 128, 256, 512, 1024 (runtime picks the smallest that fits) |
| KV cache max length | 1280 |
| KV layout | transposed · mask_as_input=true |
| Stop tokens | 151645 (`< |
| Tokenizer | bundled from tokenizer.json |
Multiple prefill signatures matter for latency: with a single large signature every prompt is padded to it. The exponential set above lets a short prompt run a tiny prefill instead of always paying the 1024-token cost.
<|im_start|>user
{user message}<|im_end|>
<|im_start|>assistant
<think>
</think>
{answer}<|im_end|>1val engine = Engine(
2 EngineConfig(
3 modelPath = "/path/to/qwen3_0.6b_nothink_q4_block32_ekv1280.litertlm",
4 backend = Backend.CPU(),
5 cacheDir = context.cacheDir.absolutePath,
6 )
7).apply { initialize() }
8
9val conversation = engine.createConversation(
10 ConversationConfig(
11 systemInstruction = Contents.of("You are a helpful, concise assistant."),
12 samplerConfig = SamplerConfig(temperature = 0.8, topK = 40, topP = 0.9),
13 )
14)
15
16conversation.sendMessageAsync("How did I sleep last night?")
17 .collect { msg -> /* stream text */ }<think>…</think> block before display.1import json
2from litert_torch.generative.examples.qwen import qwen3
3from litert_torch.generative.utilities import converter, export_config as ec_lib
4from litert_torch.generative.layers import kv_cache as kv_utils
5
6CKPT = "Qwen3-0.6B" # local HF snapshot
7ec = ec_lib.ExportConfig()
8ec.kvcache_layout = kv_utils.KV_LAYOUT_TRANSPOSED
9ec.mask_as_input = True
10
11common = dict(
12 output_path=".",
13 prefill_seq_len=[8, 64, 128, 256, 512, 1024],
14 kv_cache_max_len=1280,
15 quantize="dynamic_int4_block32",
16 export_config=ec,
17 output_format="litertlm",
18 hf_tokenizer_model_path=f"{CKPT}/tokenizer.json",
19 stop_token_ids=[151645, 151643],
20)
21
22# Standard (thinking on): bake the Qwen3 Jinja template
23tpl = json.load(open(f"{CKPT}/tokenizer_config.json"))["chat_template"]
24converter.convert_to_litert(
25 qwen3.build_0_6b_model(CKPT), output_name_prefix="qwen3_0.6b",
26 jinja_prompt_template=tpl, **common)
27
28# No-think: prefill a closed empty think block in the assistant turn
29converter.convert_to_litert(
30 qwen3.build_0_6b_model(CKPT), output_name_prefix="qwen3_0.6b_nothink",
31 user_prompt_prefix="<|im_start|>user\n", user_prompt_suffix="<|im_end|>\n",
32 model_prompt_prefix="<|im_start|>assistant\n<think>\n\n</think>\n\n",
33 model_prompt_suffix="<|im_end|>\n", **common)Qwen/Qwen3-0.6B; see the
Qwen3 technical report for that model's
pretraining data.Qwen/Qwen3-0.6B.