feat(qwen38): the w5nl64 heavier-quant campaign toolchain (fetch, BF16 reference, arms, FP8-anchored gate) #76

Merged
dank merged 7 commits from feat/qwen38-w5nl64 into main 2026-10-27 19:59:37 -07:00
Owner

What this is

The toolchain for the ordered campaign: cook a heavier / more faithful quant of
Qwen3.8-Flash-Next for radiance than the served qwen3.8-next-flash-fp8-iq4r-moe
,
and land it on frank-archon only if it beats what is running.

This PR ships no payload and deploys nothing. scripts/deploy-plan.py plans zero
services for every path in it (pinned by a test), so merging cannot drain the endpoint.
The 15 h 40 m of convert time happens later, in a drained window Frank authorizes.

The instrument, not a guess

Fidelity is scored against the vendor BF16 checkpoint, because the served payload is
quantized from that base — the Swift-1.5 finetune is a different model and its era is
retired. Acceptance is a KLD gate with two anchors: fp8 (the reference-grade
release) and iq4r (what is actually serving). An arm must land strictly inside the
interval those two define, at every slice
, with top-1 agreement no better than the
served payload's is not enough. The swift15 bar (KL ≤ 0.03 against BF16 alone) is retired
as an instrument: it can pass an arm that loses to production.

Arms

One recipe template, three arms generated per run from it, so the other 60 lines cannot
drift between arms:

arm expert row
control cd=3
cd6 same set with cd=6
ao1 act_order=1 and no cd= — libquant refuses the pair (lq_registry.cpp:105), so AoA is its own sweep, not a fourth column

Every routed expert at w5nl (five-bit codes in a 32-level table), fp8_e4m3 scales in
64-groups, the top level rotated through the 128-wide Hadamard GPTQ picks against the
calibration corpus. Protected experts stay bf16: --target-count sizes that plane by the
byte bill the pinned host pool can afford instead of by a fixed ratio, and the TP=2
parity law (each 256-expert rank half even) is a refusal, not a silent fix-up.

Gates that bite before the hours are spent

  • fetcher: shard census + per-shard byte count + Hub total, -f so an HTTP error body
    never becomes a "shard"
  • reference build: verified checkpoint, peak-disk bill (350,000 MiB — the .rad is built
    beside the 335 GiB checkpoint), --force retires to ~/.AGENTTRASH, --plan-only first
  • reference serve: drains frank-archon and restores on every exit path; one step-size
    knob and one window knob
    for both logits modes, so a reference and an arm cannot be
    measured at different shapes; refuses a corpus record that cannot fit the declared
    window before the drain, on --dry-run too
  • arms: the BF16 container still on the volume, a recording too thin to calibrate
    (uncalibrated convert only whispers on stderr), an imatrix outside the mounted dir, an
    arm that exists, a derivation that cannot land its target, a destination too small
  • gate: unordered anchors stop the run — the instrument is wrong, not the arm

Shape facts (measured, not assumed)

  • Production operating point is four slots over 2,048 (frank-archon.env:58, :97);
    the rig rides the same point.
  • The KLD corpus's longest record is 38,263 chars (~9.6 k tokens at the pessimistic
    chars/4), so the reference declares at --max-ctx 32768 — 2.6× inside. Dropping the flag
    hands the resolver the checkpoint's 262,144 window = 258.8 GiB of fp8 cache on a 192 GiB
    machine.
  • --max-num-batched-tokens is the throughput lever, not slot count; --vram-kv-mib is
    removed in the pinned 1.8.1 and naming it is a boot refusal (test-pinned).
  • Disk sequencing is forced by 754 GiB free: reference container is trashed after the one
    drained window, and the FP8 anchor is fetched last.

Verification

  • ./tests/run.sh → 558/558 ALL TESTS PASSED (new seams: qwen38_campaign 32,
    qwen38_reference 12, qwen38_grams 12). No e2e gate needed: nothing deployable changed.
  • Every new gate red-proofed by neutralising it on scratch copies (21 proofs; repo files
    were never the target), plus engine ground-truth against the pinned image GPU-less:
    the driver's full argv parses (--kv-cache-dtype fp8, the w5nl quant string,
    --plan-only), a bad value is refused at parse time, and --vram-kv-mib still refuses.
  • deploy-plan.py on every new path → empty plan, both targets.

