Investigation: does the 6-bit core make K4-Core-K6 think longer?

K4-Core-K6 thought longer than K4 on CuteAFD in the run that raised this question (code 1.43x, prose 1.19x, read after the fact). Rerun on CuteAFD with new seeds under a frozen protocol, the gap is 1.15x [0.97, 1.32]: smaller, inconclusive under the frozen rule, and mostly on code (1.27x). A third checkpoint that keeps K4-Core-K6's routed experts but restores its BF16 core separates the two parts: the experts contribute nothing measurable (0.99x [0.93, 1.05]), so what difference there is goes with the 6-bit core (1.16x [0.98, 1.36]). On fixed reasoning traces neither part changes when the model decides to stop, on CuteAFD (whose two launches score bit-identically) or on the vLLM fork. Whether the core changes how often replies loop is open.

Direction, everywhere on this page except the vLLM per-group table: ratios put K4-Core-K6, or the part of it under test, first (above 1 = it thought longer); differences are K4-Core-K6's side minus the other (below 0 = it was less ready to stop). G4's published reading is stated the other way (BF16 / 6-bit = 0.80); here it is 1.25.

At a glance

Each answer with the file it comes from. CuteAFD v4.0.0 and tpurtell's vLLM fork v0.9.2 (with a local loader modification), two RTX PRO 6000
QuestionResultSource
Did K4-Core-K6 think longer than K4 on CuteAFD?reasoning tokens, seed-pairedFirst run (post hoc): code 1.43x [1.20, 1.59], prose 1.19x. Frozen rerun, new seeds: 1.15x [0.97, 1.32]; code 1.27x, prose 1.04x. not detected (inconclusive)BLOCK-L-POSTHOC.json, S1-RESULT.json
Is it the routed experts?K4-Core-K6's experts / K4's, same core bytes0.99x [0.93, 1.05]: no measurable contributionS1-RESULT.json
Is it the 6-bit core?6-bit core / BF16 core converted to FP8, same experts1.16x [0.98, 1.36]; above 1 on all 4 code prompts (1.24, 1.37, 1.09, 1.32). not detected (inconclusive)S1-RESULT.json
Does the core change when the model stops, on fixed text?log p(</think>) where 77 GPQA traces stoppedNo, on either engine: vLLM fork −0.005 [−0.019, +0.009], CuteAFD −0.011 [−0.039, +0.017]; experts +0.004 [−0.025, +0.031]G2-SCORES-A1.json, S2-READ.md
Do two launches of the same model agree?CuteAFD: bit-identical on 93,670 of 93,670 scored rows. vLLM fork: no; the launch difference (+0.006) is as large as the core'sS2-IDENTITY.json
Does the core change decode speed?median tok/s, code / prose, CuteAFD6-bit core 121 / 79; BF16→FP8 core 130 / 88; K4 129 / 88: the native 6-bit core is the slower partsamples.csv
Does the core change how often replies loop?Open: 1 loop in 18 replies (6-bit core) and 0 in 12 (BF16 core) on one GPQA question, vLLM fork; 0 capped of 96 replies in the CuteAFD rerunG4-RESULT.md, samples.csv

Thinking length in free generation

Thinking length in free generation, every measurement (ratio, log scale)

What this shows. Each row is a ratio of reasoning tokens with its 95% interval (over prompts; for G4, over replies). Small marks are the individual prompts. A solid line excludes 1; a light dashed one does not.

