Nightly 2026-07-24: deps fresh · burn.toml kernel validation · chat-template byte gate (caught + fixed a real divergence) · pre-existing GPU test failure fixed - #13
Merged
Conversation
…-util/xxhash-rust/zerocopy 10 patch-level lock bumps; wgpu 29 stays pinned (burn 0.21 resolves it transitively — unblocks with a burn bump, not a cargo upgrade). fmt, clippy --all-targets, 176 unit + 6 load-gate tests, and cargo build all green; GPU budget gates re-verified later this run on a quiet card. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…suites; bench crate opts out Discovery semantics read from cubecl-runtime 0.10 source: config walks UP from the process CWD (cubecl.toml before burn.toml at each level, first hit wins) and cargo runs each crate's tests/benches with CWD = the package dir. Root burn.toml sets [cubecl.compilation] check_mode = "validate" (bounds- check every launch AND validate unchecked kernels for OOB) for the crates/mummu parity/real-model suites; crates/mummu-bench/cubecl.toml pins the budget/bench crate back to "auto" so recorded numbers never carry validation overhead. Consumers run from their own CWD — untouched. Proof: a poisoned root burn.toml fails a GPU test at config load naming the bad key (discovery + parse); a poisoned bench cubecl.toml does the same from the bench crate (opt-out file is the one found there); the whole real-model GPU battery passed with validate armed (no OOB found); budget gate 12.4 / 12.4 tok/s + TTFT ~115 ms across two runs, identical to a no-config A/B run (12.1), budgets unmoved. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…s per process Pre-existing deterministic failure found (and reproduced on unmodified origin/main, serial and parallel): instantiating GpuF16 flips Burn's per-device default dtype policy process-wide, so real_qwen3's f32 GGUF cross-check — running after the f16 leg in the same test binary — panicked reading its logits back (TypeMismatch: expected F16, got F32). The repo convention is that every GpuF16 leg lives in real_f16.rs as its own process; qwen3's f16 test now does too. After the move: real_qwen3 2/2 (GGUF-vs-safetensors cross-check back to its recorded numbers — cosine 0.98910, top-1 151667 both builds) and real_f16 2/2 (qwen2 + qwen3 f16 legs) on the 4070 Ti SUPER. The library-level hazard for consumers switching precision at runtime is recorded as a P6 roadmap item. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… to transformers
Building the gate caught a real divergence and it is fixed: our renders
embedded tool JSON compact ({"a":1}) where every checkpoint template runs
Jinja tojson = Python json.dumps separators ({"a": 1}) — and the models
emit that spacing back (the 07-11 real-GPU proof logged it verbatim). New
public chat::py_json (a json.dumps-separator serde Formatter) feeds all
template-embedded JSON in BOTH conventions (Hermes tool lines + history
<tool_call> blocks, LFM 'List of tools:' line).
The gate: tools/template-probe (out-of-workspace bin, candle-probe pattern)
renders a template via hf-chat-template 0.2.1 (minijinja + transformers
compat). Deliberately NOT a dev-dependency — it enables serde_json's
preserve_order feature, which (features being additive) would flip our own
test builds from sorted to insertion-ordered maps, diverging the very
renders the tests byte-verify from what plain-feature consumers build.
tests/template_gate.rs (ignored; MUMMU_TEMPLATE_PROBE + checkpoint dirs)
pulls each checkpoint's OWN template through TokenizerConfig::from_dir
(incl. LFM2.5's standalone chat_template.jinja) and byte-compares: 9/9 —
Qwen2.5 plain/tools/tool-call-history, Qwen3 plain/tools, LFM2.5
plain±system/tools±system/think-strip/pythonic+tool turns all
byte-identical; the family divergences (Qwen2.5's no-system branding
preamble, Qwen3's no-system no-preamble, Qwen3 history think-stripping) are
pinned to their exact deltas so any other drift fails loudly.
Real-GPU re-proof with the spaced prompts: all three toolcall suites green —
Qwen2.5, LFM2.5, and Qwen3 each emitted a clean parseable call (in exactly
the spaced spelling). Parity re-passed bit-identically (max |dlogit|
2.670288e-5, Ollama greedy leg exact); 177 unit tests green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ADMAP/README ROADMAP: perf-section burn.toml item [x] (discovery semantics + A/B proof); P3 hf-chat-template item [x] payoff (1) with the py_json divergence story; new [ ]s — ChatMl::qwen3() history think-stripping (byte-gate finding), general template-fallback renderer (payoff 2, preserve_order caveat), P6 one-process Gpu/GpuF16 dtype-policy hazard (root cause of the pre-existing real_qwen3 failure), P9 KV-cache FP8/e4m3 quantization (vLLM April 2026 lessons, 2026-07-24 research). P4 note: template-embedded tool JSON now spells json.dumps separators. README: the function-calling feature now claims byte-identity with transformers' renders, gated by the 9-case template_gate. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…source file, derived per-stage representations, no new format Folds the design discussion into the placement-plan item: bf16 (or GGUF) stays the single stored artifact; f32/f16 stages are load-time casts (CastFloatAdapter), the CPU stage is the P9 keep-quantized leg (block-wise Q4_K-style on-the-fly quant preferred over naive RTN); a derived-artifact cache is a later optimization (ordinary shards keyed by source hash + dtype + layer range — a cache, not a format). Runtime dependency order recorded: cross-device dtype-policy experiment first, then the stage-composed model type (one Wgpu backend multi-dtype for GPU+iGPU; a backend-type seam for CPU), activation casts at seams, per-stage KV shards + schedule. Planner expectation: pipeline throughput = slowest stage — small stages are for FIT, not speed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rallel nightlies Both runs independently found and fixed the same three things; main's (already-merged) implementations win wherever they overlap: - Template byte gate: keep main's in-process hf-chat-template dev-dep + workspace-level serde_json preserve_order (insertion-order prompt bytes in PRODUCTION — the stronger resolution of the same feature-unification hazard this branch dodged with an out-of-workspace probe). tools/template-probe is DROPPED as superseded; this branch's extra coverage is PORTED into main's harness: Qwen2.5 plain/tools/FC-history, Qwen2.5 + Qwen3 divergence pinning (default preambles, think-stripping), LFM2.5 plain/tools/think/pythonic legs (also exercising the chat_template.jinja fallback). Gate now 10 cases, all passing. - python_json spacing: keep main's (same formatter, private fn); drop this branch's public py_json duplicate. - GpuF16 isolation: keep main's (same test move + the deeper loader fix — target_float from the TYPE); keep main's richer dtype-policy roadmap item, drop this branch's duplicate. - Keep from this branch: burn.toml kernel-OOB validation + the bench-crate cubecl.toml opt-out, the P6 heterogeneous-precision design note, the P9 KV-cache FP8 research item, ChatMl::qwen3() think-strip item. - Keep from main: tokenizer_config surfaced on Loaded* structs (config-driven EOS/BOS), all model loader changes. Verified on the merged tree: fmt + clippy clean; 176 unit tests; template gate 10/10 byte-identical; real_qwen3 2/2 (validate armed, tokenizer_config assertions live), real_toolcall clean spaced call, real_f16 2/2; budgets hold — CPU 13.56 tok/s, GPU 12.3/13.4 tok/s + TTFT ~104 ms (first run after fresh binaries reads low while autotune re-tunes, per the roadmap note). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Owner
Author
|
Merged origin/main (PR #12 — the parallel 2026-07-22 nightly) into this branch and reconciled the duplicate work; see the merge commit message for the full resolution. Highlights: main's in-process gate + workspace |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Nightly 2026-07-24 — deps fresh · burn.toml kernel validation · the chat-template byte gate is real (and it caught a divergence) · a pre-existing GPU test failure fixed
Four increments + research folded, each verified green before landing.
1 · Dependency freshness (
092c8db)cargo update: 10 patch-level bumps (clap 4.6.4, glob 0.3.4, libc 0.2.189, rustls-pki-types 1.15.1, syn 3.0.3, tokio 1.53.1, tokio-util 0.7.19, xxhash-rust 0.8.18, zerocopy 0.8.55 ×2).cargo upgrade --incompatibleoffered only wgpu 29→30 — held per the intentional pin (burn 0.21 resolves wgpu 29 transitively; it unblocks with a burn bump, not acargo upgrade). tokenizers stays current at 0.23.1; no Burn 0.22 exists yet.2 · burn.toml — CubeCL kernel-OOB validation armed for the correctness suites (
e9bb46d, perf-section item ticked)Read the discovery logic out of cubecl-runtime 0.10's source (
RuntimeConfig::from_current_dir): it walks up from the process CWD, checkingcubecl.tomlbeforeburn.tomlat each level, first hit wins — and cargo runs every crate's tests/benches with CWD = the package dir. Hence two files:burn.toml(repo root):[cubecl.compilation] check_mode = "validate"— bounds-check every kernel launch AND validate explicitly-unchecked kernels for OOB (the failure class behind silent wrong-logits drift). Arms allcrates/mummuparity/real-model suites.crates/mummu-bench/cubecl.toml:check_mode = "auto"— the budget/bench crate finds this first, so recorded perf numbers never include validation overhead.Consumers run from their own CWDs — untouched. Proofs: a poisoned root
burn.tomlfails a GPU test at config load naming the exact bad key (unknown variant 'not-a-real-mode', expected enforce/validate/auto); a poisoned benchcubecl.tomldoes the same from the bench crate (so the opt-out file is genuinely the one discovered there); the whole real-model battery below ran with validation armed — no OOB surfaced; and the budget gate is unmoved (12.4 tok/s with the files vs 12.1 in a no-file A/B).3 · Pre-existing GPU failure found, root-caused, fixed (
7c10026)real_qwen3_gguf_loads_and_agrees_with_safetensorsfails on unmodified origin/main (serial AND parallel — verified from the untouched main checkout, which exonerated this run's changes): instantiatingGpuF16flips Burn's per-device default dtype policy process-wide, so the f32 GGUF cross-check running after the f16 leg in the same test binary panics reading its logits back (TypeMismatch: expected F16, got F32). Fix = the repo's own convention: everyGpuF16leg lives inreal_f16.rsas its own process; qwen3's f16 test moved there. After the move:real_qwen32/2 with the recorded numbers back (GGUF-vs-bf16 cosine 0.98910, top-1 151667 both builds),real_f162/2. The library-level hazard (a consumer switching precision at runtime in one process) is now a P6 roadmap item.4 · The template byte gate — renders now byte-identical to
transformers.apply_chat_template(e9b56b8, P3 item ticked)The "template-vs-renderer consistency" marker check is now a true byte gate, and building it caught a real divergence:
The bug it found (fixed): our renders embedded tool JSON compact (
{"a":1}) where every checkpoint template runs Jinjatojson= Pythonjson.dumpsseparators ({"a": 1}) — and the models emit that spacing back (the 07-11 real-GPU proof literally logged{"name": "get_weather", "arguments": {"city": "Paris"}}). New publicchat::py_json(ajson.dumps-separator serde Formatter) feeds all template-embedded JSON in both conventions.The gate:
tools/template-probe(out-of-workspace bin, the candle-probe pattern) renders a template via hf-chat-template 0.2.1 (minijinja + transformers compat layer). Deliberately NOT a dev-dependency: hf-chat-template enables serde_json'spreserve_order, which — features being additive — would silently flip our own test builds from sorted to insertion-ordered maps, diverging the very renders the tests verify from what plain-feature consumers build.tests/template_gate.rs(ignored, env-keyed) pulls each checkpoint's OWN template through the real import path (TokenizerConfig::from_dir, incl. LFM2.5's standalonechat_template.jinja— fetched into the local cache this run, exercising the 07-20 fallback on a real checkpoint) and byte-compares. 9/9 pass: Qwen2.5 plain/tools/tool-call-history · Qwen3 plain/tools · LFM2.5 plain±system/tools±system/think-stripping/pythonic-call+tool-turns — all byte-identical. The only family divergences are pinned to their exact deltas so any other drift fails loudly: Qwen2.5's no-system branding preamble ("You are Qwen, …" vs our neutral one), Qwen3's no-system no-preamble, Qwen3's history think-stripping (→ new[ ]:ChatMl::qwen3()with the strip).Verification battery (RTX 4070 Ti SUPER, quiet card; real-model suites ran with kernel validation armed)
cargo fmt/clippy --all-targetsreal_qwen3(safetensors + GGUF cross-check)real_f16(qwen2 + qwen3 f16 legs)real_toolcall×3 (Qwen2.5 / LFM2.5 / Qwen3, new spaced prompts)real_inferenceResearch folded
[ ]with vLLM's shipped numbers + transferable lessons (two-level f32 accumulation, layer-selective beats uniform, head_dim sensitivity). https://vllm.ai/blog/2026-04-22-fp8-kvcache[ ]s from this run's findings:ChatMl::qwen3()think-stripping; general template-fallback renderer (payoff 2, preserve_order caveat documented); the P6 one-process Gpu/GpuF16 dtype-policy hazard.What's next
tokenizer.modelimport (needs a fixture fetch).TokenizerConfigon theLoaded*structs).🤖 Generated with Claude Code