Downloads · 30 days
892
65% of all-time downloads
litert-community/Spark-X2.5-4B
Spark-X2.5-4B is a text generation model from litert-community. Use it when you need the model to write or continue text. It is set up for litert-lm. The card lists the license as apache-2.0.
Measured on device (edge-compat, spark-x2.5-4b-int4): Galaxy S26 · LiteRT-LM 0.16.0 · GPU · decode 4.9 tok/s · prefill 56 tok/s · TTFT 3.98 s · all 2233 ops delegated (2026-09-07); Mac Studio M4 Max · LiteRT-LM 0.17.0…
Downloads · 30 days
892
65% of all-time downloads
All-time downloads
1.4K
Public
Repo size
13.4 GB
Likes
5
Public
Click a slice to open those files.
.litertlm6.7 GB · 100%
From the Hugging Face model README
Measured on device (edge-compat, spark-x2.5-4b-int4): Galaxy S26 · LiteRT-LM 0.16.0 · GPU · decode 4.9 tok/s · prefill 56 tok/s · TTFT 3.98 s · all 2233 ops delegated (2026-09-07); Mac Studio M4 Max · LiteRT-LM 0.17.0 · GPU · decode 53.6 tok/s · prefill 826 tok/s · TTFT 329 ms (2026-09-07); Galaxy S26 · LiteRT-LM 0.16.0 · CPU · decode 5.5 tok/s · prefill 35 tok/s · TTFT 6.31 s (2026-09-07). Record: https://github.com/john-rocky/edge-compat/blob/main/cards/spark-x2.5-4b-int4/CARD.md
Measured on device (edge-compat, spark-x2.5-4b-int8): Mac Studio M4 Max · LiteRT-LM 0.17.0 · GPU · decode 49.4 tok/s · prefill 784 tok/s · TTFT 347 ms (2026-09-07); Galaxy S26 · LiteRT-LM 0.16.0 · CPU · decode 4.5 tok/s · prefill 65 tok/s · TTFT 3.49 s (2026-09-07); Mac Studio M4 Max · LiteRT-LM 0.17.0 · CPU · decode 19.5 tok/s · prefill 345 tok/s · TTFT 792 ms (2026-09-07). Record: https://github.com/john-rocky/edge-compat/blob/main/cards/spark-x2.5-4b-int8/CARD.md
XHToken/Spark-X2.5-4B converted to the LiteRT-LM (.litertlm) format for on-device inference with Google's LiteRT-LM runtime. Tested on litert-lm 0.17.0.
Spark-X2.5 is the SparkLLM Team's (iFLYTEK) open model series released in August 2026 — a 4.11B dense decoder (36 layers, hidden 2560, 16 query / 4 KV heads of 256, sliding-window(512) x3 : full x1, 131,072-entry tied vocab) with a hybrid attention layout of three sliding-window layers per full-attention layer, per-head sigmoid attention-output gates, exact-GELU gated MLPs and a native 1M-token context in the original. It is a reasoning model: it works problems inside <think>…</think> before answering, and these bundles carry that machinery — the generation prompt pre-fills the think opener exactly as the vendor chat template does, and a thought channel is declared in the bundle metadata so the runtime separates reasoning from the answer and honours a thinking budget. Apache-2.0.
| File | Recipe | Size |
|---|---|---|
Spark-X2.5-4B_int8.litertlm | int8 dynamic on linears + embedding | 4238 MB |
Spark-X2.5-4B_int4.litertlm | int4 blockwise-128 + OCTAV on linears, int8 embedding (externalized) | 2482 MB |
2026-09-21: chat template updated to accept the 0.18 content-parts form (string form unchanged); weights, tokenizer and executor metadata byte-identical.
Both files are at bf16 parity on GSM8K (94 = 94 = 94) — with fp32 GPU activations declared in the bundle (under the runtime's default fp16 GPU activations the same int8 weights scored 84; see Conversion notes). int4 (block-128) is the recommended file: same accuracy, 41% smaller (2.48 GB), and the faster GPU file on the Mac (53.6 vs 49.4 tok/s decode). int8 (4.24 GB) is the CPU-prefill file (345 vs 118 tok/s on the Mac CPU). On the Galaxy S26 this 4B is a ~5 tok/s model on every measured path — the fp32-activation OpenCL path does not beat the CPU there (int4: GPU 4.9 vs CPU 5.5–5.6 tok/s decode) but halves peak memory (2.0 vs 3.5 GB); pick by memory, not speed.
tokenizer.json, byte-level BPE) encodes 234 of 234 probe rows — every added token alone and mid-string, the role-marker turn, Latin-1 / Extended-A, emoji, CJK, digits, whitespace — to the same ids as the tokenizers reading of the upstream file.GSM8K, greedy, 0-shot chain-of-thought, 3584 output tokens (a reasoning model truncated mid-thought never reaches its answer; 2048 cut a third of the bf16 model's first questions), n=100, identical prompt, harness and answer extraction for every row; the LiteRT rows ran on the litert-lm 0.17.0 engine (GPU backend), scored on the text after the thought channel:
| Configuration | GSM8K |
|---|---|
| PyTorch bf16 (reference, MPS) | 94% (6 unfinished at the 3584-token cap) |
| LiteRT int8 | 94% (7 unfinished at the 3584-token cap) |
| LiteRT int4 | 94% (7 unfinished at the 3584-token cap) |
litert-lm run ./Spark-X2.5-4B_int8.litertlm --prompt "What is the capital of France? Answer in one word." --thinking true
# GPU
litert-lm run ./Spark-X2.5-4B_int8.litertlm --backend gpu --cache no --thinking true --prompt "..."
Notes for a reasoning model:
thought channel (<think> … </think>), so runtimes that expose ThinkingConfig / a thinking budget can cap or read the reasoning separately; the streamed answer contains only the final response. enable_thinking: false renders the vendor's no-think form (<|Bot|></think>).<|System|>\nyou are a helpful assistant., a user system prompt appended after it), every message wrapped in <|start▁of▁sentence|> … <|end▁of▁sentence|>, generation prompt <|Bot|><think>; stop token <|end▁of▁sentence|>. Tool-call formatting is not carried. KV budget 4096 tokens (the original's 1M context does not apply on-device), six prefill signatures (1024, 256, 64, 16, 4, 1) — six rather than eleven because every exported signature is charged engine memory whether or not it is called.Apple M4 Max (litert-lm benchmark 0.17.0, -p 256 -d 256 --runs 3 --cache no, quiet machine, serialized, ≥300 s rest before each GPU reading; every backend first proven to generate on the file):
| File | Backend | Prefill (256) | Decode | TTFT | Init |
|---|---|---|---|---|---|
| int8 | GPU (Metal) | 784 tok/s | 49.4 tok/s | 0.35 s | 4.1 s |
| int8 | CPU | 345 tok/s | 19.5 tok/s | 0.79 s | 27.0 s |
| int4 | GPU (Metal) | 826 tok/s | 53.6 tok/s | 0.33 s | 3.7 s |
| int4 | CPU | 118 tok/s | 18.4 tok/s | 2.24 s | 5.3 s |
Galaxy S26 (SM-S942Q, Snapdragon SM8850, Adreno; litert_lm_advanced_main from the litert-lm v0.16.0 release kit, 205-token prompt with --benchmark, 2 runs per cell, ranges shown):
| File | Backend | Prefill (205) | Decode | TTFT | Init | Peak RSS |
|---|---|---|---|---|---|---|
| int8 | GPU (OpenCL) | not measured — the benchmark turn (a ~3,900-token thinking response at ~5 tok/s) exceeded the 20-minute leg cap; the file loads with full OpenCL delegation (2236/2236 nodes) and answers the gate prompt correctly on the GPU | ||||
| int8 | CPU | 65–102 tok/s | 4.5–4.7 tok/s | 2.30–3.49 s | 0.4–0.7 s | 5553 MB |
| int4 | GPU (OpenCL) | 43–56 tok/s | 4.9 tok/s | 3.98–5.21 s | 14.0–16.6 s | 1960 MB |
| int4 | CPU | 35–86 tok/s | 5.5–5.6 tok/s | 2.65–6.31 s | 1.5–4.1 s | 3536 MB |
iPhone 17 Pro (G41DeviceTest harness, composite 8-question prompt, --max-tokens 3072, on-device byte count verified against the source file; score = questions answered correctly inside one reply):
| File | Metal GPU | CPU | Init GPU | Init CPU |
|---|---|---|---|---|
| int8 | 8/8 | 8/8 | 2.9 s | 13.2 s |
| int4 | 7/8 | 7/8 | 5.3 s | 9.0 s |
Both files run with fp32 GPU activations on the phone as well. The int8 file is a single 4.24 GB weights section and loads under this harness (Increased Memory Limit entitlement; available memory floor ~2.6 GB on the Metal leg, ~4.5 GB on the CPU leg); the int4 file's Metal leg bottomed at ~2.0 GB free. GPU init times are with a warm shader cache (a cold first launch of the int8 file initialised in 18.8 s). The int4 file's one miss on each backend is the rhyme line at the end of the composite 8-question prompt (it answers "sweet"); asked on its own the same question is answered "blue" on every backend.
Converted with litert-torch 0.9.3 / transformers 5.14.1 / ai-edge-quantizer, released wheels (reproduction script: hf-to-litertlm).
modeling_spark.py computes attention through its own eager function and ignores config._attn_implementation; the export copy dispatches through the registered attention interface (so litert-torch's transposed KV cache is used), threads the per-call kwargs, declares the attention-backend capability flags, and applies the per-head sigmoid output gate in the interface's layout. In eager mode the patched file is bit-identical to the vendor file (max |Δlogit| 0.0 on 24 random tokens); two further edits make the vendor file load under transformers 5 at all (_tied_weights_keys mapping form, mask-utility kwargs).thought channel is declared in the metadata. Without the channel the runtime streams raw reasoning into the answer and silently ignores any thinking budget.<|start▁of▁sentence|> as BOS but never prepends it (add_bos_token: false); the template carries its own. The exporter's unconditional start_token write was suppressed (measured harmless in bf16 on the 8-question gate, but it is not the vendor prompt).prefer_activation_type = "fp32", a metadata-only repack; weights byte-identical). The runtime runs the text decoder with fp16 activations on the GPU by default, and on this 36-layer decoder that silently costs reasoning accuracy: the same int8 weights scored GSM8K 84 under fp16 GPU activations and 94 under fp32 — established by re-running the GPU losses on the CPU (fp32) path, where 10 of 11 came back right. The 8-question gate did not see it (8/8 either way); only a long-generation accuracy row does. Expect a larger GPU memory footprint than an fp16-activation file of the same size.tokenizer.json (HF tokenizer section), not a SentencePiece conversion.Distributed under Apache-2.0 (inherited from the base model; the upstream LICENSE file is included). Changes from the original work: weights converted from safetensors bf16 to LiteRT flatbuffers and quantized as described above; tokenizer and chat template repackaged into the .litertlm bundle (thinking pre-fill and thought-channel metadata as described); tool-calling template branches not carried. No training or fine-tuning. This repository is a community conversion and is not affiliated with iFLYTEK or the SparkLLM Team.