lpalbou commited on
Commit
5d2740c
·
verified ·
1 Parent(s): a74b83d

kev-4b-mlx-4bit: model card

Browse files
Files changed (1) hide show
  1. README.md +55 -11
README.md CHANGED
@@ -12,21 +12,39 @@ pipeline_tag: text-classification
12
 
13
  # Kev-4B for MLX, 4-bit, group 32, with the Gated DeltaNet projections (in_proj_qkv / in_proj_z / in_proj_a / in_proj_b / out_proj) kept at 8-bit
14
 
15
- A decision model: it reads a document (the *state*) and answers typed questions about it — `choice`
16
- over named options, `noul` (the probability a statement is true), `score` over ordered levels — with
17
- calibrated probabilities, in one forward pass, without generating text.
 
18
 
19
- This is [jaredpalmer/kev-4b](https://huggingface.co/jaredpalmer/kev-4b) (Jared Palmer, Apache-2.0: a rank-16 LoRA plus a
20
- pointer head on a Qwen3.5 base) with the adapter folded into the base and the backbone quantized for
21
- [mlx-lm](https://github.com/ml-explore/mlx-lm) at 4-bit, group 32, with the Gated DeltaNet projections (in_proj_qkv / in_proj_z / in_proj_a / in_proj_b / out_proj) kept at 8-bit (3.0 GB). The pointer head
 
 
22
  (`head.safetensors`) stays in float32; `decision.json` records the recipe and the source checkpoint.
23
 
 
 
 
 
 
 
 
 
 
 
24
  ## Measured
25
 
26
  public-pool-v6 development set (1,328 records): accuracy 0.847 (bf16 0.846), Brier 0.226, ECE 0.024; argmax agreement with bf16 0.973, mean |Δp| 0.023, 3.1 % of questions moved by more than 0.10; 113 ms per record on an M5 Max. A plain 4-bit conversion (every linear at 4 bits, group 64) loses a point of accuracy and moves 10.6 % of the answers; this recipe is the measured compromise. Use the 8-bit checkpoint when you threshold probabilities.
27
 
28
  ## Use with AbstractCore
29
 
 
 
 
 
 
30
  ```python
31
  from abstractcore import create_llm
32
 
@@ -39,18 +57,44 @@ result = llm.generate(
39
  "criteria": {"returns": "Exchanges, refunds, wrong or damaged items",
40
  "shipping": "Delivery status, delays, lost packages",
41
  "billing": "Charges, invoices, payment problems"}},
42
- "escalate": {"type": "noul", "instructions": "Does this need urgent human attention?"},
43
  "frustration": {"type": "score", "instructions": "How frustrated is the customer?",
44
  "criteria": ["Calm", "Frustrated", "Very angry"]},
45
  },
46
  )
47
- result.decisions["department"].choice, result.decisions["escalate"].noul
 
 
 
48
  ```
49
 
50
- Or over HTTP on an AbstractCore server: `POST /v1/decisions` with `{"model": "mlx/AbstractFramework/kev-4b-mlx-4bit", "state": ..., "questions": ...}`.
51
- Docs: https://github.com/lpalbou/AbstractCore/blob/main/docs/decision-models.md
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
53
  ## Attribution
54
 
55
  Weights derived from jaredpalmer/kev-4b (Jared Palmer) on Qwen/Qwen3.5 base models (Alibaba), both Apache-2.0.
56
- Converted with `python -m abstractcore.decision.convert`.
 
12
 
13
  # Kev-4B for MLX, 4-bit, group 32, with the Gated DeltaNet projections (in_proj_qkv / in_proj_z / in_proj_a / in_proj_b / out_proj) kept at 8-bit
14
 
15
+ **What it is.** A decision model: it reads a document (the *state*) and answers typed questions about it
16
+ — `choice` over named options, `noul` (the probability that a statement is true), `score` over ordered
17
+ levels — with calibrated probabilities, in one forward pass, without generating text. Use it to classify,
18
+ route, triage, score or check documents and threshold the probabilities (send the uncertain cases to a human).
19
 
20
+ **Why this checkpoint.** The published [jaredpalmer/kev-4b](https://huggingface.co/jaredpalmer/kev-4b) (Jared Palmer,
21
+ Apache-2.0) is a rank-16 LoRA plus a pointer head on a Qwen3.5 base: running it means downloading the
22
+ base model, folding the adapter in at every load and keeping bf16 weights in memory. This repository is the
23
+ merged result quantized for [mlx-lm](https://github.com/ml-explore/mlx-lm) at 4-bit, group 32, with the Gated DeltaNet projections (in_proj_qkv / in_proj_z / in_proj_a / in_proj_b / out_proj) kept at 8-bit (3.0 GB):
24
+ one download, loads in a few seconds, same answers within the measured tolerance below. The pointer head
25
  (`head.safetensors`) stays in float32; `decision.json` records the recipe and the source checkpoint.
26
 
27
+ **How accuracy is protected.** A decision model's value is its calibration, and a plain 4-bit
28
+ quantization damages it: every linear layer at 4 bits (group 64) costs Kev-4B a point of accuracy and
29
+ moves a tenth of its answers by more than 0.10 probability. The recipes here were chosen by measuring
30
+ every candidate against the bf16 weights on the model author's public development set (1,328 records,
31
+ 1,592 questions: argmax agreement, mean and maximum probability shift, accuracy, Brier, ECE), per module
32
+ group and group size. Quantization sensitivity sits in the Gated DeltaNet projections and the group size;
33
+ keeping those projections at 8 bits with 32-element groups keeps the accuracy, and the 8-bit checkpoint is
34
+ indistinguishable from bf16. The companion checkpoints are `AbstractFramework/kev-4b-mlx-8bit` and
35
+ `AbstractFramework/kev-4b-mlx-4bit`; prefer 8-bit when you threshold probabilities, 4-bit when size matters.
36
+
37
  ## Measured
38
 
39
  public-pool-v6 development set (1,328 records): accuracy 0.847 (bf16 0.846), Brier 0.226, ECE 0.024; argmax agreement with bf16 0.973, mean |Δp| 0.023, 3.1 % of questions moved by more than 0.10; 113 ms per record on an M5 Max. A plain 4-bit conversion (every linear at 4 bits, group 64) loses a point of accuracy and moves 10.6 % of the answers; this recipe is the measured compromise. Use the 8-bit checkpoint when you threshold probabilities.
40
 
41
  ## Use with AbstractCore
42
 
43
+ ```bash
44
+ pip install "abstractcore[apple]"
45
+ abstractcore models download mlx AbstractFramework/kev-4b-mlx-4bit
46
+ ```
47
+
48
  ```python
49
  from abstractcore import create_llm
50
 
 
57
  "criteria": {"returns": "Exchanges, refunds, wrong or damaged items",
58
  "shipping": "Delivery status, delays, lost packages",
59
  "billing": "Charges, invoices, payment problems"}},
60
+ "escalate": "Does this need urgent human attention?", # shorthand for a noul question
61
  "frustration": {"type": "score", "instructions": "How frustrated is the customer?",
62
  "criteria": ["Calm", "Frustrated", "Very angry"]},
63
  },
64
  )
65
+ result.decisions["department"].choice # "returns"
66
+ result.decisions["department"].probabilities # {"returns": 0.50, "shipping": 0.37, "billing": 0.13}
67
+ result.decisions["escalate"].noul # 0.73
68
+ result.decisions["frustration"].score # expected level, 0..2
69
  ```
70
 
71
+ Over HTTP (`abstractcore serve`), the same request is `POST /v1/decisions` with
72
+ `{"model": "mlx/AbstractFramework/kev-4b-mlx-4bit", "state": ..., "questions": ...}`.
73
+
74
+ ## The state cache (KV cache) and what to expect
75
+
76
+ The document is read once per request and reused for every question in it; AbstractCore also keeps
77
+ the computed state of the last four documents, so a second request about the same document only pays
78
+ for its questions. Measured on an M5 Max with this family's 8-bit Kev-4B:
79
+
80
+ | Request | First time | Same document again |
81
+ |---|---|---|
82
+ | a 100-token support ticket, three questions | ~95 ms | ~45 ms |
83
+ | a 6,300-token contract, three questions | ~1.4 s | ~0.1 s |
84
+
85
+ Reading the document is the cost (about 3,000 tokens per second for Kev-4B, four to five times faster
86
+ for Kev-0.8B); the questions themselves cost tens of milliseconds. Ask everything you need about a
87
+ document in one call, or in consecutive calls while it is still cached. To disable the cache (every
88
+ request re-reads its document): `create_llm("mlx", model=..., decision_prefix_cache_size=0)`; to keep
89
+ more documents: `decision_prefix_cache_size=16`. The cache lives in memory for the life of the provider.
90
+
91
+ ## Docs
92
+
93
+ - Decision models in AbstractCore: https://github.com/lpalbou/AbstractCore/blob/main/docs/decision-models.md
94
+ (engines, every supported model, conversion recipes, the full measurements)
95
+ - AbstractFramework: https://github.com/lpalbou/abstractframework
96
 
97
  ## Attribution
98
 
99
  Weights derived from jaredpalmer/kev-4b (Jared Palmer) on Qwen/Qwen3.5 base models (Alibaba), both Apache-2.0.
100
+ Converted and measured with `python -m abstractcore.decision.convert`.