What lands after this merges

The recipe header (scripts/recipes/qwen4exp-qwen38-w5nl64-bf16trunk.recipe) carries the
campaign's order end to end. Step 8 is the only file edit that touches production: the trio
plus deploy.sh dankserver --service frank-archon, and if the win needs the bigger pinned
plane, FRANK_ARCHON_HOST_POOL_MIB and FRANK_ARCHON_TTM_TARGET_MIB move in the same
commit — a pool raised without the TTM target is a boot refusal Restart=always repeats
forever. Rollback is the commit before it.


cwd: /home/blank/.omp/wt/wt-20261027-142335-6d1fc1f · session: 01a17f3f-3e2e-7509-aef8-be516c27cf98

# What this is The toolchain for the ordered campaign: **cook a heavier / more faithful quant of Qwen3.8-Flash-Next for radiance than the served `qwen3.8-next-flash-fp8-iq4r-moe`**, and land it on `frank-archon` only if it beats what is running. This PR ships **no payload and deploys nothing**. `scripts/deploy-plan.py` plans zero services for every path in it (pinned by a test), so merging cannot drain the endpoint. The 15 h 40 m of convert time happens later, in a drained window Frank authorizes. ## The instrument, not a guess Fidelity is scored against **the vendor BF16 checkpoint**, because the served payload is quantized from that base — the Swift-1.5 finetune is a different model and its era is retired. Acceptance is a **KLD gate with two anchors**: `fp8` (the reference-grade release) and `iq4r` (what is actually serving). An arm must land **strictly inside the interval those two define, at every slice**, with top-1 agreement no better than the served payload's is not enough. The swift15 bar (KL ≤ 0.03 against BF16 alone) is retired as an instrument: it can pass an arm that loses to production. ## Arms One recipe template, three arms generated per run from it, so the other 60 lines cannot drift between arms: | arm | expert row | |---|---| | control | `cd=3` | | cd6 | same set with `cd=6` | | ao1 | `act_order=1` and **no `cd=`** — libquant refuses the pair (`lq_registry.cpp:105`), so AoA is its own sweep, not a fourth column | Every routed expert at `w5nl` (five-bit codes in a 32-level table), `fp8_e4m3` scales in 64-groups, the top level rotated through the 128-wide Hadamard GPTQ picks against the calibration corpus. Protected experts stay bf16: `--target-count` sizes that plane by the **byte bill the pinned host pool can afford** instead of by a fixed ratio, and the TP=2 parity law (each 256-expert rank half even) is a refusal, not a silent fix-up. ## Gates that bite before the hours are spent - fetcher: shard census + per-shard byte count + Hub total, `-f` so an HTTP error body never becomes a "shard" - reference build: verified checkpoint, peak-disk bill (350,000 MiB — the .rad is built beside the 335 GiB checkpoint), `--force` retires to `~/.AGENTTRASH`, `--plan-only` first - reference serve: drains `frank-archon` and restores on every exit path; **one step-size knob and one window knob** for both logits modes, so a reference and an arm cannot be measured at different shapes; refuses a corpus record that cannot fit the declared window **before** the drain, on `--dry-run` too - arms: the BF16 container still on the volume, a recording too thin to calibrate (uncalibrated convert only whispers on stderr), an imatrix outside the mounted dir, an arm that exists, a derivation that cannot land its target, a destination too small - gate: unordered anchors stop the run — the instrument is wrong, not the arm ## Shape facts (measured, not assumed) - Production operating point is **four slots over 2,048** (`frank-archon.env:58`, `:97`); the rig rides the same point. - The KLD corpus's longest record is **38,263 chars** (~9.6 k tokens at the pessimistic chars/4), so the reference declares at `--max-ctx 32768` — 2.6× inside. Dropping the flag hands the resolver the checkpoint's 262,144 window = 258.8 GiB of fp8 cache on a 192 GiB machine. - `--max-num-batched-tokens` is the throughput lever, not slot count; `--vram-kv-mib` is removed in the pinned 1.8.1 and naming it is a boot refusal (test-pinned). - Disk sequencing is forced by 754 GiB free: reference container is trashed after the one drained window, and the FP8 anchor is fetched last. ## Verification - `./tests/run.sh` → **558/558 ALL TESTS PASSED** (new seams: `qwen38_campaign` 32, `qwen38_reference` 12, `qwen38_grams` 12). No e2e gate needed: nothing deployable changed. - Every new gate red-proofed by neutralising it on scratch copies (21 proofs; repo files were never the target), plus engine ground-truth against the pinned image GPU-less: the driver's full argv parses (`--kv-cache-dtype fp8`, the `w5nl` quant string, `--plan-only`), a bad value is refused at parse time, and `--vram-kv-mib` still refuses. - `deploy-plan.py` on every new path → empty plan, both targets. ## What lands after this merges The recipe header (`scripts/recipes/qwen4exp-qwen38-w5nl64-bf16trunk.recipe`) carries the campaign's order end to end. Step 8 is the only file edit that touches production: the trio plus `deploy.sh dankserver --service frank-archon`, and if the win needs the bigger pinned plane, `FRANK_ARCHON_HOST_POOL_MIB` and `FRANK_ARCHON_TTM_TARGET_MIB` move in the **same** commit — a pool raised without the TTM target is a boot refusal `Restart=always` repeats forever. Rollback is the commit before it. --- cwd: /home/blank/.omp/wt/wt-20261027-142335-6d1fc1f · session: 01a17f3f-3e2e-7509-aef8-be516c27cf98
dank added 7 commits 2026-10-27 19:41:12 -07:00
The w5nl64 campaign measures against the vendor checkpoint, not the Swift-1.5
finetune: the served payload (qwen3.8-next-flash-fp8-iq4r-moe) is quantized from
this base, so fidelity must be scored against the same reference. 335.3 GiB
across 10 shards.

