Merge nucleic/eager-glass-wren-mrb5 into dev
This commit is contained in:
+81
-25
@@ -43,10 +43,12 @@ is a classic small-model problem.
|
|||||||
classifier is exactly the energy bill this policy exists to avoid. Both shipped models
|
classifier is exactly the energy bill this policy exists to avoid. Both shipped models
|
||||||
are *designed for accelerator eligibility from day one* (fixed shapes, fp16-friendly
|
are *designed for accelerator eligibility from day one* (fixed shapes, fp16-friendly
|
||||||
ops — §4.2), and scheduling is verified, not assumed (§8).
|
ops — §4.2), and scheduling is verified, not assumed (§8).
|
||||||
6. **Two model sizes, one contract:** a **light** classifier every machine can run, and a
|
6. **A model ladder, one contract:** a **light** classifier every machine can run, a
|
||||||
**deep** classifier (§4.3) that meaningfully exploits ANE/NPU headroom for higher
|
**deep** classifier (§4.3) that exploits ANE/NPU headroom for higher accuracy on the
|
||||||
accuracy on the ambiguous prompts the light model gets wrong. Same labels, same
|
ambiguous prompts the light model gets wrong, and a **max** classifier (§4.4) that
|
||||||
calibration semantics, same wire — machines differ only in which artifact answers.
|
spends big-GPU headroom (RTX/Radeon-class, AC power only) on the best result the
|
||||||
|
hardware can deliver. Same labels, same calibration semantics, same wire — machines
|
||||||
|
differ only in which artifact answers.
|
||||||
7. **No architectural churn:** the classifier slots into the existing layer stack behind
|
7. **No architectural churn:** the classifier slots into the existing layer stack behind
|
||||||
`PurposeVerdict.Source`; routing, session plumbing, UI, and wire stay as shipped.
|
`PurposeVerdict.Source`; routing, session plumbing, UI, and wire stay as shipped.
|
||||||
|
|
||||||
@@ -178,11 +180,12 @@ runs quantized **7B** LLMs at usable rates ([NPU comparison](https://localaimast
|
|||||||
the ANE side routinely serves Apple's ~3B foundation model. So the deep model is sized by
|
the ANE side routinely serves Apple's ~3B foundation model. So the deep model is sized by
|
||||||
*task saturation*, not by hardware: past roughly half a billion parameters, **encoder**
|
*task saturation*, not by hardware: past roughly half a billion parameters, **encoder**
|
||||||
accuracy on a fixed 8-way task flattens, and the next meaningful step up is a 1–3B
|
accuracy on a fixed 8-way task flattens, and the next meaningful step up is a 1–3B
|
||||||
generative decoder — rejected, because it reintroduces exactly what this plan removes
|
generative decoder — rejected *as the default path*, because it reintroduces exactly what
|
||||||
(uncalibrated generation, hundreds of ms, GB-scale memory residency) for negligible
|
this plan removes (uncalibrated generation, hundreds of ms, GB-scale memory residency)
|
||||||
classification gain. Target ship size: **large-class encoder, ~400M params**, decided by
|
for negligible classification gain on ordinary machines. (§4.4 revisits the decoder under
|
||||||
ablation (below), with the older base size kept as a pipeline ablation rung rather than a
|
strict constraints as the optional GPU-max tier.) Target ship size for deep: **large-class
|
||||||
shipping artifact.
|
encoder, ~400M params**, decided by ablation (below), with the older base size kept as a
|
||||||
|
pipeline ablation rung rather than a shipping artifact.
|
||||||
|
|
||||||
- **Architecture:** ModernBERT-class encoder, **large size (~400M params; ~150M base
|
- **Architecture:** ModernBERT-class encoder, **large size (~400M params; ~150M base
|
||||||
variant trained as an ablation rung)**, **512-token window** (the hard cases are long —
|
variant trained as an ablation rung)**, **512-token window** (the hard cases are long —
|
||||||
@@ -212,16 +215,59 @@ shipping artifact.
|
|||||||
- **Same export discipline as 4.2:** fixed 1×512-token shape, fp16 (+ int8-QDQ variant),
|
- **Same export discipline as 4.2:** fixed 1×512-token shape, fp16 (+ int8-QDQ variant),
|
||||||
both ONNX and Core ML artifacts, same tokenizer spec, same threshold JSON schema.
|
both ONNX and Core ML artifacts, same tokenizer spec, same threshold JSON schema.
|
||||||
- **Model selection at runtime** (per machine, decided once per launch and re-checked on
|
- **Model selection at runtime** (per machine, decided once per launch and re-checked on
|
||||||
asset/hardware change):
|
asset/hardware/power change):
|
||||||
- deep model present **and** verified accelerator-resident (§5/§6 checks) → **deep is
|
- max model present **and** its §4.4 eligibility holds (verified GPU rung + memory
|
||||||
the L1 classifier**; lite stays loaded as the instant-answer for the first keystrokes
|
floor + AC power) → **max is the L1 classifier**;
|
||||||
if deep's asset is still warming;
|
- else deep model present **and** verified accelerator-resident (§5/§6 checks) →
|
||||||
|
**deep is L1**; lite stays loaded as the instant-answer for the first keystrokes
|
||||||
|
if the bigger asset is still warming;
|
||||||
- otherwise → lite is L1 (which is already ≥ the current AFM path).
|
- otherwise → lite is L1 (which is already ≥ the current AFM path).
|
||||||
|
Power transitions re-run this ladder live: unplugging mid-session steps max → deep
|
||||||
|
seamlessly (next debounce tick answers on the smaller model).
|
||||||
A cascade variant (lite always answers; deep re-scores only low-margin drafts) is the
|
A cascade variant (lite always answers; deep re-scores only low-margin drafts) is the
|
||||||
fallback posture if deep-everywhere measures worse on energy than expected — the
|
fallback posture if deep-everywhere measures worse on energy than expected — the
|
||||||
layering makes either wiring a one-line change in `PromptPurposeService`.
|
layering makes either wiring a one-line change in `PromptPurposeService`.
|
||||||
|
|
||||||
### 4.4 Artifacts, conversion, versioning
|
### 4.4 The GPU-max classifier (`purpose-max`) — spending real GPU headroom
|
||||||
|
|
||||||
|
§4.3's sizing argument stands: past ~0.5B parameters, a *bigger encoder* buys latency,
|
||||||
|
not accuracy. So the tier above deep-large is not a larger encoder — it is a **different
|
||||||
|
kind of model** that only RTX/Radeon-class (or big-unified-memory Apple GPU) headroom
|
||||||
|
makes viable: a small **instruction-tuned decoder used as a constrained classifier**.
|
||||||
|
This deliberately *revisits* §2's decoder rejection, which was a rejection for the
|
||||||
|
*default* path (uncalibrated free generation, hundreds of ms, GB-scale residency on
|
||||||
|
every machine). Under the max tier's constraints, each objection is answered rather than
|
||||||
|
waved off:
|
||||||
|
|
||||||
|
- **Architecture:** a 1.5–4B instruction-tuned decoder (Qwen/Phi-class), LoRA-fine-tuned
|
||||||
|
on the same dataset and merged. Classification is **not free generation**: one prefill
|
||||||
|
over the 512-token head + a single constrained step with the logits masked to the 8
|
||||||
|
label tokens — the masked-label distribution is the output, temperature-scaled on the
|
||||||
|
validation split exactly like the encoders (this restores the calibration story the §2
|
||||||
|
rejection was about). Secondary-purpose and difficulty ride the same masked readout.
|
||||||
|
- **What it buys beyond accuracy:** a short *generated* rationale (one clause, capped
|
||||||
|
tokens) for the chip tooltip — a per-prompt "why", where the encoders can only attach
|
||||||
|
canned per-cell copy. Generation of the rationale is optional, async after the label,
|
||||||
|
and never on any routing path.
|
||||||
|
- **Eligibility (all required):** a verified GPU rung per §5/§6 (NvTensorRT-RTX /
|
||||||
|
MIGraphX / OpenVINO-GPU on Windows, Apple GPU on macOS) **and** a memory floor
|
||||||
|
(≥ 6 GB dedicated VRAM, or ≥ 24 GB unified memory on Apple silicon) **and AC power**.
|
||||||
|
On battery the ladder drops to deep on the ANE/NPU automatically — max is a
|
||||||
|
wall-power luxury by definition, and the power-transition listener swaps tiers live
|
||||||
|
(mid-draft transitions just change which model answers the next debounce tick).
|
||||||
|
- **Artifacts:** int4/int8 quantized, ~1–2.5 GB — a separately downloaded optional asset
|
||||||
|
("best on this machine" offer in Settings › Intelligence, never auto-downloaded).
|
||||||
|
Export uses the generative stacks (ONNX Runtime GenAI format for Windows ML's runtime;
|
||||||
|
a stateful Core ML model on macOS) — meaningfully more export complexity than the
|
||||||
|
encoders, which is why max is its own late work item and not on deep's critical path.
|
||||||
|
- **Budgets & gates:** label p95 ≤ 250 ms on the eligibility-floor GPU (still well inside
|
||||||
|
the debounce window; rationale generation excluded from the budget); ships only on a
|
||||||
|
**≥ +2-point hard-slice win over deep-large** — if constrained decoding can't beat the
|
||||||
|
large encoder where it matters, max doesn't exist and the doc's saturation argument was
|
||||||
|
simply right; idle-unload is mandatory (a multi-GB resident model must never outlive
|
||||||
|
composer attention, and must never keep a dGPU awake).
|
||||||
|
|
||||||
|
### 4.5 Artifacts, conversion, versioning
|
||||||
|
|
||||||
- **Canonical artifact: ONNX** (opset ≥ 17), one file, one tokenizer spec (exported
|
- **Canonical artifact: ONNX** (opset ≥ 17), one file, one tokenizer spec (exported
|
||||||
vocab + normalization rules — no runtime HuggingFace dependency).
|
vocab + normalization rules — no runtime HuggingFace dependency).
|
||||||
@@ -231,9 +277,10 @@ shipping artifact.
|
|||||||
the frozen test set; label agreement ≥ 99.5% and identical accuracy-to-the-gate, or the
|
the frozen test set; label agreement ≥ 99.5% and identical accuracy-to-the-gate, or the
|
||||||
conversion is rejected (this is what makes "one model, two runtimes" honest).
|
conversion is rejected (this is what makes "one model, two runtimes" honest).
|
||||||
- **Windows runtime:** the ONNX artifact as-is, via Windows ML (§6).
|
- **Windows runtime:** the ONNX artifact as-is, via Windows ML (§6).
|
||||||
- **Naming:** `purpose-lite-v<N>` / `purpose-deep-v<N>` with `.onnx` (canonical, per-EP
|
- **Naming:** `purpose-lite-v<N>` / `purpose-deep-v<N>` / `purpose-max-v<N>` with `.onnx`
|
||||||
quantization variants) and `.mlmodelc` (converted) suffixes.
|
(canonical, per-EP quantization variants; GenAI-format for max) and `.mlmodelc`
|
||||||
- **Versioning:** artifacts named `purpose-<lite|deep>-v<N>.<onnx|mlmodelc>`; the version
|
(converted) suffixes.
|
||||||
|
- **Versioning:** artifacts named `purpose-<lite|deep|max>-v<N>.<…>`; the version
|
||||||
string rides `PurposeVerdict.reason` provenance and the session routing note, so field
|
string rides `PurposeVerdict.reason` provenance and the session routing note, so field
|
||||||
behavior is attributable to a model version. Old artifact kept for one release for a fast
|
behavior is attributable to a model version. Old artifact kept for one release for a fast
|
||||||
revert (`nucleic.purposeClassifierVersion` defaults key as the pin/kill switch).
|
revert (`nucleic.purposeClassifierVersion` defaults key as the pin/kill switch).
|
||||||
@@ -396,11 +443,16 @@ path to the slider later, for free.
|
|||||||
2. **Tier-drift invariant** re-run over *model* predictions (not just heuristics), for
|
2. **Tier-drift invariant** re-run over *model* predictions (not just heuristics), for
|
||||||
both models: every test-set misroute within one cost tier at all levels/lanes — and for
|
both models: every test-set misroute within one cost tier at all levels/lanes — and for
|
||||||
deep's mixed-intent path, the primary+secondary blend rule proven to stay in-bound.
|
deep's mixed-intent path, the primary+secondary blend rule proven to stay in-bound.
|
||||||
3. **Parity gates:** Core ML↔ONNX label agreement ≥ 99.5% per model (§4.4); C#↔Swift
|
3. **Parity gates:** Core ML↔ONNX label agreement ≥ 99.5% per model (§4.5); C#↔Swift
|
||||||
threshold config is one shared JSON so acceptance semantics can't fork.
|
threshold config is one shared JSON so acceptance semantics can't fork. For max, the
|
||||||
4. **Latency:** lite p95 ≤ 20 ms; deep p95 ≤ 100 ms *on the accelerator it's gated to*
|
masked-label readout must additionally pass a calibration bound (ECE ≤ lite's on the
|
||||||
(still several debounce ticks under the 700 ms window, and never on the send path).
|
validation split) — a decoder that classifies better but *confides* worse would poison
|
||||||
Measured in eval.py and asserted loosely in a perf smoke test.
|
the accept/corroborate/escalate contract.
|
||||||
|
4. **Latency:** lite p95 ≤ 20 ms; deep p95 ≤ 100 ms *on the accelerator it's gated to*;
|
||||||
|
max label-readout p95 ≤ 250 ms on the eligibility-floor GPU (rationale generation
|
||||||
|
excluded — async, off every routing path). All still several debounce ticks under the
|
||||||
|
700 ms window, and never on the send path. Measured in eval.py and asserted loosely in
|
||||||
|
a perf smoke test.
|
||||||
5. **Accelerator-residency gates** (goal #5 made falsifiable):
|
5. **Accelerator-residency gates** (goal #5 made falsifiable):
|
||||||
- macOS: `MLComputePlan` ANE-op share ≥ the per-artifact floor emitted at conversion,
|
- macOS: `MLComputePlan` ANE-op share ≥ the per-artifact floor emitted at conversion,
|
||||||
checked at load on-device (rung fallbacks per §5 — the GPU retry must itself pass a
|
checked at load on-device (rung fallbacks per §5 — the GPU retry must itself pass a
|
||||||
@@ -419,7 +471,9 @@ path to the slider later, for free.
|
|||||||
cycle with A/B logging *locally* (both verdicts recorded in the routing note's reason);
|
cycle with A/B logging *locally* (both verdicts recorded in the routing note's reason);
|
||||||
flip default on when disagreement analysis shows the model ≥ AFM on real drafts; remove
|
flip default on when disagreement analysis shows the model ≥ AFM on real drafts; remove
|
||||||
the AFM layer (L2 demotion, §5) after two clean releases. Deep rolls out behind the
|
the AFM layer (L2 demotion, §5) after two clean releases. Deep rolls out behind the
|
||||||
same telemetry one cycle after lite.
|
same telemetry one cycle after lite; max one cycle after deep, and only if its §4.4
|
||||||
|
hard-slice-over-deep-large gate held on the frozen set (a tier that can't beat the one
|
||||||
|
below it is deleted, not shipped).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -476,8 +530,10 @@ path to the slider later, for free.
|
|||||||
| 7 | Windows ML runtime (with the port's §7 renderer) | `PurposeClassifier.cs` (Windows App SDK 1.8.1+, power-source-aware policy ladder — `MAX_EFFICIENCY` on battery; NPU→GPU (NvTensorRT-RTX/MIGraphX/OpenVINO-GPU)→CPU on AC — explicit-EP validation path, AOT compile-at-first-use), shared threshold JSON, degradation ladder |
|
| 7 | Windows ML runtime (with the port's §7 renderer) | `PurposeClassifier.cs` (Windows App SDK 1.8.1+, power-source-aware policy ladder — `MAX_EFFICIENCY` on battery; NPU→GPU (NvTensorRT-RTX/MIGraphX/OpenVINO-GPU)→CPU on AC — explicit-EP validation path, AOT compile-at-first-use), shared threshold JSON, degradation ladder |
|
||||||
| 8 | `purpose-deep` training + heads | ModernBERT-class multi-task checkpoints at base (~150M) *and* large (~400M), 512-token window, ≤ 850 MB fp16 / ≤ 450 MB int8 artifacts, hard-slice +5pt-over-lite and large-vs-base ablation gates, mixed-intent blend rule in router + tests |
|
| 8 | `purpose-deep` training + heads | ModernBERT-class multi-task checkpoints at base (~150M) *and* large (~400M), 512-token window, ≤ 850 MB fp16 / ≤ 450 MB int8 artifacts, hard-slice +5pt-over-lite and large-vs-base ablation gates, mixed-intent blend rule in router + tests |
|
||||||
| 9 | Deep-model distribution + selection | on-demand asset download/verify/pin (macOS-VM base-image pattern), §4.3 runtime selection ladder, accelerator-residency gating on both platforms, Settings download affordance |
|
| 9 | Deep-model distribution + selection | on-demand asset download/verify/pin (macOS-VM base-image pattern), §4.3 runtime selection ladder, accelerator-residency gating on both platforms, Settings download affordance |
|
||||||
| 10 | Rollout | dark-ship + local A/B logging, lite default flip, deep one cycle later, AFM layer retirement |
|
| 10 | Rollout | dark-ship + local A/B logging, lite default flip, deep one cycle later, max one after that, AFM layer retirement |
|
||||||
|
| 11 | `purpose-max` (optional tier, after 8–9 prove out) | 1.5–4B LoRA-fine-tuned decoder, masked-label constrained readout + calibration, GenAI-format ONNX + stateful Core ML exports, GPU+memory+AC eligibility gating with live power-transition stepping, async rationale generation, idle-unload |
|
||||||
|
|
||||||
Items 1–5 are independent of the Windows port's schedule; 6 can land any time (additive);
|
Items 1–5 are independent of the Windows port's schedule; 6 can land any time (additive);
|
||||||
7 rides the port's renderer milestone; 8–9 start once item 5's hard slice exists (deep's
|
7 rides the port's renderer milestone; 8–9 start once item 5's hard slice exists (deep's
|
||||||
gate is defined against it).
|
gate is defined against it); 11 starts only after deep ships and holds its gates — max is
|
||||||
|
an *optional* crown, not a dependency of anything.
|
||||||
|
|||||||
Reference in New Issue
Block a user