|
Download README.md from mlboydaisuke/Kev-0.8B-CoreAI: direct link, hf CLI and curl.
- Browser
- Download file 33.9 kB
-
https://huggingface.co/mlboydaisuke/Kev-0.8B-CoreAI/resolve/main/README.md
- Command line
-
hf download hf://mlboydaisuke/Kev-0.8B-CoreAI/README.md
-
curl -L -o README.md https://huggingface.co/mlboydaisuke/Kev-0.8B-CoreAI/resolve/main/README.md
33.9 kB
| license: apache-2.0 | |
| base_model: jaredpalmer/kev-0.8b | |
| base_model_relation: quantized | |
| pipeline_tag: text-classification | |
| library_name: coreai | |
| language: | |
| - en | |
| tags: | |
| - coreai | |
| - core-ai | |
| - apple | |
| - on-device | |
| - iphone | |
| - decision-model | |
| - systemone | |
| - typed-decisions | |
| - structured-output | |
| # Kev-0.8B — Core AI | |
| Apple Core AI (`.aimodel`) conversion of [jaredpalmer/kev-0.8b](https://huggingface.co/jaredpalmer/kev-0.8b/tree/bf75a6a8848ea6960ff2ed108d9ed44c2941174f) (tag `v1.0`, Apache-2.0): a state and typed questions in, the probability of every option of every question out. | |
| | Variant | Path | Size | Requires | Tested on | | |
| |---|---|---:|---|---| | |
| | Decoder, fp16, with the host's pointer head | `gpu-pipelined/kev_0_8b_decode_fp16_metal_pf128/` | 1,520 MB | macOS 27 / iOS 27 | M4 Max, macOS 27.0 (26A428), 2026-10-04; iPhone 18 Pro, iOS 27.0 (24A437), 2026-10-04 | | |
| One question of 94 tokens takes 29.9 ms on the M4 Max and 37.8 ms on the iPhone 18 Pro, in Swift ([measured below](#time-per-decision-on-the-mac)). | |
| ```swift | |
| import Kev | |
| let bundle = URL(filePath: "Kev-0.8B-CoreAI/gpu-pipelined/kev_0_8b_decode_fp16_metal_pf128") | |
| let kev = try await KevDecider(bundle: bundle) // asset: nil = the .aimodel, specialized here (GPU, frequent reshapes) | |
| let response = try await kev.decide(requestJSON: requestData, shared: true) // shared: the state's whole calls run once | |
| print(PythonFormat.dumps(response, asciiOnly: false)) | |
| ``` | |
| The snippet uses the [`Kev`](https://github.com/john-rocky/coreai-model-zoo/tree/main/apps/Kev) Swift package from the model zoo. The zoo card and the gate scripts live in [coreai-model-zoo](https://github.com/john-rocky/coreai-model-zoo/blob/main/models/kev-0.8b/README.md); the rest of this page is the same text with repository links. | |
| Source [jaredpalmer/kev-0.8b](https://huggingface.co/jaredpalmer/kev-0.8b/tree/bf75a6a8848ea6960ff2ed108d9ed44c2941174f) (tag `v1.0`, commit `bf75a6a`) · base [Qwen/Qwen3.5-0.8B-Base](https://huggingface.co/Qwen/Qwen3.5-0.8B-Base/tree/dc7cdfe2ee4154fa7e30f5b51ca41bfa40174e68) (revision `dc7cdfe`) | |
| A **decision model**. Give it a state (text, or a JSON object or array) and typed questions: `noul` | |
| (yes / no), `choice` (named options) or `score` (ordered levels). It returns a probability for every | |
| option of every question. It never generates text. Requests and responses use the SystemOne-compatible | |
| request shape: `{model, state, questions}` in, `{model, answers, usage}` out, one typed decision per | |
| question. | |
| Jared Palmer trained it as a rank-16 LoRA adapter and a pointer head on Qwen3.5-0.8B-Base (24 layers: | |
| 18 Gated DeltaNet and 6 full attention, hidden size 1,024). The author's card: "It reads one document | |
| (the *state*) and a set of typed questions about it, and returns a calibrated probability distribution | |
| over the options supplied with each question, in a single forward pass and without generating text." | |
| Each question is its own row: the state, then the question and its options. The head scores each | |
| option's closing token against the question's last token. The author's card reports benchmark | |
| results; none of them are re-measured here. | |
| This port merges the adapter into the base with the author's own merge script and exports the text | |
| backbone as one Core AI graph. The graph takes 128 token ids per call and returns the final-norm hidden | |
| state at every position; it has no vocabulary head. Each Gated DeltaNet layer runs its recurrence in an | |
| fp32 Metal kernel, one GPU dispatch per layer per call. Weights are fp16 (1.51 GB). The host runs the | |
| pointer head from the author's head weights. The gate is probability parity with the author's own fp32 | |
| code, on every option of every question, on a fixture of 434 questions and on a held-out set of 130. | |
| It runs on the Mac GPU and on an iPhone 18 Pro. On both, the shipped `.aimodel` is specialized where it | |
| runs. | |
| ## Readout contract | |
| One row per question, every row from zeroed states. The ids are the author's `kev.model.encode` in its | |
| row form (`rows_of`), with the base model's tokenizer: | |
| ``` | |
| [<|fim_prefix|>] + render(state) + [<|fim_middle|>] + render(instructions) | |
| + for each option: [<|box_start|>] + option_text + [<|box_end|>] | |
| + [<|fim_suffix|>] | |
| ``` | |
| - Delimiters, from the base tokenizer: `<|fim_prefix|>` 248060 (state), `<|fim_middle|>` 248061 | |
| (question), `<|box_start|>` 248049 / `<|box_end|>` 248050 (an option), `<|fim_suffix|>` 248062 | |
| (decide). Pad = eos = `<|endoftext|>` 248044; no bos. The `kev-4b` repository still carries Qwen3-era | |
| `added_tokens.json` with other ids; the author's loader reads the tokenizer from the base, and so | |
| does this port. | |
| - User text is tokenized without special tokens after `<|name|>` is rewritten to `<¦name¦>` | |
| (`user_tokens`), so a request can never produce a delimiter. | |
| - `render()` (`kev.api.to_record`): a string as is; an object or an array as `key: value` lines (`- ` | |
| for array items, nesting indented by two spaces), values as Python's `str()`. Options: `noul` = | |
| `no[: <criteria.false>]`, `yes[: <criteria.true>]`, in that order; `choice` = `name` or | |
| `name: <description>` in criteria order; `score` = the levels in order. Keys: `choice` = the criteria | |
| names, `noul` = `false`, `true`, `score` = `"0"`..`"n-1"`. | |
| - The head reads the hidden state at `<|fim_suffix|>` (the row's last token) and at every | |
| `<|box_end|>`: `z_k = ((W_k h_opt_k + b_k) · (W_q h_decide + b_q)) / 16`, `p = softmax(z / T)` within | |
| the question, T = 2.3510958125672174 (the author's calibration, stored in `head.pt`). `W_q`, `W_k` | |
| are `[256, 1024]` with biases, fp32. | |
| - Response (`kev.api.to_answers`): `noul` → p(true); `choice` → the argmax key, a confidence | |
| `(p_max − 1/K) / (1 − 1/K)` and every p; `score` → Σ level · p, the legend, every p and a confidence | |
| `max(0, 1 − E|level − mode| / D)`; values rounded to 4 decimals. `usage` = `{input_tokens, | |
| output_tokens}` with the author's counting (the packed request; the tokens of `json.dumps(answers)`). | |
| - Length: a row holds at most **3,968 tokens**. The last call is padded to 128 tokens and must end at or | |
| below the graph's position bound of 4,095. The author's server accepts states of 65,536 tokens; here a | |
| longer row is refused before any call. | |
| - Shared prefix (optional, exact): every row of a request starts with the same state tokens, so the | |
| state's whole calls (⌊Ls / 128⌋ of them) can run once, the four states be copied per question, and each row | |
| continue from there. Every row's hidden state equals its direct run bit for bit (below). | |
| `conversion/kev/oracle_kev.py` runs the author's package unchanged (`Checkpoint.load("cpu", fp32)`, | |
| `kev.model.admit`, the row-form `forward`, one CPU thread) and records the reference: | |
| [`fixtures-kev-0.8b.json`](https://github.com/john-rocky/coreai-model-zoo/blob/main/models/kev-0.8b/fixtures-kev-0.8b.json). The fixture is 384 records and 434 questions: | |
| lines 1–60 of the author's transfer-v4 development file (`evals/v4/transfer-v4/development.jsonl`, | |
| tag `kev-1.0`; MMLU, 4 options), records 1–20 of each of its seven other sources (140, `choice` and | |
| `noul`), its `score` records 1–20, the 144 `choice` items of SemIf authored144, and 20 records | |
| written for the port (70 questions: `noul`, `choice` with 2–10 options, `score` with 2–7 levels, | |
| JSON states, three states of 1,431–1,746 tokens, one record of 8 questions). The longest row is 1,802 | |
| tokens. Fourteen questions have an oracle top-2 margin of 0.02 or less (near-ties) and are listed apart. | |
| The held-out set is the next 130 transfer-v4 records (mmlu 61–100, records 21–30 of each other source, | |
| `score` records 21–40), with its own oracle run. | |
| ## Core AI shape | |
| `conversion/kev/qwen3_5_kev_decoder.py`: the overlay's stateful Qwen3.5 text decoder | |
| (`Qwen3_5StatefulForCausalLM`) on the merged weights, the vocabulary head replaced by the identity, the | |
| output the final-norm hidden state at every position. One function, `main`, at a static 128 tokens. Each | |
| Gated DeltaNet layer runs its recurrence in the overlay's fp32 Metal chunk kernel | |
| (`qwen3_5_gdn_metal`): one GPU dispatch per layer per call, the recurrent state kept in fp32 through the | |
| call. | |
| | | name | shape, type | | |
| |---|---|---| | |
| | inputs | `input_ids` | [1, 128] int32 | | |
| | | `position_ids` | [1, seq] int32, the ramp 0 .. seq − 1 | | |
| | states | `keyCache`, `valueCache` | [6, 1, 2, ctx, 256] fp16, ctx up to 4,096 | | |
| | | `convState`, `recState` | [18, 1, 6144, 3], [18, 1, 16, 128, 128] fp16 | | |
| | output | `hidden` | [1, 128, 1024] fp16, every position | | |
| Per row of T ids, from zeroed states: ⌈T / 128⌉ calls, call k with ids[128k : 128k + 128] and position_ids | |
| 0..128k + 127. The last call is padded with `<|endoftext|>` (248044) and its padded rows are dropped. The | |
| rows of every call, cut to T, are the backbone's final-norm `last_hidden_state [T, 1024]`. The bundle's | |
| `metadata.json` says `kind: decision-backbone` and `language.prefill_chunk: 128`, and carries this order, | |
| the row layout, the delimiter ids, the render rules, the head formula and the response shape. | |
| **Host.** Builds the rows, runs the calls, converts the hidden rows at the readout positions to float64, | |
| applies the head (`head/head.safetensors`, `head/kev_head.json`) and the per-question softmax in float64, | |
| rounds p to fp32 once, and writes the response. `conversion/kev/decide.py` is the Python reference; | |
| [`apps/Kev`](https://github.com/john-rocky/coreai-model-zoo/tree/main/apps/Kev) is the Swift one. With `shared: true` the state's whole calls run once. A | |
| prepared state (`prepare(state:)`, then `decide(prepared:questionsJSON:)`) runs the same calls in two steps, | |
| so questions that arrive later skip the state. | |
| No engine is involved: the hosts drive the low-level runtime (`AIModel` + `loadFunction`, four zeroed | |
| states per row). No runtime patch. | |
| ## Measured (Apple M4 Max, macOS 27.0 26A428, 2026-10-03 – 10-04) | |
| The bar, fixed before any graph ran: the argmax equal to the oracle's on every question whose oracle | |
| top-2 margin is above 0.02 (near-ties listed apart), max |Δp| ≤ 0.02 over every option of every | |
| question, the mean over rows of each row's mean |Δp| ≤ 0.002, and every process re-running its opening row | |
| bit for bit. The Python gates load the AOT `.aimodelc` (`coreai-build compile … --platform macOS | |
| --preferred-compute gpu --architecture h16c --expect-frequent-reshapes`) with | |
| `SpecializationOptions.default()`. | |
| ### Before any graph: the merge and fp32 torch | |
| - The merged checkpoint (`scripts/merge_lora_checkpoint.py`, tag `kev-1.0`; fp32, 320 tensors, 186 of | |
| them adapted, `model.safetensors` sha256 `b5ebf92a…`) answers through the author's own loader as the | |
| adapter checkpoint does: 434/434 questions, logits bit-equal. `W + (B @ A) × 2` reproduces three | |
| merged tensors bit for bit (the adapter moves them by 2.8–3.6 %). The base alone moves p by up to | |
| 0.789 (argmax 25/53), the base's Gated DeltaNet projections put back by up to 0.282 (46/53): the | |
| check can fail ([`gate-kev-0.8b-merge.json`](https://github.com/john-rocky/coreai-model-zoo/blob/main/models/kev-0.8b/gate-kev-0.8b-merge.json)). | |
| - The decoder module in fp32 on the CPU, driven like the graph with the recurrence unrolled, read through | |
| the author's head: 434/434 argmax (the 14 near-ties included), max |Δp| 3.5e-6, lowest per-position | |
| hidden cosine 0.99999999999 on the 21 rows the oracle keeps. It equals the overlay's plain text decoder | |
| bit for bit (3 rows) ([`gate-kev-0.8b-torch-parity.json`](https://github.com/john-rocky/coreai-model-zoo/blob/main/models/kev-0.8b/gate-kev-0.8b-torch-parity.json)). | |
| - The Metal kernel has no torch values: its `torch_defn` returns zeros of the right shapes. The GPU gate | |
| below is its parity check. | |
| ### The graph alone on the Mac GPU | |
| The oracle's ids in, the fp16 hidden rows read through the author's fp32 head: | |
| | set | questions | argmax (margin > 0.02) | near-ties agreeing | max \|Δp\| | mean of row means | bar | | |
| |---|---:|---:|---:|---:|---:|---| | |
| | **fixture** | 434 | **420/420** | **13/14** | **0.0124** | **0.00096** | **PASS** | | |
| | held out | 130 | 125/125 | 5/5 | 0.0058 | 0.00083 | PASS | | |
| The near-tie that flips is a SemIf item with an oracle margin of 0.0032; it moves by 0.0026. The worst | |
| row is a SemIf item (0.0124). Every value is finite and every process's re-run is bit-equal. Two red arms | |
| move p on the same graph: a state swapped for another record's moves 4 of 5 argmaxes (max |Δp| 0.905); a | |
| grammatical "not" in five yes / no questions moves 2 of 5 (0.759). Transcript: | |
| [`gate-kev-0.8b-readout.json`](https://github.com/john-rocky/coreai-model-zoo/blob/main/models/kev-0.8b/gate-kev-0.8b-readout.json). | |
| ### From the request: Python and Swift | |
| - `conversion/kev/host.py`, without the author's package, rebuilds every oracle row from the raw | |
| request (ids, `<|fim_suffix|>` / `<|box_end|>` indices, keys): 434/434 and 130/130 rows with two | |
| tokenizer implementations. `decide.py` on the AOT graph: hidden rows bit-equal to the gate's on 434/434 | |
| and 130/130 rows ([`gate-kev-0.8b-host.json`](https://github.com/john-rocky/coreai-model-zoo/blob/main/models/kev-0.8b/gate-kev-0.8b-host.json)). | |
| - The Swift host ([`apps/Kev`](https://github.com/john-rocky/coreai-model-zoo/tree/main/apps/Kev), Release): ids from the raw request 434/434 and 130/130; | |
| on the same AOT asset every row's hidden state and every p equal the Python reference's bit for bit | |
| (434/434), every answer set's `json.dumps` and usage byte for byte (384/384), and the bar is the gate's | |
| (fixture 0.0124 / 0.00096). With the shared prefix every row's hidden state and p equal the direct run's | |
| (434/434). Its text half equals CPython on 2,787 rendered values, 599 requests (21 refused with the | |
| same messages), 203,635 doubles (`str`, `repr`, `round`) and 1,093 `json.dumps` texts. One word changed | |
| in one question turns its record red. | |
| - JIT: the `.aimodel` specialized by the Swift runtime (GPU preferred, `expectFrequentReshapes`) equals | |
| the AOT asset bit for bit on 25 rows of 10 records. The specialization took 3.34 s (4.05 s with the | |
| tokenizer and the head); with the runtime's cache warm a load took 0.69 s | |
| ([`gate-kev-0.8b-swift.json`](https://github.com/john-rocky/coreai-model-zoo/blob/main/models/kev-0.8b/gate-kev-0.8b-swift.json)). | |
| ### Time per decision on the Mac | |
| Swift, Release CLI, the AOT asset, in one machine-wide GPU lock window (2026-10-04 12:13–12:27 JST). Two | |
| processes per graph counted only when no other GPU job ran and the one-minute load average was at most 12; | |
| each made 10 decisions per item after one warm-up, and the table gives the median (p10–p90) over the 20. | |
| The earlier upload's graph (below, under Bundle) ran in the same window: | |
| | request | tokens | calls | ms | p10–p90 | earlier upload's graph, ms | | |
| |---|---:|---:|---:|---|---:| | |
| | one question | 94 | 1 | 29.9 | 29.6–30.1 | 100.1 | | |
| | one question | 380 | 3 | 89.2 | 88.7–90.4 | 404.4 | | |
| | one question | 1,518 | 12 | 357.0 | 355.4–359.3 | 1,600.1 | | |
| | one question | 1,802 | 15 | 447.9 | 446.6–449.8 | 1,897.6 | | |
| | five questions on one 137-token state, each row from zero | 240 | 10 | 296.6 | 294.6–298.5 | 845.7 | | |
| | the same five questions, the state run once (shared) | 240 | 6 | 186.4 | 185.4–187.7 | 327.7 | | |
| | eight questions on that state, each row from zero | 320 | 16 | 474.2 | 472.2–475.9 | 1,377.0 | | |
| | the same eight questions, shared | 320 | 9 | 278.8 | 277.2–281.7 | 461.0 | | |
| | four questions on one 1,477-token state, each row from zero | 1,622 | 49 | 1,455.9 | 1,453.7–1,460.4 | 6,366.1 | | |
| | the same four questions, shared | 1,622 | 16 | 485.4 | 483.8–489.4 | 1,749.0 | | |
| | a follow-up question on a prepared 137-token state | — | — | 30.3 | — | 34.1 | | |
| | a follow-up question on a prepared 1,477-token state | — | — | 31.5 | — | 51.5 | | |
| Preparing the two states took 34.1–34.7 ms and 335.9–339.6 ms (the two processes' medians). In round 11's | |
| lock window (09:43–10:45 JST) the `.aimodel` specialized by Swift, the shipped path, took 29.7 ms for the | |
| 94-token question and 186.5 ms for the five questions shared, against 30.0 and 189.1 ms for the AOT asset; | |
| the Python reference took 33.4 and 207.1 ms. Transcript: [`gate-kev-0.8b-timing-mac.json`](https://github.com/john-rocky/coreai-model-zoo/blob/main/models/kev-0.8b/gate-kev-0.8b-timing-mac.json). | |
| ### iPhone 18 Pro (iOS 27.0 24A437, Core AI arch h19p, 2026-10-04) | |
| Through [`apps/KevGate`](https://github.com/john-rocky/coreai-model-zoo/tree/main/apps/KevGate), a headless gate app on the Swift host, Release, without the | |
| increased-memory-limit entitlement (3,529 MB available at launch). The phone was on USB power, the | |
| battery at 80 % and charging; every bench item started at thermal state nominal. Every p the app wrote | |
| was re-scored on the Mac from its bit patterns. | |
| - **Load.** The `.aimodel` specialized on the phone (GPU preferred, `expectFrequentReshapes`) took 4.26 s cold, | |
| 3.60 s of it in `AIModel(contentsOf:)`, with +2,502,056,463 B of runtime cache and a peak footprint of 233 MB | |
| (round 13, an earlier KevGate build). With the cache warm, the gate run below loaded it in 1.50 s. | |
| - **Gate** (run `20261004-140048`, KevGate built on round 15's host): | |
| | set | questions | argmax (margin > 0.02) | near-ties agreeing | max \|Δp\| | mean of row means | bar | | |
| |---|---:|---:|---:|---:|---:|---| | |
| | fixture | 434 | 420/420 | 13/14 | 0.0110 | 0.00097 | PASS | | |
| | held out | 130 | 125/125 | 5/5 | 0.0059 | 0.00083 | PASS | | |
| The shared prefix equals the direct run on all 20 multi-question records, and the re-run of the opening | |
| record is bit-equal. No hidden row equals the Mac's (a different GPU): their p differ by at most 0.0026, | |
| with every argmax equal (434/434). The fixture pass peaked at a 389 MB footprint. | |
| - **Bench** (60 s of rest before each item, one warm-up, then 5 decisions; `latency_ms` = state resets, | |
| graph calls and the head). The earlier upload's graph ran in the same session: | |
| | request | tokens | ms | earlier upload's graph, ms | | |
| |---|---:|---:|---:| | |
| | one question | 94 | 37.8 | 156.7 | | |
| | one question | 380 | 110.6 | 627.9 | | |
| | one question | 1,518 | 444.1 | 2,500.9 | | |
| | one question | 1,802 | 559.1 | 2,977.8 | | |
| | five questions on one 137-token state, each row from zero / shared | 240 | 361.9 / 223.2 | 1,331.4 / 507.4 | | |
| | eight questions on that state, each row from zero / shared | 320 | 583.2 / 333.4 | 2,167.4 / 723.3 | | |
| | four questions on one 1,477-token state, each row from zero / shared | 1,622 | 1,822.2 / 613.9 | 10,061.6 / 2,769.8 | | |
| | the five questions on a prepared state (the prepare: 38.8 / 211.6 ms) | 240 | 183.4 | 295.5 | | |
| | the four questions on a prepared state (the prepare: 415.3 / 2,451.4 ms) | 1,622 | 196.5 | 342.4 | | |
| An earlier session on the same phone, with an earlier KevGate build, gave 36.5 ms for the 94-token question | |
| against 157.1 ms for the earlier upload's graph. Transcript: [`gate-kev-0.8b-iphone.json`](https://github.com/john-rocky/coreai-model-zoo/blob/main/models/kev-0.8b/gate-kev-0.8b-iphone.json). | |
| Kev-4B on the phone: see the [Kev-4B card](https://github.com/john-rocky/coreai-model-zoo/blob/main/models/kev-4b/README.md). | |
| ## Forms measured | |
| Every form below was exported, compiled and gated the same way. The times come from different windows, so | |
| compare forms only within one window. Full records: [`gate-kev-0.8b-forms.json`](https://github.com/john-rocky/coreai-model-zoo/blob/main/models/kev-0.8b/gate-kev-0.8b-forms.json). | |
| Mac (Swift Release CLI, the 94-token question, median of the counted processes): | |
| | form | 94-token decision, ms | window | fixture max \|Δp\| | note | | |
| |---|---:|---|---:|---| | |
| | Gated DeltaNet unrolled, S = 16 (the earlier upload) | 100.1 | round 15 | 0.0117 | | | |
| | unrolled, S = 32 | 139.0 | round 11 | 0.0118 | | | |
| | unrolled, S = 64 | — | — | 0.0100 | not timed in a lock window (68.06 ms per call on a shared GPU) | | |
| | in-graph chunk scan, S = 16 | — | — | 0.0135 | not timed in a lock window (10.90 ms per call on a shared GPU) | | |
| | in-graph chunk scan, S = 32 | — | — | — | fails: non-near-tie argmax 112/127, max \|Δp\| 0.125, non-finite rows; breaks in fp32 torch too | | |
| | Metal kernel, S = 16 / 32 / 64 | 63.6 / 42.7 / 41.5 | round 11 | 0.0115 / 0.0134 / 0.0115 | | | |
| | **Metal kernel, S = 128 (this release)** | **29.9** | round 15 | **0.0124** | | | |
| | Metal kernel, query length 2..512, host calls of at most 512 ids | 25.2 | round 15 | 0.0112 | not shipped: memory grows (below) | | |
| | the same graph, host calls of at most 256 / 128 ids | 25.1 / 25.0 | round 15 | 0.0060 / 0.0060 (130 rows) | not shipped | | |
| | int8, every linear (unrolled S = 16) | — | — | 0.0431 | fails the bar (Precision) | | |
| | any form on the Neural Engine | — | — | — | not run: the recurrence's fp32 state is not an ANE element type ([`qwen3.5-static-ane.md`](https://github.com/john-rocky/coreai-model-zoo/blob/main/knowledge/qwen3.5-static-ane.md)) | | |
| iPhone 18 Pro (KevGate bench, the 94-token question): | |
| | form | ms | session | fixture max \|Δp\| | | |
| |---|---:|---|---:| | |
| | unrolled, S = 16 (the earlier upload) | 156.7 | round 13, stage C | 0.0102 | | |
| | Metal kernel, S = 16 / 32 / 64 | 92.4 / 58.5 / 49.3 | round 13, stage A | 0.0110 / 0.0133 / 0.0098 | | |
| | **Metal kernel, S = 128 (this release)** | **37.8** | round 13, stage C | **0.0110** | | |
| | Metal kernel, query length 2..512, host calls of at most 512 ids | 32.6 | round 13, stage C | gate stopped by memory (below) | | |
| **Several short questions on one state.** For these, the S = 64 graph takes less time than S = 128. In | |
| round 11's Mac window, five questions on one 137-token state, shared, took 145.0 ms with S = 64 and | |
| 189.1 ms with S = 128; one 94-token question took 41.5 and 30.0 ms. On the iPhone (round 13, stage A) | |
| the same pairs took 180.3 against 224.4 ms and 49.3 against 36.5 ms. The S = 64 bundle is not in this | |
| release: it would need a new export and a new gate. | |
| **Why the dynamic-length graph does not ship.** The graph whose query length is dynamic (2..512) passed the | |
| gate on the Mac and decided the 94-token question in 25.2 ms. A process that keeps changing its call length | |
| keeps growing, though. Cycling four call lengths (128, 256, 384, 512) three times added 467.1, 166.9 and | |
| 168.5 MB per lap in Swift and 460.7, 169.5 and 169.6 MB in Python. Alternating between two lengths did not | |
| grow after the opening calls; bringing in a third added 19.1 MB, then 1.3 MB. On the iPhone the gate run | |
| reached 3,497 MB with 43 MB available after 439 calls and stopped writing. A 2-second sleep gave back part of | |
| the memory and loading the function again gave back none; creating the `AIModel` again gave it back. Records: | |
| [`gate-kev-0.8b-forms.json`](https://github.com/john-rocky/coreai-model-zoo/blob/main/models/kev-0.8b/gate-kev-0.8b-forms.json); notes: | |
| [`knowledge/kev-port.md`](https://github.com/john-rocky/coreai-model-zoo/blob/main/knowledge/kev-port.md). | |
| ## Precision | |
| **int8 was measured and is not shipped.** It was measured on the unrolled S = 16 graph, the earlier upload; | |
| the Metal-kernel graphs were not measured in int8. int8 per block of 32 over every decoder linear | |
| (`symmetric_with_clipping`, weights only; the embedding table, the Gated DeltaNet conv1d and every norm | |
| fp16) fails the bar: | |
| | decoder (unrolled S = 16) | `main.mlirb` bytes | fixture max \|Δp\| / mean | held out max \|Δp\| / mean | bar | | |
| |---|---:|---:|---:|---| | |
| | fp16 | 1,506,481,909 | 0.0117 / 0.00097 | 0.0057 / 0.00081 | PASS | | |
| | int8lin: every linear int8 | 1,040,063,350 | 0.0431 / 0.00326 | 0.0273 / 0.00294 | FAIL | | |
| | int8mix: int8 except layers 0–11 | 1,273,276,920 | 0.0089 / 0.00103 | 0.0043 / 0.00082 | PASS | | |
| int8lin breaks the bar on 10 fixture rows (above 0.01: 51 rows; fp16: 1). An fp32 torch bisect with the | |
| exporter's own int8 weights (`conversion/kev/int8_bisect_torch.py`, 60 rows) reproduces it (0.0420 | |
| against the graph's 0.0431). Its rule, written before any result, asked for the worst row below 0.010 | |
| with at most half of the linear weights kept fp16; no set met it (the best: four kinds of linear kept | |
| fp16, 45.5 % of the weights, 0.0141). Layers 0–11 kept fp16, exactly half and outside the rule's search, | |
| give 0.0046 on the bisect rows; that is int8mix. It keeps 85 % of fp16's bytes, and it was chosen on the | |
| fixture, so it does not ship ([`gate-kev-0.8b-int8.json`](https://github.com/john-rocky/coreai-model-zoo/blob/main/models/kev-0.8b/gate-kev-0.8b-int8.json)). | |
| **What the compiled asset holds.** `--expect-frequent-reshapes` adds an fp16 copy of every linear weight | |
| to the compiled asset: for the unrolled graph the iPhone h19p asset is 2,505,674,625 bytes with it and | |
| 1,506,400,620 without, and this release's Mac h16c asset is 2,502,047,194 bytes against a 1,505,385,733-byte | |
| `main.mlirb`. On a toy (an embedding and two linears) compiled with a fixed input length, the int8 | |
| version's `resources.bin` is 12,582,936 bytes on macOS and iOS, with and without the flag, the bytes of | |
| the fp16 toy compiled without it, against an int8 `main.mlirb` of 10,623,080 bytes. An int8 `.aimodel` | |
| downloads smaller; the compiled asset is not smaller by the same amount | |
| ([`../kev-4b/gate-kev-4b-int8.json`](https://github.com/john-rocky/coreai-model-zoo/blob/main/models/kev-4b/gate-kev-4b-int8.json)). | |
| ## ⬇️ Bundle | |
| [mlboydaisuke/Kev-0.8B-CoreAI](https://huggingface.co/mlboydaisuke/Kev-0.8B-CoreAI), one folder under | |
| `gpu-pipelined/`: | |
| | file | what | bytes | sha256 | | |
| |---|---|---:|---| | |
| | `kev_0_8b_decode_fp16_metal_pf128.aimodel/main.mlirb` | the decoder, fp16 | 1,505,385,733 | `19d5a480…2c3f684e` | | |
| | `metadata.json` | `kind: decision-backbone`, the readout contract, the gate | 12,590 | `6e50e41a…47282227` | | |
| | `tokenizer/tokenizer.json` | the base model's, verbatim | 12,807,196 | `fe000e3e…d50d2927` | | |
| | `tokenizer/tokenizer_config.json` | the base model's, verbatim | 16,712 | `e611fbcc…c47885de` | | |
| | `head/head.safetensors` | the pointer head: q / k weight `[256, 1024]` and bias, fp32 | 2,099,576 | `12038b02…00893a42` | | |
| | `head/kev_head.json` | head size, scale, temperature, delimiter ids, provenance | 2,046 | `73d51070…9d5c9d7c` | | |
| The repository root carries the base model's `config.json`, the adapter's `adapter_config.json` and the | |
| Apache-2.0 `LICENSE`, verbatim. `SHA256SUMS` lists every file. Its Hub revision is | |
| [`3792e4b`](https://huggingface.co/mlboydaisuke/Kev-0.8B-CoreAI/tree/3792e4bf4ff6337afaa774b2a229580bcc0493e5) (2026-10-04). | |
| **The earlier upload.** Hub revision | |
| [`7793533`](https://huggingface.co/mlboydaisuke/Kev-0.8B-CoreAI/tree/7793533783de7c8f916c1cba1144a561fb70b321) | |
| held another graph of this port, `kev_0_8b_decode_fp16_pf16`: the Gated DeltaNet recurrence unrolled step by | |
| step, 16 tokens per call. It passed the same gate (fixture max |Δp| 0.0117, held out 0.0057). In the Mac | |
| window above it took 100.1 ms for the 94-token question against 29.9 ms for this release, and on the iPhone | |
| 156.7 ms against 37.8 ms. | |
| No AOT asset ships: the Swift runtime specializes the `.aimodel` correctly on the Mac and on the phone (the | |
| JIT rows above). To compile one for the Mac anyway: | |
| ```bash | |
| xcrun coreai-build compile kev_0_8b_decode_fp16_metal_pf128.aimodel --output aot --preferred-compute gpu \ | |
| --platform macOS --architecture h16c --expect-frequent-reshapes | |
| ``` | |
| ## Use it | |
| Swift, with the [`Kev`](https://github.com/john-rocky/coreai-model-zoo/tree/main/apps/Kev) package (macOS 27 / iOS 27; the system CoreAI framework, | |
| Accelerate and swift-transformers' tokenizer), on a download of the repository: | |
| ```swift | |
| import Kev | |
| let bundle = URL(filePath: "Kev-0.8B-CoreAI/gpu-pipelined/kev_0_8b_decode_fp16_metal_pf128") | |
| let kev = try await KevDecider(bundle: bundle) // asset: nil = the .aimodel, specialized here (GPU, frequent reshapes) | |
| let response = try await kev.decide(requestJSON: requestData, shared: true) // shared: the state's whole calls run once | |
| print(PythonFormat.dumps(response, asciiOnly: false)) | |
| // {"model": "kev_0_8b_decode_fp16_metal_pf128", "answers": {"team": {"type": "choice", "choice": "billing", "confidence": …, | |
| // "probabilities": {…}}, "urgent": {"type": "noul", "noul": …}}, "usage": {"input_tokens": …, "output_tokens": …}, "latency_ms": …} | |
| // questions that arrive later, on the same state | |
| let prepared = try await kev.prepare(state: try JSONParser.parse(stateData)) // the state's whole calls, once | |
| let later = try await kev.decide(prepared: prepared, questionsJSON: questionsData) // only the questions' rows run | |
| ``` | |
| The same from the Mac CLI (`swift build -c release --package-path apps/Kev` builds `kev`): | |
| ```bash | |
| kev run --bundle Kev-0.8B-CoreAI/gpu-pipelined/kev_0_8b_decode_fp16_metal_pf128 --asset jit \ | |
| --request req.json --shared --out resp.json | |
| ``` | |
| A request, in the SystemOne-compatible request shape: | |
| ```json | |
| {"model": "kev-0.8b", | |
| "state": "I was charged twice for my last order. Please refund one of the charges.", | |
| "questions": { | |
| "team": {"type": "choice", "instructions": "Which team should handle this?", | |
| "criteria": {"billing": "Charges and refunds", "shipping": "Deliveries", "returns": "Exchanges"}}, | |
| "urgent": {"type": "noul", "instructions": "Does this need a reply today?"}}} | |
| ``` | |
| Python: `conversion/kev/decide.py run --model kev-0.8b --bundle <folder> --aimodelc <asset> --request | |
| req.json [--shared] --out resp.json` is the gates' own read-out with `coreai.runtime`. It loads an AOT | |
| `.aimodelc` (compile one with the command above); the Python gates never used the Python runtime's JIT. | |
| ## Reproduce | |
| Environment: the zoo overlay venv (coreai-core 1.0.0b2, coreai-torch 0.4.1, torch 2.9.0, transformers | |
| 4.57.6), Xcode 27.0 RC. The author's code (the oracle and the merge) runs in its own venv built from the | |
| author's `uv.lock` at tag `kev-1.0` (torch 2.8.0, transformers 5.17.0, peft 0.21.0). The steps, in order, | |
| with every flag, are in [`conversion/kev/README.md`](https://github.com/john-rocky/coreai-model-zoo/blob/main/conversion/kev/README.md). | |
| ```bash | |
| # the merged checkpoint, with the author's script (tag kev-1.0) | |
| (cd $ZOO_WORK_ROOT/_kev/kev-src && python scripts/merge_lora_checkpoint.py \ | |
| --lora jaredpalmer/kev-0.8b@788ddbdd65715bb03a56788c822f6c632c9a551d --out $ZOO_WORK_ROOT/_kev/merged/kev-0.8b-v1.0) | |
| # the decoder (--aot adds the h16c .aimodelc the Python gates load) | |
| python conversion/kev/export_decoder.py fp16 --gdn-scan metal --prefill-chunk 128 --aot | |
| # the published bundle: the gated .aimodel bytes and their metadata, without exporting again | |
| python conversion/kev/export_decoder.py fp16 --gdn-scan metal --prefill-chunk 128 --metadata-only \ | |
| --from-aimodel <bundles>/kev_0_8b_decode_fp16_metal_pf128/kev_0_8b_decode_fp16_metal_pf128.aimodel \ | |
| --bundle-dir <ship>/kev_0_8b_decode_fp16_metal_pf128 | |
| ``` | |
| Recipe: [`recipe.toml`](https://github.com/john-rocky/coreai-model-zoo/blob/main/models/kev-0.8b/recipe.toml). Port notes: [`knowledge/kev-port.md`](https://github.com/john-rocky/coreai-model-zoo/blob/main/knowledge/kev-port.md). | |
| ## Other formats | |
| On the Hub (2026-10-04), not run here: | |
| - Core ML: [`FluidInference/kev-0.8b-coreml`](https://huggingface.co/FluidInference/kev-0.8b-coreml), a | |
| different runtime (Core ML packages for iOS 18 / macOS 15, fp16 on the GPU): a fused multifunction | |
| package that packs a request's questions into one call, row packages, and the pointer head. | |
| - ONNX: [`midudev/kev-0.8b-ONNX`](https://huggingface.co/midudev/kev-0.8b-ONNX) (ONNX Runtime Web, int4 | |
| weights with the Gated DeltaNet projections and MLPs int8, the pointer head as `head.bin`). | |
| - GGUF: [`ggml-org/Kev-0.8B-GGUF`](https://huggingface.co/ggml-org/Kev-0.8B-GGUF) ("a decision model, | |
| to be used via `/v1/systemone` API", per its card). | |
| - RKLLM: [`ShiWarai/kev-0.8b-rknn`](https://huggingface.co/ShiWarai/kev-0.8b-rknn) (Rockchip RK3588, | |
| w8a8, the pointer head in NumPy on the CPU, rows up to 320 tokens). | |
| - Merged weights: [`ayan4m1/kev-0.8b-merged`](https://huggingface.co/ayan4m1/kev-0.8b-merged). | |
| - MLX: the author's repository serves Kev through MLX on Apple silicon. | |
| No other Core AI conversion of Kev was listed on the Hub on 2026-10-04. | |
| ## License | |
| Apache-2.0: the adapter and the head (jaredpalmer/kev-0.8b) and the base (Qwen/Qwen3.5-0.8B-Base); the | |
| bundle inherits it, and the Hugging Face repository carries the base's `LICENSE`. The author's package | |
| runs only in the oracle and the merge, at gate time; it is not part of the bundle. The fixture file | |
| carries its own terms: its 144 SemIf authored144 items are MIT (github.com/TheoLeeCJ/SemIf at | |
| `ca3ba65f`), with their copyright and permission notice; the transfer-v4 records are references to the | |
| author's file (line and row hashes), not its text; of the 20 records written for the port, 11 are | |
| published and 9 are withheld (an invented name in each was found in use on the web), keeping their ids | |
| and numbers. | |
| ## Limits | |
| From the [author's card](https://huggingface.co/jaredpalmer/kev-0.8b): English only; text generation, | |
| chat, tool-call routing and fully automated consequential decisions about people are out of scope; the | |
| temperature was fitted on the author's development rows (the card explains how to measure and refit it on | |
| one's own data). This port adds: | |
| - A row holds at most 3,968 tokens, while the author's server accepts states up to 65,536. | |
| - A process's opening call is slower. On the Mac the opening 128-token call of each Python gate process | |
| took 211–1,188 ms, against a median of 29.9 ms for its later calls. On the phone the opening decision | |
| took 66.9 ms, against 37.8 ms in the bench of the same build. | |
| - If you export this decoder with a dynamic query length yourself, keep the call lengths to one or two | |
| values. A process that cycles more lengths grows its memory until the `AIModel` is created again (measured | |
| on the Mac and the iPhone; which runtime layer keeps the memory is not isolated). | |