Verifier gates on the index's own shard list, each shard's declared byte count,
and the Hub's declared total - a curl without -f writes the 401 body as the
'shard' and reports success. --fetch refuses when the destination cannot hold
the checkpoint, because a 335 GiB download that fills the disk mid-shard costs
the whole campaign window.
The swift15 rule (top 7% by imatrix energy, bar-only) left the plane size to the
distribution. The w5nl64 arm trades a *pinned host pool* against KL, so the
operator needs to say how many GiB of bf16 experts the pool can afford and have
the set land there: --target-count walks the ranked candidates until the byte
bill matches, keeps the bar-only pass for experts that are disproportionate for
their size, and reports the pool's ceiling instead of padding when the count
cannot be reached.

TP=2 cuts the expert plane into two 256-expert rank halves, and an odd count in
either half unbalances the placement, so the parity audit is a refusal (exit 2,
'PARITY LAW BROKEN'), not a silent fix-up: the driver stops rather than
converting a payload whose expert placement no one priced.
rad-convert's GPTQ path reads importance from an imatrix GGUF; the reference
container's --kld-record pass emits per-expert and per-hidden Grams as raw
recordings. This folds them into one v3 file: a single expert-major f32 entry
per MoE layer plus the hidden-width entries, every data offset a multiple of
general.alignment as the loader requires.

Refusals, each one a silent-worse outcome the swift15 campaign hit: an expert
with no gram of its own carries the layer's pooled diagonal and the count is
reported (a silent zero is a down-quantized expert nobody priced); expert grams
with no pooled gram, a gram short by one float (names the file), the same global
expert recorded twice with different numbers, an empty recording directory, and
an existing output. --min-rows sets the noise floor below which a recording is
dropped. rows is u64 so a corpus that outgrows u32 survives the header instead
of wrapping.
One template (every routed expert at five bits, E4M3 scales in 64-groups, the
top level rotated through the 128-wide Hadamard chosen by GPTQ against CALIB)
plus a driver that generates the per-arm expert row, so the other 60 lines can
never drift between arms: control (cd=3), cd=6, and act_order=1 with NO cd= -
libquant refuses the pair (lq_registry.cpp:105), so the AoA arm is its own
sweep, not a fourth column.

