The gap
test_minimax_h3 runs 44 live calls into vllm::DequantNvfp4ToBf16 and asserts
57,395 things, and not one of them can see the fp4 nibble order flip. Measured
directly, not inferred: instrument the function with a call counter, then mutate its shared
default from kLowFirst to kHighFirst (mutation M3 in
.agents/specs/nvfp4-nibble-order.md §5.5) and rebuild. Three of the ten NVFP4 gates turn
red. test_minimax_h3 stays Status: SUCCESS! at 79 cases / 57,395 assertions, byte
identical to baseline. test_qwen3_forward does the same at 30 live calls.
E2M1 packs two 4-bit values per byte. Reading the wrong nibble first transposes every
adjacent pair. The result is finite, correctly shaped and correctly scaled — the group
scale, the absmax and every magnitude summary are identical by construction, which is why
these suites cannot feel it.
Why it matters now, and not only in principle
H3's NVFP4 checkpoints are HIGH-nibble-first, and H3 reaches the standard low-first read by
normalizing its bytes at load — MiniMaxH3Nvfp4SwapNibbles, behind
MiniMaxH3Nvfp4HighNibbleFirst() (minimax_h3.h:1500-1517) — and then calling the shared
dequant with the default order. That was the right design for H3, whose bytes also feed a
Marlin fp4-resident path where one byte transform fixes both arms.
#571 adds a second mechanism for the same concept: an Nvfp4NibbleOrder parameter on the
shared DequantNvfp4ToBf16, for LTX-2.5, which has no fp4-resident arm. Both mechanisms are
deliberate and .agents/specs/nvfp4-nibble-order.md §3.1 records which to use when.
The hazard is composition. If H3 is ever routed through the new kHighFirst parameter
while the load-time swap stays default-ON, the two compose into a double flip — exactly the
defect both were built to prevent — and nothing in the tree fires. The mechanism that would
catch it is the one H3 does not have.
What is owed
A nibble-sensitive gate for the H3 NVFP4 arm: one that turns RED when the effective nibble
order changes, by either mechanism or by both.
The instrument already exists. H3's own FL2VA-GGUF correlation is the same
independent-oracle technique #571 just built for LTX-2.5 — dequantize the same module from
two files that quantize the same base weights and correlate. It separates a nibble
transposition cleanly (LTX-2.5 measures 0.994968 correct vs −0.00239 transposed) precisely
because the two readings decode the same multiset per group, so nothing weaker than a
correlation can tell them apart.
Two properties the gate must have, both learned the hard way in #571:
- A control arm. Correlate against a DIFFERENT module's weights and require the
correlation to collapse, or the fixture cannot separate a correct implementation from a
plausible wrong one.
- A band, not a ceiling, on relative rms. Pearson correlation is scale-invariant, so it
cannot see a systematic scale error at all, and an unbounded-below tolerance passes an arm
that has quietly started comparing the oracle to itself.
Also worth folding in while the suite is open: five of the ten NVFP4 gates
(test_qwen36_weights, test_ops_nvfp4_matmul, test_ops_moe_grouped,
test_ops_nvfp4_fp4, test_ltx2_device) make zero calls into the function on a default
run, so their byte-identical counts are evidence of nothing about it. That is fine as long as
nobody quotes them as coverage — §5.5 now records the per-gate call counts so nobody does.
Evidence
.agents/specs/nvfp4-nibble-order.md §5.5 carries the full call-count / M3 table.
Found during the fresh review of #571 (issue #435).
The gap
test_minimax_h3runs 44 live calls intovllm::DequantNvfp4ToBf16and asserts57,395 things, and not one of them can see the fp4 nibble order flip. Measured
directly, not inferred: instrument the function with a call counter, then mutate its shared
default from
kLowFirsttokHighFirst(mutation M3 in.agents/specs/nvfp4-nibble-order.md§5.5) and rebuild. Three of the ten NVFP4 gates turnred.
test_minimax_h3staysStatus: SUCCESS!at 79 cases / 57,395 assertions, byteidentical to baseline.
test_qwen3_forwarddoes the same at 30 live calls.E2M1 packs two 4-bit values per byte. Reading the wrong nibble first transposes every
adjacent pair. The result is finite, correctly shaped and correctly scaled — the group
scale, the absmax and every magnitude summary are identical by construction, which is why
these suites cannot feel it.
Why it matters now, and not only in principle
H3's NVFP4 checkpoints are HIGH-nibble-first, and H3 reaches the standard low-first read by
normalizing its bytes at load —
MiniMaxH3Nvfp4SwapNibbles, behindMiniMaxH3Nvfp4HighNibbleFirst()(minimax_h3.h:1500-1517) — and then calling the shareddequant with the default order. That was the right design for H3, whose bytes also feed a
Marlin fp4-resident path where one byte transform fixes both arms.
#571 adds a second mechanism for the same concept: an
Nvfp4NibbleOrderparameter on theshared
DequantNvfp4ToBf16, for LTX-2.5, which has no fp4-resident arm. Both mechanisms aredeliberate and
.agents/specs/nvfp4-nibble-order.md§3.1 records which to use when.The hazard is composition. If H3 is ever routed through the new
kHighFirstparameterwhile the load-time swap stays default-ON, the two compose into a double flip — exactly the
defect both were built to prevent — and nothing in the tree fires. The mechanism that would
catch it is the one H3 does not have.
What is owed
A nibble-sensitive gate for the H3 NVFP4 arm: one that turns RED when the effective nibble
order changes, by either mechanism or by both.
The instrument already exists. H3's own FL2VA-GGUF correlation is the same
independent-oracle technique #571 just built for LTX-2.5 — dequantize the same module from
two files that quantize the same base weights and correlate. It separates a nibble
transposition cleanly (LTX-2.5 measures 0.994968 correct vs −0.00239 transposed) precisely
because the two readings decode the same multiset per group, so nothing weaker than a
correlation can tell them apart.
Two properties the gate must have, both learned the hard way in #571:
correlation to collapse, or the fixture cannot separate a correct implementation from a
plausible wrong one.
cannot see a systematic scale error at all, and an unbounded-below tolerance passes an arm
that has quietly started comparing the oracle to itself.
Also worth folding in while the suite is open: five of the ten NVFP4 gates
(
test_qwen36_weights,test_ops_nvfp4_matmul,test_ops_moe_grouped,test_ops_nvfp4_fp4,test_ltx2_device) make zero calls into the function on a defaultrun, so their byte-identical counts are evidence of nothing about it. That is fine as long as
nobody quotes them as coverage — §5.5 now records the per-gate call counts so nobody does.
Evidence
.agents/specs/nvfp4-nibble-order.md§5.5 carries the full call-count / M3 table.Found during the fresh review of #571 (issue #435).