CuteAFDvLLM forkinterval excludes 1interval includes 1one prompt
0.67x0.8x1.25x1.5x2x1x← thinks lessthinks longer →same lengthCuteAFD v4 Block L, K4-Core-K6 / K4, 2 runs (post hoc; the observation)CuteAFD frozen rerun, new seeds, code + prose (8 prompts, 32 pairs)vLLM fork, GPQA question 12 (G4), 6-bit core / BF16 core, 12 replies eachCode: 1.43x [1.20, 1.59]Code4 prompts, 16 pairsBlock L code p0: 1.61xBlock L code p1: 1.10xBlock L code p2: 1.50xBlock L code p3: 1.56x1.43x [1.20, 1.59]Prose: 1.19x [1.06, 1.39]Prose4 prompts, 16 pairsBlock L prose p0: 1.08xBlock L prose p1: 1.52xBlock L prose p2: 1.20xBlock L prose p3: 1.03x1.19x [1.06, 1.39]JSON: 1.07x [0.99, 1.21]JSON3 prompts, 12 pairsBlock L json p0: 0.99xBlock L json p1: 1.03xBlock L json p2: 1.21x1.07x [0.99, 1.21]Reasoning: 1.05x [0.85, 1.39]Reasoning4 prompts, 16 pairsBlock L reasoning p0: 0.97xBlock L reasoning p1: 1.56xBlock L reasoning p2: 0.81xBlock L reasoning p3: 1.00x1.05x [0.85, 1.39]Total: K4-Core-K6 / K4: 1.15x [0.97, 1.32]Total: K4-Core-K6 / K4code 1.27x · prose 1.04xTotal code-p0: 1.35xTotal code-p1: 1.47xTotal code-p2: 1.17xTotal code-p3: 1.13xTotal prose-p0: 1.16xTotal prose-p1: 1.45xTotal prose-p2: 0.99xTotal prose-p3: 0.70x1.15x [0.97, 1.32]Core: 6-bit / BF16→FP8: 1.16x [0.98, 1.36]Core: 6-bit / BF16→FP8code 1.25x · prose 1.08xCore code-p0: 1.24xCore code-p1: 1.37xCore code-p2: 1.09xCore code-p3: 1.32xCore prose-p0: 1.21xCore prose-p1: 1.65xCore prose-p2: 0.91xCore prose-p3: 0.74x1.16x [0.98, 1.36]Experts: K4-Core-K6's / K4's: 0.99x [0.93, 1.05]Experts: K4-Core-K6's / K4'scode 1.02x · prose 0.97xExperts code-p0: 1.08xExperts code-p1: 1.07xExperts code-p2: 1.08xExperts code-p3: 0.85xExperts prose-p0: 0.96xExperts prose-p1: 0.88xExperts prose-p2: 1.09xExperts prose-p3: 0.96x0.99x [0.93, 1.05]All replies (frozen): 1.25x [0.88, 1.98]All replies (frozen)one reply looped to the cap1.25x [0.88, 1.98]Finished replies (post hoc): 1.03x [0.83, 1.28]Finished replies (post hoc)11 vs 121.03x [0.83, 1.28]

How to use it. Read the first two blocks together: the same prompts, first in the run that raised the question, then rerun with new seeds and split into core and experts. The rerun's code prompts stay above 1, smaller; prose moves toward 1; the experts sit at 1.

Table view: the exact numbers
MeasurementContentPairsRatio95% interval, prompts95% interval, pairsPer prompt
Block L (post hoc), K4-Core-K6 / K4code161.43x[1.20, 1.59]—1.61, 1.10, 1.50, 1.56
Block L (post hoc), K4-Core-K6 / K4prose161.19x[1.06, 1.39]—1.08, 1.52, 1.20, 1.03
Block L (post hoc), K4-Core-K6 / K4json121.07x[0.99, 1.21]—0.99, 1.03, 1.21
Block L (post hoc), K4-Core-K6 / K4reasoning161.05x[0.85, 1.39]—0.97, 1.56, 0.81, 1.00
Rerun total, K4-Core-K6 / K4code + prose321.15x[0.97, 1.32][1.02, 1.29]code 1.35, 1.47, 1.17, 1.13; prose 1.16, 1.45, 0.99, 0.70
Rerun core, 6-bit / BF16→FP8code + prose321.16x[0.98, 1.36][1.01, 1.31]code 1.24, 1.37, 1.09, 1.32; prose 1.21, 1.65, 0.91, 0.74
Rerun experts, K4-Core-K6's / K4'scode + prose320.99x[0.93, 1.05][0.87, 1.12]code 1.08, 1.07, 1.08, 0.85; prose 0.96, 0.88, 1.09, 0.96
vLLM G4 (frozen), 6-bit / BF16GPQA q1212 seed pairs1.25x[0.88, 1.98]—one question
vLLM G4 finished only (post hoc)GPQA q1211 vs 121.03x[0.83, 1.28]—one question

