Skip to content

🔨 feat(quants): use the importance matrix when encoding NVFP4 - #66

Open
worthant wants to merge 1 commit into
masterfrom
feat/nvfp4-imatrix
Open

🔨 feat(quants): use the importance matrix when encoding NVFP4#66
worthant wants to merge 1 commit into
masterfrom
feat/nvfp4-imatrix

Conversation

@worthant

@worthant worthant commented Aug 5, 2026

Copy link
Copy Markdown
Member

Upstream quantize_nvfp4 takes quant_weights and immediately does GGML_UNUSED(quant_weights), so an importance matrix has no effect on this type while every K and IQ type uses one.

The scale of an NVFP4 sub-block is stored as UE4M3, so neighbouring scales sit ~12.5% apart. Rounding to amax/6 picks one point on that grid and it is rarely the best one: a slightly smaller scale clips the single largest weight but resolves the other fifteen better. This walks eight codes around that point, and for each one refits the scale against its own assignment by weighted least squares, keeping whichever candidate has the lowest importance-weighted error.

Blocks with all-zero importance, which is what experts the calibration corpus never routed to look like, fall back to magnitude-only weights. Without that the weighted error is degenerate and the search picks an arbitrary scale; an earlier revision that missed this case measured a mean KLD of 2.76.

Measurements

Ling-3.0-flash, mean KL divergence against the bf16 baseline, 92 chunks of held-out text at 4096 tokens, 4x RTX PRO 6000:

build mean KLD top-1
NVFP4, imatrix discarded 0.05602 94.721%
NVFP4, this patch 0.05363 94.865%

A 4.3% reduction in KLD for no change in file size, format or inference cost; the work is paid once at quantization time. The measurement is one model on one corpus, and the spread between the encoder variants tried along the way (0.05363 to 0.05392) is close to the +-0.001 error bar, so treat the ranking among those as unresolved. The gap to the unweighted encoder is about 2.4x the error bar.

Raw logs: AtomicChat/Ling-3.0-flash-GGUF-metrics.

Not done yet

Before this is worth proposing upstream it needs a sha256 check that output without an imatrix is byte-identical to before, an explicit all-zero imatrix test, numbers on a dense model such as Llama-3.1-8B on wikitext2, and the quantization-time cost of the search.

quantize_nvfp4 discarded quant_weights, so an imatrix changed nothing for
this type while every K and IQ type uses it. Encode each sub-block by
searching the ue4m3 scale grid around amax/6 under an importance-weighted
error, refitting the scale against its own assignment. Blocks whose
importance is entirely zero, which happens for experts the corpus never
routed to, fall back to magnitude-only weights so the search stays
well posed. Without an imatrix the reference encoder is still used, so
existing output is unchanged.

On Ling-3.0-flash the mean KL divergence against bf16 drops from 0.05602
to 0.05363 and top-1 agreement rises from 94.721% to 94.865%.
@github-actions github-actions Bot added the ggml label Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant