Views
No views yet
coreai-torch (LLMs: coreai.llm.export) into .aimodel bundles that run on the GPU or the Neural Engine, e.g. Qwen3-8B 4-bit decodes at 94 tok/s on an M4 Max GPU, MLX 90 under the same protocol (apple-silicon-llm-bench, macOS 27 beta, 2026-06)..aimodel)patches [1024,768] → image_embeds [256,2048], hidden 1152 × 27 layers) and the LFM2 conv+attention
hybrid decoder (hidden 2048, 30 layers = 22 short-conv + 8 GQA attention, vocab 128 000, tied
head), with the image tokens spliced in through a static image_embeds input. No recurrent
scan, so decode is loop-free on Apple's coreai-pipelined GPU engine with no custom kernels.Requires macOS 27 (Core AI ships with the OS). Conversion code, gates and knowledge base: coreai-model-zoo.
| path | size | measured (M4 Max) | numerics |
|---|---|---|---|
gpu-pipelined/lfm2_5_vl_3b_vision_fp16 | 815 MB | 75.7 ms/image | image_embeds cos 0.999995 vs fp32 HF |
gpu-pipelined/lfm2_5_vl_3b_decode_int8lin | 3.1 GB | — | suite 7/9 cases token-exact; logits_last cos 0.999970 |
gpu-pipelined/lfm2_5_vl_3b_decode_int4lin | 2.0 GB | — | suite 7/9 — identical to int8 and to the fp16 baseline |
gpu-pipelined/lfm2_5_vl_3b_decode_int8lin_textcore | 3.1 GB | 120.9 prompt / 105.3 decode tok/s | the same weights with no image input |
coreai-torch 0.4.1,
llm-benchmark -p 128 -g 256 -n 3, COREAI_CHUNK_THRESHOLD=1. The tok/s row is the text
core because llm-runner cannot bind the VLM bundle's image_embeds buffer.ios-h18p/lfm2_5_vl_3b_decode_int4lin + the fp16 towerresources.bin is 3.13 GiB);
int4lin's is 2.03 GiB and does — which is worth stating because the note this port was written
against put the load wall at 2 GiB, and 2.03 GiB was written up as expected-to-fail before a
phone was asked. It loaded. Use int8lin on a Mac and int4lin on a phone; on this model int4
costs nothing (7/9 on the suite, the same cases as fp16).1git clone https://github.com/apple/coreai-models # + the zoo's engine patches, see below
2swift build -c release --product llm-runner
3
4COREAI_CHUNK_THRESHOLD=1 .build/release/llm-runner \
5 --model gpu-pipelined/lfm2_5_vl_3b_decode_int8lin_textcore \
6 --prompt "The alphabet begins A, B, C," \
7 --max-tokens 64 --sampling-strategy greedy \
8 --inference-engine-variant coreai-pipelined --warmup offcoreai-pipelined-extra-states for the conv state,
coreai-pipelined-static-inputs for image_embeds) are in the zoo under apps/.(x/255 − 0.5)/0.5, and patchifies
into 16×16 patches with the channel as the fastest axis ([y][x][c]); then it runs the
vision bundle, binds the output as image_embeds, and rewrites the prompt's <image> ids
(124907) to V + slot. Reference implementation:
_smoke/lfm25vl_preprocess.py.resample: 3 (PIL BICUBIC) where the 450M declares 2 (BILINEAR) — read it off
processor_config.json. And this tokenizer's post-processor does not prepend
<|startoftext|> (the 450M's does), while the chat template starts with it: feed the model a
prompt without BOS and it answers " F, F, F, F" — fluent degeneracy, no error.projector_use_layernorm: false and ships no such
weights, and nn.LayerNorm's default init makes that invisible.patch_embedding.weight is [1152, 768] — a Linear
over pre-flattened patches, not a Conv2d over an image — and position_embedding.weight is
[256, 1152], a 16×16 grid bilinearly resized (antialias) to the actual patch grid. The
tower's 4304-wide MLP is not divisible by 32, so int8 there is per-block-16.conversion/export_lfm25vl_pipelined.py
(--hf-id LiquidAI/LFM2.5-VL-3B — the same script that built the 450M) and
knowledge/lfm2.5-vl-port.md.LiquidAI/LFM2.5-VL-3B (revision
5a414ead75d45db003906d06fb62bd5b6846cec0). Not affiliated with Apple or LiquidAI.