Sources: BLOCK-L-POSTHOC.json, S1-RESULT.json, G4-RESULT.json (G4 inverted here), G4-RESULT.md (finished-only); per reply: samples.csv.

The stop decision on fixed traces

The stop decision on fixed traces, both engines

What this shows. The same 77 finished GPQA reasoning traces, fed token by token to each arm. Each row is the paired difference in log p(</think>) at the token where the trace stopped thinking, with its 95% interval over traces. The shaded band is the vLLM fork's difference between two launches of the same model; CuteAFD's two launches are identical, so it has none.

vLLM forkCuteAFDvLLM launch-to-launch differenceinterval includes 0
−0.06−0.04−0.02+0.02+0.040← less ready to stopmore ready →no changevLLM fork (G2), 77 finished tracesCuteAFD (the same 77 traces); second launch bit-identicalvLLM fork, 6-bit core minus BF16 core6-bit core − BF16 coreband: second launch differs by +0.006−0.005 [−0.019, +0.009]CuteAFD Core: 6-bit − BF16→FP8Core: 6-bit − BF16→FP8same experts−0.011 [−0.039, +0.017]CuteAFD Experts: K4-Core-K6's − K4'sExperts: K4-Core-K6's − K4'ssame core bytes+0.004 [−0.025, +0.031]CuteAFD Total: K4-Core-K6 − K4Total: K4-Core-K6 − K4−0.007 [−0.044, +0.026]

How to use it. Every interval includes 0. The traces are GPQA reasoning, the content where free generation shows no length difference; code text was not scored this way.

Table view: the exact numbers
EngineContrastlog p(</think>) at the stopHazard, ×10⁻⁵Top-64 KL, all rowsSecond launch
vLLM fork6-bit core − BF16 core−0.005 [−0.019, +0.009]+0.400.0071+0.006 (KL 0.0040)
CuteAFDCore: C-K6 − C-K6x−0.011 [−0.039, +0.017]+0.96 [−0.78, +2.84]0.01270 (bit-identical)
CuteAFDExperts: C-K6x − C-K4+0.004 [−0.025, +0.031]−0.17 [−2.14, +1.62]0.02120 (bit-identical)
CuteAFDTotal: C-K6 − C-K4−0.007 [−0.044, +0.026]+0.79 [−1.28, +2.82]0.02590 (bit-identical)

Hazard: mean p(</think>) over the 512 tokens before the stop. KL: top-64, nats per token, between the two arms of the row (experts: 0.0203 with the other arm as reference). Sources: G2-SCORES-A1.json, S2-SCORES-base-C-K6.json, S2-SCORES-base-C-K6x.json, S2-IDENTITY.json; per probe: s2-probes.csv.

How the results fit together

CuteAFD: core or experts?

Three arms on CuteAFD v4.0.0 (unmodified launcher; serving and scoring configs differ only in the checkpoint). 32 replies per arm in free generation, all finished, none capped; 93 fixed traces per arm
ArmCheckpointCore at runtimeReasoning tokens (median), code / proseDecode tok/s, code / prose
K4-Core-K6C-K6wrldsuksgo2mars/GLM-5.3-Flash-EXL3-K4-Core-K6 @ 5d3fffe1native 6-bit EXL3
experts: K4-Core-K6's
36.9K / 17.7K121 / 79
K4-Core-K6, BF16 coreC-K6x · local derived checkpoint, not a producer releasebuilt by build_derived.py from the row above and the core of zai-org/GLM-5.3-Flash-BF16 @ f9fed3bbBF16 → FP8 at load, as K4
experts: K4-Core-K6's
31.6K / 18.3K130 / 88
K4C-K4brandonmusic/GLM-5.3-Flash-tr3-4bpw @ a5fee929BF16 → FP8 at load
experts: K4's
33.7K / 18.7K129 / 88
The BF16 core tensors are byte-identical to K4's (316 of 316; core-hash.json), so core minus experts isolates each part. CuteAFD's planner gives the derived checkpoint the same plan as K4 (FP8 core projections, FP8 head, same KV pool). Medians are of all 16 replies per content, not paired; the ratios above are paired.

