Skip to content

mtp_pack: Q2_0 scale search over 0.15 to 1.0 x max|w|, either sign - #1934

Closed
gputier wants to merge 5 commits into
Niko1221:mainfrom
gputier:pr/mtp-scale-0.1.42
Closed

gputier wants to merge 5 commits into
Niko1221:mainfrom
gputier:pr/mtp-scale-0.1.42

Conversation

@gputier

@gputier gputier commented Oct 11, 2026

Copy link
Copy Markdown
Contributor

tools/mtp_pack.py picks each Q2_0 block's scale among 17 positive values between 0.5 and 1.0 times the block's max |w|. The levels are -1, 0, 1 and 2, so they are not symmetric, and a negative scale is often closer: it puts the level 2 on the side where the block's largest weights are. This PR searches 0.15 to 1.0 times max |w| for both signs. It keeps the previous 17 candidates in the set and rounds each scale to fp16 before measuring it, so no block ends up with a larger error than before. The file format does not change, and neither does the engine: the kernels already read a signed scale.

Relative RMS error of the packed draft experts, on synthetic blocks (tools/test_mtp_pack.py): 0.855 of the previous search on normal weights, 0.824 on Laplace, 0.833 on Student t3. The test also checks every block, and that the packed bytes decode, through tools/gguf_writer.dequantize_q2_0, to the values the search measured. A scale too large for fp16 now raises an error. One that rounds to 0 keeps the previous behaviour.

expert_multi_test now gives half of its Q2_0 scales a negative sign and compares the kernel with the scalar oracle. s2_expert_grouped_parity already drew signed scales. On an RTX 5090 with a Ryzen 9 9950X3D (AVX-512), both pass, and the whole ctest gives the same 106 of 107 as v0.1.42.

On that machine (IQ3_S, a French draft vocabulary of 46,587 tokens, served with --spec 4 --spec-min-p 0.5), I rebuilt the draft head from the same inputs with this packer. Only experts.bin changes. Against the current head, 8 interleaved pairs on fresh servers: draft acceptance 0.732 against 0.716, and output speed on a 22,785-token prompt +9.4% (8 of 8 pairs). Short prompts and a 99K-token cold read stayed within noise. That head was built before the commit that adds the previous candidates back to the search, which can only lower each block's error.

Python suite: tools/test_mtp_pack.py adds 5 tests. Everything else gives the same results as on v0.1.42, including 8 setup.py tests that fail in a plain container on both.

…n of d

The grid was 0.5 to 1.0 x max|w| in 17 steps, d > 0 only. It now spans 0.15 to 1.0
in 29 steps (a finer step than before) for both signs. A negative d mirrors the code
grid to {+1, 0, -1, -2} x |d|. On synthetic normal, Laplace and t3 blocks the relative
RMS error drops by 14 to 18 %. The kernels read d as a signed fp16, so the file format
is unchanged, and a block with max|w| = 0 keeps d = 0.
… the kernel against the scalar oracle

mtp_pack.py now stores negative scales, but the synthetic expert blobs drew positive
fp16 scales only, so no CPU expert test decoded d < 0. Half of the scales are negative
now, and the single-token kernel is compared with s2_expert_scalar, which decodes the
scales on its own, within expert_parity's 3e-3.
…cale to fp16 before measuring it

The candidates are the previous 17 positive steps of [0.5, 1.0] plus the wider grid in both signs. Each one is
rounded to fp16 before its error is measured, so no block ends with a larger error than the previous search gave it.
A block whose max|w| exceeds the fp16 range raises instead of storing an infinite scale.
…es with gguf_writer

The comparison with the previous search runs per block, on the three laws and on a block whose optimum is a previous
grid point. The decode is tools/gguf_writer.dequantize_q2_0, the scales are read in one view, the blob is decoded
once, a block beyond the fp16 range is checked, and a missing gguf-py skips the module with its reason.
@Niko1221

Copy link
Copy Markdown
Owner

Thank you. We packed the MTP head with the old and the new search and ran both with --spec 4 on the RTX 3060 (4 English prompts x 200 tokens, 5 interleaved rounds): acceptance 2355/3567 (0.660) with the old pack and 2325/3585 (0.648) with the new one, decode 50.9 vs 52.4 tok/s (noise). The pack also took 9:15 against 2:20. So we cannot show a gain on English prompts and setup would pay the time for everyone. If your gain is specific to the French draft vocabulary, an opt-in flag on mtp_pack with your numbers would be easy to take.

@gputier

gputier commented Oct 17, 2026

Copy link
Copy Markdown
Contributor Author

Thank you for measuring it. Our gain was 0.716 to 0.732 acceptance, with the French draft list on one RTX 5090, over a mixed set of prompts rather than a French-only one. That is too small to justify a pack four times slower, and I have no clean French A/B that would make a flag worth carrying. Closing this; we keep the rebuilt head on our side.

@gputier gputier closed this Oct 17, 2026
gputier added a commit to gputier/StrataGP that referenced this pull request Oct 17, 2026
gputier added a commit to gputier/StrataGP that referenced this pull request Oct 17, 2026
…précompilé, pertes de la 0.1.40 rangées sous « Ce qui n'a pas été repris »
@gputier
gputier deleted the pr/mtp-scale-0.1.42 branch October 17, 2026 12:51
mandoof1 added a commit to mandoof1/Strata that referenced this pull request Oct 18, 2026
…-1.0 x max|w| in both signs, fp16-rounded candidates; tools only)
mandoof1 added a commit to mandoof1/Strata that referenced this pull request Oct 18, 2026
…221#1415/Niko1221#1544, Niko1221#1934, STRATA_ALT_EXPERTS); conflicts: pool (one-phase keeps mode 7, POOL_FUSED moves to mode 8 and is ignored when POOL_ONEPHASE=1; per-job formats and the CPU_PARITY rule in every path), SPEC_CUM (the imdad fork's newer version from iq3b kept), dispatch (alt-experts beside cold-skip / defer-cold: probes, warms, deferrals and read_landed on each job's own source; prefetch_probed not with alt-experts), ALT_EXPERTS ignored when CPU_PARITY=1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants