⚠️ Current scope (re-scoped 2026-08-13)
The retry this issue was originally filed for has run. google/gemma-4-E2B-it-qat-q4_0-gguf
was measured on a bumped pin inside the #1415 spike and scored a clean NO-GO (103 vs that
session's 113 incumbent, and the file is +7.8 % larger). Its sibling
unsloth/gemma-4-E2B-it-qat-GGUF → UD-Q4_K_XL was measured too and passed the Mac filter.
Both are now recorded in docs/models/eval-log.md (entries §2026-08-12 and §2026-08-13).
What this issue now tracks is the third QAT file, which the original body never named:
unsloth/gemma-4-E2B-it-qat-mobile-GGUF → gemma-4-E2B-it-qat-UD-Q2_K_XL.gguf (2.19 GB,
−29.6 % vs the incumbent). Its Gate 1 verdict is BLOCKED, and not on #1415 — the b10327
pin does clear the shared-KV loader gate, but the build then SIGSEGVs on its first inference
because llama.cpp's Metal backend ships no TQ-family kernels. Still absent at b10375.
New unblock condition: llama.cpp's Metal backend gains TQ2_0 kernels — at minimum
kernel_mul_mm_tq2_0_f32 — and llama.swift ships a release at that build. Cheap re-check
before downloading anything: grep the release xcframework binary for tq2_0 kernel names,
keeping a known-present kernel (q4_0 / q8_0 / q4_K) in the same grep as a positive control.
Already done, do not re-derive: ADR-011 P1 and P2 both PASS for the mobile
re-export (<|turn> id 105 / <turn|> id 106 are both token_type=3 CONTROL).
Result detail: this comment.
Ledger: docs/models/eval-log.md (#1447).
The original body follows unchanged, for the record. Read its "Candidate under test",
"Blocked by #1415" and "Already pre-cleared" sections as historical — they describe the
Q4_0 candidate, not the one above.
Summary
Resume the /model-eval Gate 1 battery for the Gemma 4 E2B QAT candidate
once the llama.cpp pin carries shared-KV tail-layer support. Today's run
(2026-08-08) was blocked at model load — zero inferences, so no quality
judgment exists yet for QAT.
Blocked by #1415. Do not start until a pin bump has landed (or #1415 lands a
spike result that makes this measurable).
Why this is a retry, not a fresh evaluation
The 2026-08-08 Gate 1 run failed 6/6 cells in ~0.9 s each, all with the identical
error before any inference:
llama_model_load: error loading model: missing tensor 'blk.15.attn_k.weight'
Cause: Gemma 4 E2B QAT GGUFs use a shared-KV tail-layer layout (541 tensors;
attn_k / attn_v / attn_k_norm omitted for layers 15–34) that pinned llama.cpp
b8694 cannot load. Confirmed not vendor-specific — unsloth's own QAT re-export
has the byte-identical 541-tensor layout, so the split is QAT-vs-non-QAT, not
Google-vs-unsloth. Detail in #1415.
The verdict was fail in the mechanical sense only (not all 6 cells ok); it is
a blocked outcome, not a quality rejection — the same distinction the Sarashina
2026-07-08 run drew before its clean 2026-07-23 re-eval.
Already pre-cleared (do not re-derive)
Measured on 2026-08-08 against the candidate file; these carry over:
| Check |
Result |
| ADR-011 P1 non-gated source |
✅ HF gated: false, license: apache-2.0, anonymous resolve 302 → CDN 200 |
| ADR-011 P2 CONTROL token flags |
✅ <|turn> id=105 and <turn|> id=106 both token_type=3 (CONTROL) |
| EOG termination |
✅ EOG set {1, 50, 106, 212} — a superset of the incumbent's {50, 106, 212}; <turn|> terminates in both |
| Prompt-format fields |
✅ equivalent to the incumbent: systemPromptSuffix nil, assistantPrefix nil (chat template is read from the GGUF by llama.cpp) |
| File integrity |
✅ 3,349,516,256 bytes / sha256 fa401b55b07ee70a54c6dae3903c783a6e65064312529ea57175cb5f8dec6634, both matching HF X-Linked-Size / X-Linked-ETag |
Still open: P3 on-device GBNF PoC, P4 no catalog regression, P5 no raw
prompt-token sampler accept — all Gate 2, and all after Gate 1 passes.
Candidate under test
google/gemma-4-E2B-it-qat-q4_0-gguf @ 675cff42a74c774d6cb76f76d8eacb49b48c9b93
→ gemma-4-E2B_q4_0-it.gguf (3.35 GB, QAT Q4_0)
- Worth evaluating alongside
unsloth/gemma-4-E2B-it-qat-GGUF →
gemma-4-E2B-it-qat-UD-Q4_K_XL.gguf (2.62 GB, sha256
e531007218dfab990486a5de7676a6932d6ea8dea233d1f698d7c21cf8a16889): same shared-KV
layout, but ~0.49 GB smaller than the shipped Q4_K_M (2.62 vs 3.11 GB), so if
quality holds it is
the more interesting of the two on download size and RAM headroom.
Profile note (carry forward)
The 2026-08-08 run reused the incumbent profile id gemma-4-e2b-q4-k-m — legitimate
per docs/models/onboarding.md (Stage 0 is required for a new family only, and
gemma is registered) after verifying the three prompt-format fields are equivalent.
Consequence: the harness stamps modelIdentifier as "Gemma 4 E2B (Q4_K_M)", so raw
JSONL mislabels the candidate. If this candidate advances, add a proper
ModelProfile in the registration PR. Alternatively add a candidate-only profile
first (the sarashina223B precedent) to keep the retry's logs self-describing.
Acceptance criteria
Not agent-ready
Harness-gated stochastic judgment loop — the /model-eval rubric scoring is
in-session human/model judgment, and the asymmetric borderline→re-sample rule needs
an operator. Run interactively.
References
Summary
Resume the
/model-evalGate 1 battery for the Gemma 4 E2B QAT candidateonce the llama.cpp pin carries shared-KV tail-layer support. Today's run
(2026-08-08) was blocked at model load — zero inferences, so no quality
judgment exists yet for QAT.
Blocked by #1415. Do not start until a pin bump has landed (or #1415 lands a
spike result that makes this measurable).
Why this is a retry, not a fresh evaluation
The 2026-08-08 Gate 1 run failed 6/6 cells in ~0.9 s each, all with the identical
error before any inference:
Cause: Gemma 4 E2B QAT GGUFs use a shared-KV tail-layer layout (541 tensors;
attn_k/attn_v/attn_k_normomitted for layers 15–34) that pinned llama.cppb8694 cannot load. Confirmed not vendor-specific — unsloth's own QAT re-export
has the byte-identical 541-tensor layout, so the split is QAT-vs-non-QAT, not
Google-vs-unsloth. Detail in #1415.
The verdict was
failin the mechanical sense only (not all 6 cellsok); it isa blocked outcome, not a quality rejection — the same distinction the Sarashina
2026-07-08 run drew before its clean 2026-07-23 re-eval.
Already pre-cleared (do not re-derive)
Measured on 2026-08-08 against the candidate file; these carry over:
gated: false,license: apache-2.0, anonymous resolve 302 → CDN 200<|turn>id=105 and<turn|>id=106 bothtoken_type=3 (CONTROL){1, 50, 106, 212}— a superset of the incumbent's{50, 106, 212};<turn|>terminates in bothsystemPromptSuffixnil,assistantPrefixnil (chat template is read from the GGUF by llama.cpp)fa401b55b07ee70a54c6dae3903c783a6e65064312529ea57175cb5f8dec6634, both matching HFX-Linked-Size/X-Linked-ETagStill open: P3 on-device GBNF PoC, P4 no catalog regression, P5 no raw
prompt-token sampler accept — all Gate 2, and all after Gate 1 passes.
Candidate under test
google/gemma-4-E2B-it-qat-q4_0-gguf@675cff42a74c774d6cb76f76d8eacb49b48c9b93→
gemma-4-E2B_q4_0-it.gguf(3.35 GB, QAT Q4_0)unsloth/gemma-4-E2B-it-qat-GGUF→gemma-4-E2B-it-qat-UD-Q4_K_XL.gguf(2.62 GB, sha256e531007218dfab990486a5de7676a6932d6ea8dea233d1f698d7c21cf8a16889): same shared-KVlayout, but ~0.49 GB smaller than the shipped Q4_K_M (2.62 vs 3.11 GB), so if
quality holds it is
the more interesting of the two on download size and RAM headroom.
Profile note (carry forward)
The 2026-08-08 run reused the incumbent profile id
gemma-4-e2b-q4-k-m— legitimateper
docs/models/onboarding.md(Stage 0 is required for a new family only, andgemmais registered) after verifying the three prompt-format fields are equivalent.Consequence: the harness stamps
modelIdentifieras "Gemma 4 E2B (Q4_K_M)", so rawJSONL mislabels the candidate. If this candidate advances, add a proper
ModelProfilein the registration PR. Alternatively add a candidate-only profilefirst (the
sarashina223Bprecedent) to keep the retry's logs self-describing.Acceptance criteria
status: ok(or a genuine non-load failure isrecorded with its cause)
okcell;differentiationwritten against bothincumbents
advances to the ADR-011 real-device PoC and is never an adoption
docs/models/eval-log.md(committed ledger) — replacingor superseding the blocked 2026-08-08 entry, not duplicating it
cross-pin if the pin changed (see 🔧 chore: llama.cpp pin 上げの検討(b8694 → 現行)— QAT shared-KV 対応の可否を spike で判断 #1415 § eval-baseline re-basing)
Not
agent-readyHarness-gated stochastic judgment loop — the
/model-evalrubric scoring isin-session human/model judgment, and the asymmetric borderline→re-sample rule needs
an operator. Run interactively.
References
docs/models/onboarding.md— two-gate procedure