Free generation: Block L stage L3 (130,048-token cap, 2 in flight, thinking on), the same 4 code and 4 prose prompts as the run that raised the question, two new seed sets; each seed is shared by the three arms. All 96 replies finished. Reasoning tokens are counted by re-tokenizing the saved reasoning text. Frozen rule: a difference is detected when the 95% interval over the 8 prompts excludes 1; the interval over the 32 pairs is secondary. Read: S1-READ.md.

Fixed traces: the 93 traces of the vLLM investigation (token ids unchanged), scored on CuteAFD's bench probe with a cold cache and drafting off; 93,670 rows per arm; the longest trace (95,362 tokens) took 88 s. The thinking-length run's scorer is used unchanged. Read: S2-READ.md.

A note on one measure. “Max p(</think>) on unfinished traces” (the last column of the vLLM per-group table below) falls on the first scored row, the opening of the reasoning span, in 46 of 48 trace-arms on CuteAFD and 180 of 192 on the vLLM fork. That row is the same for every trace of a question, so the measure is mostly a per-question value counted once per trace. On CuteAFD it flagged the experts (one question carries it); with the opening row removed the order of the arms changes from question to question. On the vLLM fork no group met the rule on it. Post hoc: POST-HOC-S2.json.

vLLM fork: core groups on fixed traces (G2)

Direction as published: BF16 − 6-bit. Each group loaded from BF16 alone, everything else 6-bit; change against the 6-bit core, paired over traces, 95% bootstrap interval. A bar is solid when its interval excludes 0
Swapped to BF16log p(</think>) at the closeShare of the reference gapFrozen ruleHazard, ×10⁻⁵Max p on unfinished, ×10⁻⁶
All 316 core tensors316 tensors · the reference gap+0.005[−0.009, +0.019]——−0.40+2.6
KDA q, k, v projections102 tensors+0.003[−0.010, +0.017]0.5—−0.15+3.7
KDA output projection34 tensors+0.009[−0.001, +0.020]1.9—−0.57−5.6
MLA q_a and kv_a projections22 tensors−0.001[−0.014, +0.010]-0.2—−0.15−1.4
MLA q_b projection11 tensors+0.014[+0.002, +0.026]2.9meets the rule+0.33−1.8
MLA output projection11 tensors+0.017[+0.007, +0.029]3.5meets the rule−0.42−0.5
dense MLP (first layers)9 tensors+0.010[−0.003, +0.024]2.1—−0.21+0.3
shared expert gate and up84 tensors+0.004[−0.011, +0.020]0.9—−0.21−4.8
shared expert down42 tensors+0.014[−0.002, +0.028]2.8—−0.48−6.2
output head1 tensor+0.004[−0.010, +0.014]0.7—−0.62+1.1
Second launch, no swaplaunch-to-launch variation+0.006[−0.005, +0.018]——−1.00+0.5
Frozen rule (with Amendment 1): a group moves a measure when it closes at least half the gap to the all-BF16 core, its interval excludes 0 and its change exceeds the second launch's. Hazard: mean p(</think>) over the 512 tokens before the close. Max p: largest p(</think>) along the 16 traces that did not finish; mostly a per-question value (note above). Source: G2-SCORES-A1.json.

vLLM fork: free generation (G4)

