docs: refresh measured performance (local retest 2026-08-18)
Browse files
README.md
CHANGED
|
@@ -17,16 +17,16 @@ tags:
|
|
| 17 |
|
| 18 |
# LFM2.5-2.6B β Core AI (.aimodel)
|
| 19 |
|
| 20 |
-
`LiquidAI/LFM2.5-2.6B` converted to Core AI `.aimodel` bundles for Apple silicon by
|
| 21 |
-
[
|
| 22 |
-
|
| 23 |
-
quantization and a two-entrypoint (decode + chunked-prefill) function map. They
|
| 24 |
-
Core AI on macOS
|
| 25 |
-
those runtimes.
|
| 26 |
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
|
|
|
| 30 |
|
| 31 |
## Provenance
|
| 32 |
|
|
@@ -36,28 +36,25 @@ whose outputs were judged most specific.
|
|
| 36 |
| Recipe | `export_lfm2_multifunction.py int8hu --head-sym --chunk 64` |
|
| 37 |
| Toolchain base | `apple/coreai-models` @ `b1cb71b8522d99408059fa0b98b8742171bcb0b8` + the [coreai-model-zoo](https://github.com/john-rocky/coreai-model-zoo) python overlay |
|
| 38 |
| Toolchain | `coreai-torch 0.4.1`, `coreai-core 1.0.0b2`, `coreai-opt 0.2.1`, `torch 2.9.0` |
|
| 39 |
-
| Producer fingerprint | `coreai-core 1.0.0b2` on every inner `<name>.aimodel/metadata.json`
|
| 40 |
| Weight format | int8, per-K-block-32, symmetric; symmetric head (`--head-sym`) |
|
| 41 |
| Vocab | 128,000 |
|
| 42 |
-
|
|
| 43 |
|
| 44 |
-
`mf64` in the bundle name means
|
| 45 |
-
|
| 46 |
-
`function_map: {"main": ["main", "prefill"]}`. Weights are deduplicated across the two
|
| 47 |
-
entrypoints, so the prefill function costs well under a megabyte.
|
| 48 |
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
Upstream's `chat_template.jinja` ends its generation prompt with an **open** think block
|
| 52 |
-
(`<|im_start|>assistant\n<think>`). LFM2.5-2.6B is always-thinking, so an open block burns
|
| 53 |
-
684β919 reasoning tokens per item. Every bundle in this repo ships the block **closed**:
|
| 54 |
|
| 55 |
```jinja
|
| 56 |
{{- "<|im_start|>assistant\n<think></think>\n" -}}
|
| 57 |
```
|
| 58 |
|
| 59 |
-
|
| 60 |
-
|
|
|
|
|
|
|
| 61 |
|
| 62 |
## Contents
|
| 63 |
|
|
@@ -68,25 +65,21 @@ from the recipe reproduces the weights faithfully and this behaviour wrongly.
|
|
| 68 |
| `ctx16384/gpu-pipelined/lfm2_5_2_6b_decode_int8hu_block32_sym_mf64` | 3,655,243,498 | 16384 | main + prefill |
|
| 69 |
|
| 70 |
Each folder holds `<name>.aimodel/` (`main.mlirb` β 3.64 GB, `main.hash`, asset
|
| 71 |
-
`metadata.json`), a bundle-level `metadata.json`, and `tokenizer/`
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
manifest
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
integer β you do not need a new conversion for a context bump.
|
| 83 |
-
|
| 84 |
-
The small byte differences between the three folders are conversion nondeterminism, not
|
| 85 |
-
content.
|
| 86 |
|
| 87 |
## Requirements
|
| 88 |
|
| 89 |
-
- **Apple silicon Mac**, Core AI runtime.
|
| 90 |
- **Engine contract: 2 inputs.** `input_ids`, `position_ids` β logits. No static inputs, no
|
| 91 |
per-step mask. Runs on both the pipelined engine and the sequential (logits-capable)
|
| 92 |
engine, which is what makes grammar-constrained decoding available.
|
|
@@ -98,61 +91,73 @@ content.
|
|
| 98 |
268 MB at 16384.
|
| 99 |
- **Memory envelope, 16 GB Mac** (Metal `recommendedMaxWorkingSetSize` β 10.7 GB):
|
| 100 |
weights 3.64 GB resident, so KV is not the binding constraint at any context this bundle
|
| 101 |
-
declares. Measured
|
| 102 |
-
-
|
|
|
|
|
|
|
| 103 |
|
| 104 |
-
##
|
| 105 |
|
| 106 |
-
Measured on a **16 GB
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
of each run excluded as a cache-warm outlier.
|
| 111 |
|
| 112 |
| | |
|
| 113 |
|---|---|
|
| 114 |
-
| Cold load |
|
| 115 |
| Guided JSON parse | **10/10** |
|
| 116 |
-
|
|
| 117 |
-
|
|
| 118 |
-
|
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 133 |
|
| 134 |
| Artifact | Status |
|
| 135 |
|---|---|
|
| 136 |
-
| `gpu-pipelined/β¦_mf64` (ctx 4096) | **SHIP** β measured
|
| 137 |
-
| `ctx8192/β¦_mf64` | **QUALIFIED
|
| 138 |
-
| `ctx16384/β¦_mf64` | **QUALIFIED
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
`producer: "coreai-core 1.0.0b2"`. This matters: `coreai-torch 0.4.0` / `coreai-core
|
| 144 |
-
1.0.0b1` produce bundles that abort in-process at load and take the host application down
|
| 145 |
-
uncatchably. The fingerprint lives in the **inner asset** metadata, not the bundle
|
| 146 |
-
manifest β the manifest never carries a `producer` field, for good and bad bundles alike.
|
| 147 |
-
- **Stop token:** `tokenizer_config.json` declares `eos_token = "<|im_end|>"` in all three
|
| 148 |
-
folders, verified. LFM bundles need no stop-token correction (unlike Gemma 4).
|
| 149 |
-
- **Determinism:** `.aimodel` conversion is **not byte-reproducible**. Two runs of the same
|
| 150 |
-
command minutes apart on the same box differ in `main.mlirb`. The tokenizer half *is*
|
| 151 |
-
reproducible. So integrity for these bundles rests on per-file SHA-256 of the exact
|
| 152 |
-
published artifact, never on rebuilding and comparing hashes.
|
| 153 |
-
- No oracle or PSNR gate has been run against a PyTorch reference for this bundle. The
|
| 154 |
-
qualification above is behavioural (parse rate, enum conformance, content sanity, clean
|
| 155 |
-
stop) on Visible's own task, not a numerics gate.
|
| 156 |
|
| 157 |
## License
|
| 158 |
|
|
@@ -161,5 +166,5 @@ bundles are a derivative of that checkpoint and the same licence and its obligat
|
|
| 161 |
with them β see the
|
| 162 |
[upstream licence](https://huggingface.co/LiquidAI/LFM2.5-2.6B/blob/main/LICENSE). Anyone
|
| 163 |
redistributing these files should redistribute the licence with them and comply with its
|
| 164 |
-
terms. Nothing here relicenses Liquid AI's weights;
|
| 165 |
-
|
|
|
|
| 17 |
|
| 18 |
# LFM2.5-2.6B β Core AI (.aimodel)
|
| 19 |
|
| 20 |
+
`LiquidAI/LFM2.5-2.6B` converted to Core AI `.aimodel` bundles for Apple silicon by
|
| 21 |
+
[visible-cx](https://huggingface.co/visible-cx). These are derivative artifacts: Liquid
|
| 22 |
+
AI's weights re-expressed as a Core AI graph with int8 block-32 symmetric weight
|
| 23 |
+
quantization and a two-entrypoint (decode + chunked-prefill) function map. They load
|
| 24 |
+
through Core AI on macOS and are not usable by PyTorch, GGUF or MLX.
|
|
|
|
| 25 |
|
| 26 |
+
Of the dense LFM2.5 bundles published here, this is the strongest on guided
|
| 27 |
+
structured-output work and the only one qualified for long context: **3/3 verbatim needle
|
| 28 |
+
recall at 14,566 tokens, sustaining 32 tok/s for under half a gigabyte of in-process
|
| 29 |
+
footprint.**
|
| 30 |
|
| 31 |
## Provenance
|
| 32 |
|
|
|
|
| 36 |
| Recipe | `export_lfm2_multifunction.py int8hu --head-sym --chunk 64` |
|
| 37 |
| Toolchain base | `apple/coreai-models` @ `b1cb71b8522d99408059fa0b98b8742171bcb0b8` + the [coreai-model-zoo](https://github.com/john-rocky/coreai-model-zoo) python overlay |
|
| 38 |
| Toolchain | `coreai-torch 0.4.1`, `coreai-core 1.0.0b2`, `coreai-opt 0.2.1`, `torch 2.9.0` |
|
| 39 |
+
| Producer fingerprint | `coreai-core 1.0.0b2` on every inner `<name>.aimodel/metadata.json` |
|
| 40 |
| Weight format | int8, per-K-block-32, symmetric; symmetric head (`--head-sym`) |
|
| 41 |
| Vocab | 128,000 |
|
| 42 |
+
| Export functions | `main` (S=1 decode) + `prefill` (S=64 chunked prefill), `function_map: {"main": ["main", "prefill"]}`, weights deduplicated across entrypoints |
|
| 43 |
|
| 44 |
+
`mf64` in the bundle name means multifunction with a 64-wide prefill; the prefill function
|
| 45 |
+
costs well under a megabyte.
|
|
|
|
|
|
|
| 46 |
|
| 47 |
+
**Chat template.** LFM2.5-2.6B is an always-thinking model. The template shipped in every
|
| 48 |
+
bundle here **terminates the reasoning block in the generation prompt**:
|
|
|
|
|
|
|
|
|
|
| 49 |
|
| 50 |
```jinja
|
| 51 |
{{- "<|im_start|>assistant\n<think></think>\n" -}}
|
| 52 |
```
|
| 53 |
|
| 54 |
+
An unterminated block (`β¦assistant\n<think>`) causes the model to spend the entire
|
| 55 |
+
generation budget inside `<think>`, which a host routes to a reasoning channel and never to
|
| 56 |
+
the response β 684β919 tokens per item, with no visible output. If you rebuild from the
|
| 57 |
+
recipe, apply the same termination.
|
| 58 |
|
| 59 |
## Contents
|
| 60 |
|
|
|
|
| 65 |
| `ctx16384/gpu-pipelined/lfm2_5_2_6b_decode_int8hu_block32_sym_mf64` | 3,655,243,498 | 16384 | main + prefill |
|
| 66 |
|
| 67 |
Each folder holds `<name>.aimodel/` (`main.mlirb` β 3.64 GB, `main.hash`, asset
|
| 68 |
+
`metadata.json`), a bundle-level `metadata.json`, and `tokenizer/` (`tokenizer.json`,
|
| 69 |
+
`tokenizer_config.json`, `generation_config.json`, `chat_template.jinja`).
|
| 70 |
+
|
| 71 |
+
**The three folders hold the same weights and the same graph** β function signatures, state
|
| 72 |
+
descriptors and peak export RSS are identical at 4096, 8192 and 16384. `--max-ctx` changes
|
| 73 |
+
exactly one thing: `language.max_context_length` in the bundle manifest. The small byte
|
| 74 |
+
differences between folders are conversion nondeterminism, not content. Pick the folder
|
| 75 |
+
whose manifest integer matches the window you intend to run.
|
| 76 |
+
|
| 77 |
+
**Stop token:** `eos_token = "<|im_end|>"` in all three folders. Clean self-stop on every
|
| 78 |
+
measured sample.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
|
| 80 |
## Requirements
|
| 81 |
|
| 82 |
+
- **Apple silicon Mac**, Core AI runtime.
|
| 83 |
- **Engine contract: 2 inputs.** `input_ids`, `position_ids` β logits. No static inputs, no
|
| 84 |
per-step mask. Runs on both the pipelined engine and the sequential (logits-capable)
|
| 85 |
engine, which is what makes grammar-constrained decoding available.
|
|
|
|
| 91 |
268 MB at 16384.
|
| 92 |
- **Memory envelope, 16 GB Mac** (Metal `recommendedMaxWorkingSetSize` β 10.7 GB):
|
| 93 |
weights 3.64 GB resident, so KV is not the binding constraint at any context this bundle
|
| 94 |
+
declares. Measured max RSS **6.71 GB** on guided decoding and 7.30 GB at 15k context;
|
| 95 |
+
peak in-process footprint 0.48 GB and 0.46 GB respectively β essentially flat in context.
|
| 96 |
+
**Minimum practical machine memory: 16 GB**, at any declared context including 16384.
|
| 97 |
+
- The bundle manifest declares `runtime_env COREAI_CHUNK_THRESHOLD=1`.
|
| 98 |
|
| 99 |
+
## Performance
|
| 100 |
|
| 101 |
+
Measured on a **16 GB Apple silicon Mac (M2 Pro, macOS 27 beta)**: 10-sample harness,
|
| 102 |
+
guided JSON-constrained decoding against a fixed schema, greedy, sequential engine,
|
| 103 |
+
`reset()` between samples, 128-token cap. Load excluded from `s/row`; sample 1 excluded as
|
| 104 |
+
a cache-warm outlier.
|
|
|
|
| 105 |
|
| 106 |
| | |
|
| 107 |
|---|---|
|
| 108 |
+
| Cold load | 18.4 s |
|
| 109 |
| Guided JSON parse | **10/10** |
|
| 110 |
+
| Enum-clean | **10/10** |
|
| 111 |
+
| s/row (long samples) | **3.66** |
|
| 112 |
+
| s/row (short samples) | **3.06** |
|
| 113 |
+
| Decode | **38.1β40.0 tok/s** |
|
| 114 |
+
| TTFT | **0.47β2.29 s** |
|
| 115 |
+
| Peak footprint | 0.48 GB |
|
| 116 |
+
| Max RSS | 6.71 GB |
|
| 117 |
+
|
| 118 |
+
For scale on the same machine and harness: LFM2.5-350M runs 0.84/0.55 s/row and
|
| 119 |
+
LFM2.5-1.2B 1.89/1.37 s/row. The 2.6B is β2Γ the 1.2B, which is what its parameter count
|
| 120 |
+
predicts, and it produces the most specific free-text fields of the three.
|
| 121 |
+
|
| 122 |
+
### Long context
|
| 123 |
+
|
| 124 |
+
**Needle-in-haystack: 3/3 verbatim at both 8k and 15k.** Three distinctive facts planted at
|
| 125 |
+
10% / 50% / 90% of the filler, strict scoring (a fact counts only if the distinctive entity
|
| 126 |
+
comes back correct). All three returned at 7,813 tokens and all three at 14,566 tokens,
|
| 127 |
+
verbatim, including the date.
|
| 128 |
+
|
| 129 |
+
| probe | prompt tokens | TTFT | decode | wall | peak footprint |
|
| 130 |
+
|---|---|---|---|---|---|
|
| 131 |
+
| needle 8k | 7,813 | 13.78 s | 35.8 tok/s | 15.4 s | 0.34 GB |
|
| 132 |
+
| needle 15k | 14,566 | 27.42 s | **32.2 tok/s** | 29.1 s | 0.46 GB |
|
| 133 |
+
|
| 134 |
+
Free-form generation from a fixed prompt at three depths, 900-token cap (the model
|
| 135 |
+
self-stopped inside it every time):
|
| 136 |
+
|
| 137 |
+
| depth | prompt tokens | TTFT | decode | generated | wall | peak footprint |
|
| 138 |
+
|---|---|---|---|---|---|---|
|
| 139 |
+
| 3.4k | 3,249 | 6.88 s | 35.3 tok/s | 847 | **29.5 s** | 0.28 GB |
|
| 140 |
+
| 8k | 7,673 | 14.84 s | 36.6 tok/s | 715 | **36.0 s** | 0.47 GB |
|
| 141 |
+
| 12k | 11,643 | 22.24 s | **32.9 tok/s** | 743 | **44.4 s** | 0.46 GB |
|
| 142 |
+
|
| 143 |
+
**Decode barely moves with depth.** 40.0 tok/s at 2.3k β 35.3 at 3.2k β 36.6 at 7.7k β
|
| 144 |
+
32.9 at 11.6k: an 18% decay across a 5Γ context increase. It sustains 32β33 tok/s at
|
| 145 |
+
11.6β14.5k tokens with under half a gigabyte of in-process footprint. High context costs
|
| 146 |
+
prefill time and almost nothing else β TTFT scales cleanly (4.8 β 6.9 β 14.8 β 22.2 β
|
| 147 |
+
27.4 s) while footprint stays flat. The KV term is `GrowingKVCache`-dynamic and small at
|
| 148 |
+
this size (16 KB/token β 268 MB at 16384).
|
| 149 |
+
|
| 150 |
+
## Status
|
| 151 |
|
| 152 |
| Artifact | Status |
|
| 153 |
|---|---|
|
| 154 |
+
| `gpu-pipelined/β¦_mf64` (ctx 4096) | **SHIP** β measured: 10/10 guided parse and enum-clean, 3.66/3.06 s/row, 38.1β40.0 tok/s. |
|
| 155 |
+
| `ctx8192/β¦_mf64` | **QUALIFIED AT DEPTH** β same weights and graph; measured: 3/3 verbatim needle recall at 7,813 tokens, 36.6 tok/s at 8k, 0.47 GB peak footprint. |
|
| 156 |
+
| `ctx16384/β¦_mf64` | **QUALIFIED AT DEPTH** β 3/3 verbatim needle recall at 14,566 tokens at 32.2 tok/s, 0.46 GB peak footprint, 7.30 GB max RSS. Recommended for long-context work. |
|
| 157 |
+
|
| 158 |
+
No oracle or PSNR gate has been run against a PyTorch reference. Qualification is
|
| 159 |
+
behavioural (parse rate, enum conformance, content sanity, clean stop, needle recall), not
|
| 160 |
+
a numerics gate.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 161 |
|
| 162 |
## License
|
| 163 |
|
|
|
|
| 166 |
with them β see the
|
| 167 |
[upstream licence](https://huggingface.co/LiquidAI/LFM2.5-2.6B/blob/main/LICENSE). Anyone
|
| 168 |
redistributing these files should redistribute the licence with them and comply with its
|
| 169 |
+
terms. Nothing here relicenses Liquid AI's weights; the contribution is the conversion
|
| 170 |
+
recipe and the qualification evidence.
|