Ben Graville commited on
docs: descriptive model card
Browse files
README.md
CHANGED
|
@@ -1,50 +1,165 @@
|
|
| 1 |
---
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
library_name: coreai
|
| 3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
---
|
| 5 |
|
| 6 |
-
# LFM2.5-2.6B
|
| 7 |
|
| 8 |
-
Core AI `.aimodel` bundles
|
| 9 |
-
|
| 10 |
-
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
|
| 16 |
## Provenance
|
| 17 |
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
|
|
|
| 27 |
|
| 28 |
-
|
|
|
|
|
|
|
|
|
|
| 29 |
|
|
|
|
| 30 |
|
| 31 |
-
|
|
|
|
|
|
|
| 32 |
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
`
|
| 36 |
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
| `ctx8192/gpu-pipelined/lfm2_5_2_6b_decode_int8hu_block32_sym_mf64` | LiquidAI/LFM2.5-2.6B | 8192 | main+prefill | fp16 | coreai-core 1.0.0b2 | 20260817T205308Z |
|
| 40 |
|
|
|
|
| 41 |
|
| 42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
|
| 44 |
-
|
| 45 |
-
`
|
| 46 |
-
`
|
|
|
|
| 47 |
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
license: other
|
| 3 |
+
license_name: lfm1.0
|
| 4 |
+
license_link: https://huggingface.co/LiquidAI/LFM2.5-2.6B/blob/main/LICENSE
|
| 5 |
+
base_model: LiquidAI/LFM2.5-2.6B
|
| 6 |
library_name: coreai
|
| 7 |
+
pipeline_tag: text-generation
|
| 8 |
+
tags:
|
| 9 |
+
- core-ai
|
| 10 |
+
- aimodel
|
| 11 |
+
- apple-silicon
|
| 12 |
+
- on-device
|
| 13 |
+
- quantized
|
| 14 |
+
- int8
|
| 15 |
+
- lfm2.5
|
| 16 |
---
|
| 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 the
|
| 21 |
+
[Visible](https://visible.cx) project. These are **derivative artifacts**: the weights are
|
| 22 |
+
Liquid AI's, 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 run through
|
| 24 |
+
Core AI on macOS; they are not PyTorch, GGUF or MLX checkpoints and cannot be loaded by
|
| 25 |
+
those runtimes.
|
| 26 |
|
| 27 |
+
**This is the model the Visible app selects as its quality tier.** It is the strongest of
|
| 28 |
+
the three LFM2.5 text bundles in this catalog on Visible's own enrichment task, and the one
|
| 29 |
+
whose outputs were judged most specific.
|
| 30 |
|
| 31 |
## Provenance
|
| 32 |
|
| 33 |
+
| | |
|
| 34 |
+
|---|---|
|
| 35 |
+
| Base checkpoint | `LiquidAI/LFM2.5-2.6B` |
|
| 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` β verified per bundle |
|
| 40 |
+
| Weight format | int8, per-K-block-32, symmetric; symmetric head (`--head-sym`) |
|
| 41 |
+
| Vocab | 128,000 |
|
| 42 |
+
| Conversion host | Linux x86_64 (Debian 13), CPU tracing only |
|
| 43 |
|
| 44 |
+
`mf64` in the bundle name means **multifunction with a 64-wide prefill**: one asset
|
| 45 |
+
exposing `main` (S=1 decode) and `prefill` (S=64 chunked prefill),
|
| 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 |
+
### The `<think>` patch β read this before swapping in a fresh export
|
| 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 |
+
This correction is applied post-export and **is not in the exporter**. A fresh conversion
|
| 60 |
+
from the recipe reproduces the weights faithfully and this behaviour wrongly.
|
|
|
|
| 61 |
|
| 62 |
+
## Contents
|
| 63 |
|
| 64 |
+
| Path | Bytes | Manifest context | Functions |
|
| 65 |
+
|---|---:|---|---|
|
| 66 |
+
| `gpu-pipelined/lfm2_5_2_6b_decode_int8hu_block32_sym_mf64` | 3,655,243,493 | 4096 | main + prefill |
|
| 67 |
+
| `ctx8192/gpu-pipelined/lfm2_5_2_6b_decode_int8hu_block32_sym_mf64` | 3,655,243,501 | 8192 | main + prefill |
|
| 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 |
+
(`tokenizer.json`, `tokenizer_config.json`, `generation_config.json`,
|
| 73 |
+
`chat_template.jinja`).
|
| 74 |
|
| 75 |
+
**The three folders hold the same weights.** `--max-ctx` does not change the exported
|
| 76 |
+
graph β function signatures, state descriptors and peak export RSS are identical at 4096,
|
| 77 |
+
8192 and 16384. It changes exactly one thing: `language.max_context_length` in the bundle
|
| 78 |
+
manifest. This was proved three ways, including a same-config control re-export whose
|
| 79 |
+
`main.mlirb` differed from its twin by *more* bytes than a 4096β8192 pair does
|
| 80 |
+
(conversion is not byte-deterministic; the context delta is inside that noise floor). Pick
|
| 81 |
+
the folder whose manifest integer matches the window you intend to run, or edit the
|
| 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. Nothing here runs on Linux or on Intel.
|
| 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.
|
| 93 |
+
- **States:** `keyCache` / `valueCache` `Float16, 8 Γ 1 Γ 8 Γ ? Γ 64` plus
|
| 94 |
+
`convState Float16, 22 Γ 1 Γ 2048 Γ 2`. The sequence dim is dynamic, so the runtime
|
| 95 |
+
resolves a `GrowingKVCache` (initial capacity 256, doubling) rather than allocating the
|
| 96 |
+
manifest maximum up front. `convState` is fixed-size and does not scale with context.
|
| 97 |
+
- **KV cost: 16,384 bytes per token of context** (fp16) β 67 MB at 4096, 134 MB at 8192,
|
| 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 peak RSS on the qualification run was **4.43 GB**.
|
| 102 |
+
- `runtime_env COREAI_CHUNK_THRESHOLD=1` travels with the recipe.
|
| 103 |
+
|
| 104 |
+
## Measured performance
|
| 105 |
+
|
| 106 |
+
Measured on a **16 GB M2 Pro Mac (macOS 27 beta)** with the out-of-process `coreai-repro`
|
| 107 |
+
harness: 10 real enrichment rows (5 POST, 5 COMMENT) from Visible's prompt corpus, the
|
| 108 |
+
app's live `app_litert` JSON schema, greedy decoding through `respondJSON(to:schema:)`,
|
| 109 |
+
`reset()` per row, sequential engine, 128-token cap. Load time excluded from `s/row`; row 1
|
| 110 |
+
of each run excluded as a cache-warm outlier.
|
| 111 |
+
|
| 112 |
+
| | |
|
| 113 |
+
|---|---|
|
| 114 |
+
| Cold load | 39.5 s |
|
| 115 |
+
| Guided JSON parse | **10/10** |
|
| 116 |
+
| s/row | **3.62** (POST) / **3.04** (COMMENT) |
|
| 117 |
+
| Peak RSS | 4.43 GB |
|
| 118 |
+
| Stop token | `<\|im_end\|>`, clean self-stop on every row |
|
| 119 |
+
|
| 120 |
+
For scale within this catalog on the same harness and machine: LFM2.5-350M runs
|
| 121 |
+
0.79/0.51 s/row, LFM2.5-1.2B 1.77/1.30 s/row. The 2.6B is β2Γ the 1.2B, which is what its
|
| 122 |
+
parameter count predicts, and it produces the most specific `summary`/`context` fields of
|
| 123 |
+
the three.
|
| 124 |
+
|
| 125 |
+
A note on a figure that circulated internally: "1.75 s posts / 1.20 s comments" is the
|
| 126 |
+
**1.2B's** number, not this model's. Plan the quality tier against 3.0β3.6 s/row.
|
| 127 |
+
|
| 128 |
+
Nothing above was measured at 8192 or 16384 context; the `ctx8192`/`ctx16384` folders carry
|
| 129 |
+
the 4096 folder's graph, so throughput should be unchanged, but quality and memory at depth
|
| 130 |
+
are unmeasured.
|
| 131 |
+
|
| 132 |
+
## Qualification status
|
| 133 |
+
|
| 134 |
+
| Artifact | Status |
|
| 135 |
+
|---|---|
|
| 136 |
+
| `gpu-pipelined/β¦_mf64` (ctx 4096) | **SHIP** β measured on the harness above and selected by the Visible app as its quality tier |
|
| 137 |
+
| `ctx8192/β¦_mf64` | **QUALIFIED BY EQUIVALENCE, UNMEASURED AT DEPTH** β byte-equivalent weights and an identical graph to the shipping bundle; no run has been made at >4096 tokens |
|
| 138 |
+
| `ctx16384/β¦_mf64` | **QUALIFIED BY EQUIVALENCE, UNMEASURED AT DEPTH** β as above |
|
| 139 |
+
|
| 140 |
+
## Verification
|
| 141 |
+
|
| 142 |
+
- **Producer fingerprint:** every inner `<name>.aimodel/metadata.json` reads
|
| 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 |
+
|
| 159 |
+
`LiquidAI/LFM2.5-2.6B` is released under the **LFM Open License v1.0** (`lfm1.0`). These
|
| 160 |
+
bundles are a derivative of that checkpoint and the same licence and its obligations travel
|
| 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; Visible's contribution is the
|
| 165 |
+
conversion recipe and the qualification evidence.
|