Repository navigation
#606 follow-up: clamp the three remaining unclamped q8_1 scale/sum emit sites - #1448
Closed
MatthewHines wants to merge 2 commits into
Closed
MatthewHines wants to merge 2 commits into
MatthewHines wants to merge 2 commits into
Conversation
… q8_1_ds Three kernels still emit the (d, sum) pair of a q8_1 activation block with a raw make_half2(d, sum), bypassing the finite helper the rest of the tree uses (q8_1_finite.hpp, from 19de7f4 / f6601bf): fused_gr.cu gr_q8_tail - the fused gate-reduce tail (QFUSE) verify_kernels.cu gdn_q8_1_store - the batched GDN verify store (QFUSE) iq_kernels.cu s26_swiglu_q8_1_kernel - the S26 swiglu path A block whose amax overflows (or that reads a non-finite input) emits d = inf/NaN; fp16 makes the pair NaN (or the pathological (0,0)). Nothing downstream tests for it: a NaN scale poisons the fp16 dot of the quantized activation and every sum downstream of it, and a fully non-finite logit row ends at the sampler's all-NaN fallback - vocabulary id 0, the '!' face of the degeneration reported in Niko1221#606. Same defect class already fixed at the other emit sites; these three were missed. q8_1_ds() clamps both halves into the fp16-finite range (finite d, non-negative finite sum - the sum is a mean of |x|), producing for the GPU paths the same bits the CPU pool and the clamped GPU sites produce for the same block. A clamp at the producer, content-blind: nothing downstream of it is model-text-aware. Criteria and the wider carried-state RCA: docs/Q8_1_FINITE_DS.md and docs/DEGENERATION_RCA.md.
Q8_1_FINITE_DS.md: the invariant, the three missed sites, what a NaN scale does downstream, the diagnostic criteria for this defect class. DEGENERATION_RCA.md: the carried-state RCA behind the fix - restart-cure and cross-session persistence as localization levers, the three purity violations of the conversation cache's state = f(prefix) contract (this defect, residency-tier numerics, wall-time-learned draft policy), the falsification tests that pinned each one, and a field diagnostic protocol. Recommendations for engine-side remedies; no behavior or tuning changes included.
Niko1221
added a commit
that referenced
this pull request
Oct 8, 2026
…the other producers do The three sites fixed by the previous commit stored a clamped (d, sum) but still quantized against the unclamped d, so an overflowing block stored int8 values that no longer matched its stored scale. They now use q8_1_finite(d) and q8_1_quant like native_quantize_q8_1_kernel, the swiglu quantizer and the CPU pool. A block whose amax is finite and below 8.3M is stored bit for bit as before. Co-authored-by: Matthew Hines <matthewbretthines@gmail.com>
Owner
|
Thank you, taken. The three emit sites now go through Closing as ported. |
mobile2machan
added a commit
to mobile2machan/Strata
that referenced
this pull request
Oct 8, 2026
128 commits: batch-groups auto per stage, server listen backlog 256, the NVIDIA short-prompt CPU share, batched prompt reads (Niko1221#1323), the tokenizer cache, the engine stall watchdog (Niko1221#1317 Niko1221#1407), conversation-cache eviction (Niko1221#1347), prompt buffers sharing the embedding storage (Niko1221#1454), the Pascal decode fix (Niko1221#1469), q8_1 scale clamps (Niko1221#1448), STRATA_STAGE_PIN opt-in (off: on by default it corrupted IQ3_S decode after a long prompt), route-resident and GDN-chunked opt-ins, gfx906 build fix, AMD docs and community benches. main keeps 33af099 (AMD PCIe link speed/width and GPU name detection) and a798ac0 (the k8v4 config read-back and 816 B/cell sizing).
MistVVK
pushed a commit
to MistVVK/XeStrata
that referenced
this pull request
Oct 10, 2026
…U decode, the iq and native mmvq quantizers, the CPU lane) - from Strata Niko1221#1448: an activation past ~8.3M overflowed the scale to inf and the dot products to NaN; below that the output is bit-identical
Maddoxkkm
added a commit
to Maddoxkkm/Strata
that referenced
this pull request
Oct 10, 2026
…tch-audit.py + fetched PR diffs) Line-level audit of the eight patches applied on tuned-1403 against the tuned-141 tree and against upstream 0.1.41: Niko1221#1323 and Niko1221#1372 are upstream's now, Niko1221#1381/Niko1221#1439/Niko1221#1451 are re-applied on 141, while Niko1221#1416 (CPU share), Niko1221#1448 (q8_1 finite-ds) and Niko1221#1457 (HC scratch reuse) have no counterpart there. patch-audit.py compares a diff's added code lines against a tree, which survives the rebases and reworkings that defeat 'git apply -R --check'.
giridhart
pushed a commit
to giridhart/Strata
that referenced
this pull request
Oct 15, 2026
… it, as the other producers do The three sites fixed by the previous commit stored a clamped (d, sum) but still quantized against the unclamped d, so an overflowing block stored int8 values that no longer matched its stored scale. They now use q8_1_finite(d) and q8_1_quant like native_quantize_q8_1_kernel, the swiglu quantizer and the CPU pool. A block whose amax is finite and below 8.3M is stored bit for bit as before. Co-authored-by: Matthew Hines <matthewbretthines@gmail.com>
Ben1078
pushed a commit
to Ben1078/Strata
that referenced
this pull request
Oct 24, 2026
…1221#606/Niko1221#1448) This branch's base is v0.1.40.3, which predates upstream's clamp of the last three unclamped q8_1 activation emit sites (v0.1.41: 7a0e302 "clamp the three unclamped q8_1 scale/sum emit sites via q8_1_ds", Niko1221#606, and e372d4f "q8_1 emit sites: clamp the scale and quantize against it", Niko1221#1448). fused_gr.cu's gr_q8_tail, iq_kernels.cu's s26_swiglu_q8_1_kernel and verify_kernels.cu's gdn_q8_1_store still stored the block's (d, sum) pair with a raw make_half2 and quantized against an unclamped d, bypassing the finite helper the rest of the tree uses. A q8_1 block stores d = amax/127 and the block sum as fp16. A sum past 65504 (one massive-activation dimension among the 32 is enough) rounds to inf, and d overflows past amax = 8.3M; the dot products then read inf * 0 = NaN, and a non-finite logit row ends at the sampler's all-NaN fallback. The poison sits in the conversation's K/V and recurrent state, so with the prompt cache every later turn stays poisoned until the prompt is read again from token 0. On this rig (RX 9060 XT + RX 6650 XT, Coder IQ1_M, 256K context, layer split 35, MTP) the branch answered coherently up to ~115K-150K tokens of context, then fell into a persistent local loop -- never before, and it did not clear once started. The base tree has zero raw make_half2(d, sum) sites; this branch had three. With the clamp, a full agent run crossed the whole failure band and completed: deepest request 158,058 tokens of context, 12,577 generated, drafts accepted 6,934 of 11,756. Every other change tried during the investigation (base serve/frontend.py, the whole base serve/, build-flag changes, the two Q8_0 fused-kernel switches) was reverted first, so the only delta from the failing build is these three lines. Ported from upstream 7a0e302 (Matthew Hines) and e372d4f. Bug report: patches/BUG-q8_1-deep-context-loop.md; PR notes: patches/PR-q8_1-clamp.md.
Ben1078
added a commit
to Ben1078/Strata
that referenced
this pull request
Oct 24, 2026
hip: clamp the three q8_1 scale/sum emit sites (port of upstream Niko1221#606 / Niko1221#1448)
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.
Summary
Three kernels still emit the
(d, sum)pair of a q8_1 activation block with a rawmake_half2(d, sum), bypassing the finite helper the rest of the tree has used since19de7f4/f6601bf(include/strata/kernels/q8_1_finite.hpp):fused_gr.cu—gr_q8_tailverify_kernels.cu—gdn_q8_1_storeiq_kernels.cu—s26_swiglu_q8_1_kernelA block whose
amaxoverflows (or that reads a non-finite input) emitsd = inf/NaN; fp16 turns the pair into NaN (or the pathological(0, 0)). Nothing downstream tests for finiteness — the dot kernels assume the producer upheld the invariant, because every other producer sharesq8_1_ds(). A NaN scale poisons the fp16 dot of the quantized activation and every sum downstream of it through the layer stack; a fully non-finite logit row ends at the sampler's all-non-finite fallback — vocabulary id 0, the!face of #606.This is the same defect class already fixed at the other emit sites; these three were missed. The fix is the same one-liner pattern: route the pair through
q8_1_ds(), which clamps both halves into the fp16-finite range (finited, non-negative finitesum— the sum is a mean of|x|) and produces for the GPU paths the same bits the CPU pool and the already-clamped GPU sites produce for the same block. Content-blind producer-side clamp; nothing model-text-aware anywhere in it.Verification
nvcc -std=c++20 -arch=sm_120 -cclean on all three changed translation units (CUDA 13.4.2).!) degeneration face of After a 36,689-token request at 155k, every later request answers one repeated token until the engine reloads #606 appears on builds where the fused/S26 paths are enabled and is absent on boots that use the clamped path exclusively — consistent with the site inventory. The wider carried-state failure (restart-cures-it, spans sessions) is analyzed indocs/DEGENERATION_RCA.md; it involves two further purity violations of the state cache that this PR deliberately does not change code for.Scope
3 clamp lines + 2 includes + 2 docs. No behavior, tuning, or policy changes. Deployment-side mitigations we use in the interim (freezing the expert migrator with the existing flag, disabling the suffix-draft source, serve-layer repetition detectors) are listed as prose in the RCA doc so maintainers can route them properly — no code for them here.
Docs added:
docs/Q8_1_FINITE_DS.md— the invariant, the missed sites, diagnostic criteria for this defect class.docs/DEGENERATION_RCA.md— the full root-cause analysis: the restart-cure and cross-session-persistence localization levers, the three purity violations ofstate = f(prefix), the falsification tests that pinned each one, a field diagnostic protocol, and recommended engine-side remedies (tier-aware checkpoint identity for the residency split; reproducible policy inputs for the drafting side).