LFM2.5-8B-A1B β€” Core AI (.aimodel)

LiquidAI/LFM2.5-8B-A1B as Core AI .aimodel bundles for Apple silicon, published by visible-cx. They load through Core AI on macOS and are not usable by PyTorch, GGUF or MLX. This is the model the Visible app routes Perspectives and Reports to β€” the long-prose families, where a 16,384-token window and grammar-constrained decoding matter more than raw speed.

It is a sparse mixture-of-experts model: 8.3B total parameters, ~1.5B active per token. 24 layers β€” 18 short-convolution mixers and 6 GQA attention layers; the first two layers are dense, every layer after is a 32-expert top-4 MoE. The expert weights are read through a gather_qmm Metal kernel, which is what makes the model fast: upstream measured 140.4 tok/s on an M4 Max through the gather path against 39.2 tok/s for the same weights read as a dense over-read.

aff4/ is the bundle to use. It supersedes mf64/ (the sym8 build) on one arithmetic fact and not on preference: on a 16 GB Mac sym8 requires 12.72 GiB free before it will start, which is more than that machine has ever been measured to have; the aff4 D2 rebuild requires 7.55–7.87 GiB and has completed an 11-question report leg end to end at 56.2 tok/s. mf64/ is kept as the evidence for that comparison, not as a fallback. See Measurements.

Contents

Path Bytes Weights Context Functions Status
aff4/lfm2_5_8b_a1b_decode_aff4_gather_mf64_d2 5,724,920,429 int4 affine experts + int8 16384 main + prefill SHIP
mf64/lfm2_5_8b_a1b_decode_sym8_gather_mf64 9,447,767,758 int8 sym8 16384 main + prefill SUPERSEDED
mf64-tp/lfm2_5_8b_a1b_decode_sym8_gather_mf64_tp 9,447,998,621 int8 sym8 16384 main + prefill RETIRED

Each folder holds <name>.aimodel/ (main.mlirb, main.hash, asset metadata.json), a bundle-level metadata.json, and tokenizer/ (tokenizer.json, tokenizer_config.json, chat_template.jinja).

aff4/README.md sits beside the bundle directory rather than inside it, deliberately: a downloader that verifies a bundle by summing its subtree β€” as this project's does β€” counts a repo card inside the bundle folder as 1,084 unexpected bytes and refuses. Keep repo prose one level above any bundle directory.

Stop token: eos_token = "<|im_end|>" in all three bundles.

Chat template. LFM2.5-8B-A1B is an always-thinking model, so the generation prompt terminates the reasoning block β€” {{- "<|im_start|>assistant\n<think></think>\n" -}}, the same form the LFM2.5-2.6B bundles use. Free-form generation therefore returns text with the bundle exactly as published rather than spending the whole budget inside an unterminated <think> block. Guided decoding is unaffected either way, because the grammar forces structured output from the first token.

Provenance

Base checkpoint LiquidAI/LFM2.5-8B-A1B
Zoo recipe models/lfm2.5-8b-a1b-moe/recipe.toml β†’ ["lfm2.5-8b-a1b"], status = "verified" β€” the lineage mf64/ reproduces
Recipe export_lfm2_moe_multifunction.py β€” metalize_moe_batched installs BatchedMetalSwitchGLU
Toolchain base apple/coreai-models @ b1cb71b8522d99408059fa0b98b8742171bcb0b8 + the coreai-model-zoo python overlay
Producer fingerprint coreai-core 1.0.0b2 on every inner asset metadata.json
Vocab 128,000
Export functions main (S=1 decode) + prefill (S=64)

BatchedMetalSwitchGLU serves S=64 by sorting (token, expert) pairs and falls back to the q=1 gather path at S=1, so both entrypoints keep the gather kernel and decode arithmetic is identical between them.

aff4/ β€” the D2 rebuild

D2 is mf64/'s weights re-quantized and re-exported under three changes, each priced separately against an fp32 oracle before it was taken:

lever what it does
aff4 experts routed experts at affine int4, per-(output row, K-block 64) scale + bias, MSE-optimal clip. The 0.43 GiB of weight saving.
L1 β€” untied, quantized head lm_head untied from embed_tokens and quantized at int8 symmetric (absmax).
L2 β€” fp16 attention projections fp32_attn_proj=False, so the attention matmul is fp16 and the compiler's materialised transposes follow it.