The header carries the campaign's order (fetch -> build reference -> one drained
window for the calibration tap and the KLD reference -> trash the bf16 container
-> imatrix -> arms -> fetch the FP8 anchor last -> gate -> trio edit), because
that sequence is point-of-use for whoever runs it next, and the disk sequencing
is forced: 754 GiB free does not hold checkpoint + reference + three arms.

Gates that bite before 5h13m of convert time is spent: the BF16 reference still
occupying the volume, a recording too thin to be a calibration (converting
uncalibrated is silently worse and only whispers on stderr), an imatrix outside
the mounted campaign dir, an arm that already exists, a protected derivation
that cannot land its target, and a destination that cannot hold the output. Each
arm runs --plan-only first so the engine's own fit check bills at plan time; the
served container's argv shape is what the arms declare.
The swift15 gate compared an arm against the BF16 reference and passed on
KL <= 0.03. That bar is now the wrong instrument: the fleet already ships the
publisher's FP8-native iq4r-moe payload, so an arm that beats BF16 but loses to
what is running is a downgrade. The gate takes three recordings - fp8 anchor,
iq4r anchor, candidate - and requires the candidate's KL strictly inside the
interval the two anchors define, at every slice, plus top-1 agreement no worse
than the served payload.

The anchors must be ordered (fp8 better than iq4r) or the run stops: an
unordered pair means the instrument or the recording is wrong, not that the arm
lost, and one number out of the report is named rather than guessed at.
--recover prints the tightened numbers the same way it prints the failing ones,
so the operator sees the bar they would have had to clear.
32 black-box tests over the four tools the campaign runs, driven through their
own argv with fixture corpora - no GPU, no container, no rad-convert. Each test
is an output an operator reads: the verifier's MISSING line and exit, the byte
bill the derivation lands, the refusal text, the plan and the convert the driver
prints per arm, the interval verdict the gate returns.

Includes the planner seam the swift15 campaign lacked: the campaign's paths plan
NO deployable service, so merging this toolchain can never drain frank-archon.
The driver fixture carries four grams so --min-grams has a thin-pool control,
and the arm-driver invocation passes env assignments positionally after the
driver's own flags, so the seam exercises the real call shape.
Two tools the KLD gate depends on.

build-qwen38-bf16-rad.sh converts the checkpoint to a BF16 .rad with NO recipe
line, so every tensor stays bf16 - the reference must not carry the quantization
it is there to measure. It gates before writing 335 GiB: the checkpoint present
and fully verified by the fetcher's own verifier, the peak-disk bill (350,000
MiB: the checkpoint's 343,323 plus margin, because the .rad is built beside it),
an existing output retired to ~/.AGENTTRASH by --force instead of deleted, and
--plan-only before the real convert. --max-ctx 32768 is a declare-time check, not
a weight change: dropped, the resolver is handed the checkpoint's 262,144 window,
which at fp8 cache is 258.8 GiB on a 192 GiB machine.

run-qwen38-bf16.sh serves that container in three modes - kldref (record the
reference logits), score (record an arm's logits against that reference), calib
(open the Gram tap for the imatrix). It drains frank-archon and restores it on
every exit path, and the two logits modes ride ONE step size
(FRANK_QWEN38_MNBT, default 2048) and ONE window (FRANK_QWEN38_MAX_MODEL_LEN,
default 32768) so a reference and an arm cannot be measured at different shapes:
that is the whole validity of the KL number. Four slots over 2,048 matches
frank-archon.env's operating point (MAX_SEQS=4, MAX_BATCHED_TOKENS=2048); the
smaller host pool (12,288 vs 49,152) buys residency, which moves speed, not
logits. calib keeps 65,536 - decode-bound serving, never the gate.

kldref refuses before the drain when the corpus's longest record cannot fit the
declared window (limit = window x 3 chars, the pessimistic tokenizer bound; the
measured corpus is 38,263 chars, 2.6x inside 32,768). It runs on --dry-run too,
so the check is visible before a 20-minute drain is spent. 12 seam tests, each
red-proofed by neutralising the gate it pins.
dank merged commit 8270524edd into main 2026-10-27 19:59:37 -07:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dank/serverAppConfigs#76