GPQA diamond question 12 (a steady long thinker: 25-39K tokens in 6 earlier samples), temperature 1.0, top-p 0.95, thinking on, cap 327,680 tokens, seeds 51201-51212 on both arms
ArmFinished / loopedCompletion tokens, sortedMediansd of log tokensCorrect
6-bit core11 / 123.4K 23.9K 24.1K 26.1K 28.8K 31.9K 32.0K 36.1K 43.5K 45.6K 51.5K 327.7K32.0K0.7211 of 12
BF16 core12 / 017.1K 20.5K 25.6K 27.8K 29.0K 30.7K 33.8K 33.8K 38.7K 42.6K 45.0K 45.3K33.8K0.3111 of 12
Frozen reading (as published, BF16 / 6-bit): 0.80, 95% interval [0.51, 1.14]; stated 6-bit / BF16 on this page: 1.25 [0.88, 1.98]. The interval includes 1 and is wider than [0.8, 1.25] (inconclusive); its width comes from the one loop. Post hoc, finished replies only: 0.97 [0.78, 1.21] (6-bit / BF16 1.03); sd of log tokens 0.28 and 0.31 against 0.19 earlier, so this design resolves about a 1.3x change. The loop (seed 51203) repeated one sentence to the cap, 1.49M characters, no answer. Sources: G4-RESULT.json, G4-RESULT.md.

Loops: what the records show

Replies that reached the 327,680-token cap on the seven most length-variable GPQA questions (186, 12, 81, 120, 86, 74, 13)
CheckpointEngineRequestsAt the capWhole benchmark
K3.25vLLM fork 0.7.0-0.9.1, several configurations354 (11.4%)19 of 990 (1.9%)
K4vLLM fork 0.8.0-0.9.1283 (10.7%)23 of 792 (2.9%)
K4-Core-K6, 6-bit corevLLM fork 0.9.2 + local loader424 (9.5%)—
K3.25 and K4: every GPQA record of local-inference-evals that logged token counts. Counting the older records too, with an empty answer standing in for a cap hit: 6 of 70 and 4 of 42. K4 against K4-Core-K6: Fisher p = 1.0. Engine versions, concurrency and loader differ between rows. Questions 81 and 13 carry most cap hits (K4-Core-K6: 4 of 12). Source: LOOP-CHECKS.json.

What was tested

Reproduce and re-analyse

  1. Inputs. Checkpoints wrldsuksgo2mars/GLM-5.3-Flash-EXL3-K4-Core-K6 @ 5d3fffe1, brandonmusic/GLM-5.3-Flash-tr3-4bpw @ a5fee929 and the BF16 source zai-org/GLM-5.3-Flash-BF16 @ f9fed3bb; engines tpurtell's CuteAFD v4.0.0 (tpurtell/cuteafd) and vLLM fork v0.9.2 (tpurtell/glm-5.3-flash-ext3-2x-rtx) with the local loader modification.
  2. Derived checkpoint. build_derived.py (standard library; rewrites the shards that hold core tensors, hardlinks the rest); check with hash_core.py against core-hash.json and derived-manifest.json.
  3. CuteAFD runs. Configs in results/2026-11-03-cuteafd-core-swap/code/configs; the chain chain-cs.sh; drivers results/2026-11-03-cuteafd-core-swap/code/drivers (fixed-trace probes, identity check, Block L with new seeds) and the v4 Block L driver results/2026-11-03-cuteafd-core-swap/code/v4-drivers, which imports block_l.py.
  4. Scoring. Reasoning tokens: analyze_l.py; free generation: analyze_s1.py and block_l_posthoc.py (both read samples.csv's fields); fixed traces: score_stop.py, post_hoc_s2.py.
  5. Third-party analysis without the run. samples.csv (one row per reply: arm, seed, finish, reasoning tokens, decode speed), s2-probes.csv (one row per probe, with a digest of the per-row logits hashes), the per-trace scores in results/2026-11-03-cuteafd-core-swap/analysis and results/2026-11-02-thinking-length/analysis; every number on this page is in SUMMARY.json or SUMMARY.json.
  6. Not published. Reply and reasoning texts (model output), GPQA question text and the fixed traces' token ids (dataset terms), capture and probe dumps (top-64 log-probabilities of model output), and checkpoint weights (rebuild them from the public sources with the script above).

Open questions

Caveats

Data: CuteAFD part results/2026-11-03-cuteafd-core-swap (SUMMARY.json, S1-READ.md, S2-READ.md, protocol/); vLLM part results/2026-11-02-thinking-length (SUMMARY.json, G2-RESULT.md, G4-RESULT.md, LOOP-CHECKS.md, protocol/). Reasoning texts, question text and dumps are not published.