The head's quantization scheme is the whole story of this bundle. An affine head (D1) compiled to a 1,457,034,236-byte graph constant; the symmetric head (D2) compiled to 408,458,282. Same weights, same size on disk, one field different. A symmetric dequantize is a scale multiply the delegate absorbs into the matmul; an affine one is (q βˆ’ zp) Γ— scale, and the subtract is not absorbed β€” so the folder precomputes two half-gigabyte dequantised 2048x128000 fp16 transposes of the head instead. D1 paid for its head three times. The lever is not "quantize the head", it is "give the head a dequantize the delegate can absorb".

Non-expert weights outside the head are the shipped int8 per-block-32 recipe calibrated on the decode spec. L3 β€” dropping the prefill entrypoint β€” was not taken: it is worth 0.27 GiB on this bundle and it would put every prompt token through the S=1 graph.

Not published, deliberately: a non-QAT int4 int4km-gather variant exists upstream and does not hold quality on this model.

Requirements

  • Apple silicon Mac, Core AI runtime. Mac-only β€” neither bundle fits an iPhone even with the memory-limit entitlement.
  • Engine contract: 2 inputs (input_ids, position_ids) β†’ logits. No static inputs, no per-step mask. Runs on the pipelined engine and on the logits-capable sequential engine, which is what grammar-constrained decoding needs.
  • Manifest context 16,384; maxOutputTokens and the S=64 prefill chunk are read from the bundle's own metadata.json (function_map: {"main": ["main", "prefill"]}).
  • The runtime wires the whole weight set at the first forward pass, not at load β€” an A1B is charged for all 8.3B parameters resident. "1.5B active" is a decode-speed property and nothing else. Budget by the numbers in Measurements, not by active parameter count.
  • Minimum practical machine memory: 16 GB for aff4/, with the machine reasonably quiet. mf64/ does not start on 16 GB; 24 GB or more.
  • Disk: the bundle plus its compiled graph cache on first load. aff4/ compiles to 6,115,467,248 B; mf64/ to 10.374 GiB.
  • The bundle manifest declares runtime_env COREAI_CHUNK_THRESHOLD = "1", the most memory-conservative prefill setting available. Keep it.

Measurements

All figures below are from a 16 GB Apple silicon Mac (M2 Pro, macOS 27 beta), under an external watchdog sampling wired memory, reclaimable memory and the compressor. Compile-only figures are zero-prompt runs with no forward pass.

aff4/ (D2) β€” the completed leg

Eleven real report questions, guided JSON-constrained decoding against a fixed schema, greedy, both kill criteria armed for the whole run and verified alive.

value
answered 11 / 11, every one parsing
mean decode 56.23 tok/s (range 54.17–60.05, no decay across the leg)
load 25.46 s (warm compile cache)
campaign wall 318.79 s
wired peak / growth 9.16 / 6.22 GiB
reclaimable trough 2.45 GiB against a 1.25 GiB floor β€” 1.20 GiB of margin, never approached
watchdog never tripped

Two later runs on the same bundle read 55.81 and 59.81 tok/s, so 56.23 sits in the middle of a narrow band rather than at a lucky edge.

Throughput is flat in prompt length β€” question 11 ran at 55.12 tok/s against question 1's 59.17, and the difference tracks prompt length rather than elapsed time. Across 521 samples in an earlier leg the longest prompt produced the smallest boundary spike. That flatness is an LFM-MoE property; the dense Gemma 4 12B measured on the same machine does not have it.

Quality on that leg, counted by an automated scorer with every flag hand-adjudicated:

measure result
JSON parses 11 / 11
inversion (someone else's words attributed to the subject, or the reverse) 0 / 11
invented attributor 0 / 11
unsupported motive 0 / 11
narration 2 / 11 non-zero, both low
third-person voice 6 flagged β†’ 5 upheld
schema echo 3 flagged β†’ 1 upheld

Zero inversions across eleven questions is the headline. One of the eleven answers is bad in a way that matters, and it is recorded rather than averaged away: on a "red flags" question the model recited the question's own enumerated category list back as findings, manufacturing a serious accusation out of the prompt's taxonomy. Ten of eleven are sound; that one is a different order of defect from an untidy one.

Release and re-acquire. Three teardown cycles: wired at peak stable to 0.012 GiB across cycles; wired after release settles to within 0.075 GiB of baseline; warm re-acquire 0.004–0.006 s; output byte-identical across cycles, so no state leaks across a release.

Loading does not wire. After a 116.28 s cold-cache load the wired counter read βˆ’0.031 GiB against baseline β€” the weights are read, and the wiring burst happens at the first forward pass.

The requirement, and why mf64/ is superseded

Compile-only, one at a time, watchdog armed:

aff4/ (D2) mf64/ (sym8)
bundle on disk 5.33 GiB 8.799 GiB
compiled blob 5.695 GiB 10.374 GiB
graph constant 0.380 GiB 1.591 GiB
blob Γ· bundle 1.07Γ— 1.18Γ—
peak phys_footprint during compile 0.39 GiB β€”
forecast peak (blob Γ— 1.106) 6.30 GiB 11.473 GiB
requirement on a 16 GB Mac (peak + 1.25 GiB in-flight floor) 7.55 GiB 12.72 GiB
measured requirement, from the completed run 7.87 GiB never completed a run

This machine's ordinary reclaimable memory is 4.5–7.3 GiB, with a single best-ever reading of 9.97 GiB that has never repeated. 12.72 GiB is above anything it has ever had free. sym8 is not a slow model here; it is a model that cannot start β€” and the whole 4.2Γ— gap between the two graph constants is compiler-materialised copies that were never weights.

Two honest notes against ourselves:

  • The shipped gate is 7.55, the completed run says 7.87. The blob law is 1.3% conservative on wired growth; the 0.32 GiB gap is the dirty footprint, which a ratio over a compiled blob has no term for. A finished measurement raised this model's requirement.
  • D2's exact stack was never itself an oracle row. Its components were, separately, and both are free: against an fp32 oracle (41 headline positions, 328 aggregate) the aff4 base scores 4/41 and 79/328; + head int8 symmetric scores 4/41, 79/328; + fp16 attention scores 4/41, 78/328. For comparison sym8 scores 1/41, 14/328 and fp16 scores 0/41, 12/328 β€” so sym8 is the more faithful quantization, and it is not the one that runs. That trade is the reason this repo keeps both.

mf64/ (sym8) β€” kept as evidence

Measured before it was superseded, 10-sample guided harness, sequential engine:

Guided JSON parse / enum-clean 10/10 / 10/10
s/row, long / short 7.70 / 4.71
Decode, guided 51.9–53.5 tok/s
Prefill 6.3 ms/token, linear in depth at 8k and 15k
Needle-in-haystack 3/3 at 8k, 3/3 at 15k (14,566 prompt tokens, TTFT 91.41 s)
Max RSS 9.04–10.73 GB
Cold load / warm load 60.6 s / 22.9–26.2 s

Read Max RSS carefully: a resident set counts clean mapped pages the kernel can drop for free, so it was never a statement about what the machine has to give up. The wired figures above are.

mf64-tp/ β€” RETIRED

Failed its Mac gate on 2026-08-18. Do not deploy it and do not route traffic to it.

A token-tiled prefill kernel. Three headline claims, two failed. (1) The Metal kernel compiles and runs β€” passed. (2) It is not bit-identical to mf64: 3 of 10 guided rows diverge, including one that invents an entity and one that flips a schema enum, while a same-session mf64 re-run reproduced its own outputs byte for byte on all 10 rows. Both bundles parse 10/10 and are enum-clean, so a schema-shape gate would not have caught this. (3) Prefill came in at 5.35 ms/prompt-token against a prediction of 0.97 β€” a 1.17Γ— speedup, not 6.5Γ—. Decode is genuinely unchanged, confirming the q=1 fallthrough is clean.

Usage

Swift Package Manager, via CoreAIKit β€” a community package, not affiliated with Apple, requiring macOS 27 beta:

.package(url: "https://github.com/john-rocky/coreai-kit", branch: "main")
// target dependency: .product(name: "CoreAIKit", package: "coreai-kit")

ModelID addresses a bundle as repo + path + revision, where path is the subtree in this repo holding one complete bundle (metadata.json + *.aimodel/ + tokenizer/). It downloads from the Hub on first use and is cached afterwards:

import CoreAIKit

let model = ModelID(
    "visible-cx/LFM2.5-8B-A1B-CoreAI",
    path: "aff4/lfm2_5_8b_a1b_decode_aff4_gather_mf64_d2",
    revision: "c9b541e85b9125ecb9dc7f4fa6d3e3c06ccd78e5")   // pin, don't ride main

var config = ChatSession.Configuration()
config.engineVariant = .sequential   // required for guided / grammar-constrained decoding
config.temperature = nil             // greedy

let chat = try await ChatSession(model: model, configuration: config)
for try await event in chat.streamResponse(to: "…") {
    if case .response(let delta) = event { print(delta, terminator: "") }
}

ChatSession(bundleAt:) loads a bundle directory already on disk, which is the path to use if you stage the bundle yourself. Leave COREAI_CHUNK_THRESHOLD alone β€” the manifest sets it.

Digests

aff4/lfm2_5_8b_a1b_decode_aff4_gather_mf64_d2, computed from the exact published bytes. main.hash is the raw 32 bytes of sha256(main.mlirb) β€” verified, not assumed.

path (bundle-relative) bytes sha256
metadata.json 634 8651c35cb26fb0e2cc80eb1ce952efe170bfa5a074b99fe04ad4fae87e58fbdd
….aimodel/main.hash 32 bb97d0dd52c410366f23281534f252dc0f5dad42450c03df28a4be2f8cf299c4
….aimodel/main.mlirb 5,707,008,966 ad57774b86dae371be1318265bfd2aa41cc315ee961efd3ad14820ca6cd8a775
….aimodel/metadata.json 105 4a78efbbae885ceb04bd9503fb6eded741ce22c77075157c8e7e863059b8341c
tokenizer/chat_template.jinja 4,779 b2881deb506bdff56bf6ac46aaa33292c119953f82fedaf276634fcc4282a559
tokenizer/tokenizer.json 17,905,598 695be7802a0e4b8a81048f0ff5ebb7fc811a0ba5a6be63dbb24deb5a81096f41
tokenizer/tokenizer_config.json 315 b53c3caceb7fa0de424e1aa67b3cc5008cd2f8b8d2426a8fa221ef3cf1a949d5
total 5,724,920,429

Why per-file digests and not just a revision. A revision pin is an assertion about a repository; this is an assertion about bytes, and only the second survives a mirror, a re-upload or a CDN edge that lies. Hugging Face stores LFS objects under their SHA-256 and everything else under its git blob oid, so the whole subtree above can be checked against this table with zero bytes downloaded, from the tree API alone.

This bundle has had three addresses in one day β€” staged locally, published at 9e023baf…, republished at c9b541e8… when a stray README moved out of the bundle subtree β€” and ad57774b86dae371… did not move once. Uploading bytes does not rehash them.

Core AI .aimodel bundles are not byte-reproducible: the exporter is not deterministic even against itself. Integrity rests on these digests, not on a rebuild.

Status

Artifact Status
aff4/…_aff4_gather_mf64_d2 SHIP. Measured: 11/11 answered and parsed at 56.23 tok/s on a completed watchdogged leg, 0/11 inversions, wired growth 6.22 GiB, release returns to baseline within 0.075 GiB. Requirement 7.55–7.87 GiB on a 16 GB Mac.
mf64/…_sym8_gather_mf64 SUPERSEDED β€” kept as evidence, not deleted. Measured: 10/10 guided parse and enum-clean, 51.9–53.5 tok/s, needle 3/3 at 8k and 15k. It requires 12.72 GiB to start, which is above anything the 16 GB reference machine has been measured to have free. Nothing substitutes it for aff4/ and nothing should.
mf64-tp/…_sym8_gather_mf64_tp RETIRED β€” failed its Mac gate. Kept for the record only.

No PSNR or numerics gate has been run against a PyTorch reference on device for any bundle here. The oracle rows quoted above are box-side torch fp32 comparisons; qualification on the Mac is behavioural (parse rate, enum conformance, grounding scoring, clean stop, needle recall) plus the memory instrumentation.

License

LiquidAI/LFM2.5-8B-A1B is released under the LFM Open License v1.0 (lfm1.0), and upstream declares it as license: other + license_name: lfm1.0. These bundles are a derivative of that checkpoint and the same licence and obligations travel with them β€” see the upstream licence. Redistribute the licence with the files. The contribution here is the conversion, the compression recipe and the qualification evidence, not the weights.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for visible-cx/LFM2.5-8B-A1B-CoreAI

Quantized
(84)
this model