Skip to content

hrx: K-quant SwiGLU decode keeps separate gate and up codebooks (mixed-format pairs) - #60

Merged
bong-water-water-bong merged 2 commits into
1bit/hrx-vulkan-patchedfrom
1bit/hrx-mixgrid
Oct 2, 2026
Merged

bong-water-water-bong merged 2 commits into
1bit/hrx-vulkan-patchedfrom
1bit/hrx-mixgrid

Conversation

@bong-water-water-bong

Copy link
Copy Markdown

Unsloth's sub-4-bit UD files mix IQ1/IQ2/IQ3 types inside FFN gate/up pairs. Until now, a pair whose two formats need different codebooks was declined by the fused K-quant SwiGLU decode kernel, because the kernel staged only one codebook in workgroup memory. Those pairs fell back to the generic path, and that tracked the slow sub-3-bit decode on the leaderboard.

Mixed pairs per file and decode speed (FFN gate/up pairs needing two different codebooks, out of 64, from each file's tensor types; tg128 on dd74f6b):

File Mixed pairs tg128 (tok/s)
UD-Q4_K_XL 0 9.71
UD-IQ1_S 6 5.54
UD-IQ1_M 12 3.52
UD-IQ2_XXS 14 2.09
UD-IQ2_S 24 1.74
UD-Q2_K_XL 27 2.02
UD-IQ3_XXS 30 2.56

Change:

  • Both SwiGLU decode kernels (1 token and 2–8 tokens) allocate a 4 KiB codebook buffer each for gate and up, and fill each one for its own format. Same-format pairs fill both buffers.
  • The matcher no longer declines mixed pairs, and the kquant_grid helper is removed.

Measured on strixhalo (HRX0, balanced power mode, interleaved rounds):

dd74f6b this PR
Qwen3.8-27B UD-IQ2_S tg128 3.12 / 3.12 8.32 / 8.31
27B UD-Q4_K_XL tg128 (no mixed pairs) 11.88 / 11.88 11.81 / 11.87
ZAYA1-8B Q4_K_M tg128 93.0 / 93.2 92.4–95.4* / 92.5

* The first round's first sample was 37.6 (JIT warm-up).

  • Logits on UD-IQ2_S against the previous build: KLD 0.00013, same top token 99.1%. That run used 3 × 512 tokens with 8-token micro-batches, so decode goes through the K-quant kernels.
  • test-backend-ops -b HRX0: 996/996.

🤖 Generated with Claude Code

…d-format pairs no longer declined)

The SwiGLU decode kernels staged one codebook in workgroup memory, so a gate/up pair whose two formats need
different grids (IQ1/IQ2/IQ3 mixed within a layer, common in Unsloth's sub-4-bit UD files) was declined and
took the generic path. Gate and up now each get a 4 KiB grid buffer, filled for their own format, and the
decline rule and its kquant_grid helper are gone.

Qwen3.8-27B UD-IQ2_S (24 of 64 FFN pairs mixed), HRX0, balanced power mode, two interleaved rounds:
  tg128 3.12 -> 8.32 tok/s
  logits against the previous build (3 x 512, 8-token micro-batches): KLD 0.00013, same top 99.1%
Uniform files are unchanged: 27B UD-Q4_K_XL 11.88 -> 11.84, ZAYA1-8B Q4_K_M 93.1 -> 92.5 (warm samples).
test-backend-ops -b HRX0: 996/996.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the ggml label Oct 1, 2026

@bong-water-water-bong bong-water-water-bong left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (PR-Agent duty). Correct.

  • Gate and up now each read their own 4 KiB codebook (%grid / %grid_u), each filled only when its format needs one. That makes kquant_grid() and the mixed-pair decline in dispatch-kquant-decode.cpp unnecessary, and removing them is right.
  • The evidence covers it: UD-IQ2_S tg128 goes from 3.12 to 8.32 tok/s, with KLD 0.00013 against the previous pin. Uniform K-quant files are unchanged (27B 11.88 vs 11.84, ZAYA within noise), and test-backend-ops passes 996/996.

One measurement before merge: a uniform IQ file whose gate and up use the same grid (for example a pure IQ2_XXS or IQ3_XXS model, as in #51). Every SwiGLU workgroup now fills the same codebook twice. If that costs anything measurable there, fill %grid_u only when up_format's grid differs from gate_format's, and otherwise pass %grid for both (same idea as the old kquant_grid id, now just a select).

The 8 KiB of LDS in the two SwiGLU kernels is fine given the uniform-file numbers.

…iew)

A pair whose two formats use the same grid (same format, or IQ1_S with IQ1_M) no longer fills grid_u: the up
lanes read the gate grid. The double fill cost about 1% of decode on a pure IQ3_XXS Qwen3-4B (32.6 -> 32.2);
with this change it is within noise.

Qwen3-4B pure IQ3_XXS tg128, three interleaved rounds against dd74f6b: 32.99/32.07/32.09 vs 31.99/31.87/32.27.
Qwen3.8-27B UD-IQ2_S: 3.06/3.07/3.08 vs 8.38/8.30/8.34; logits against dd74f6b KLD 0.00013.
test-backend-ops -b HRX0: 996/996.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bong-water-water-bong

Copy link
Copy Markdown
Author

Pure-format check (review): filling the same codebook twice cost about 1% on a pure IQ3_XXS Qwen3-4B (tg128 32.6 → 32.2). The fix is pushed: when gate and up share a grid (same format, or IQ1_S with IQ1_M), grid_u isn't filled and the up lanes read the gate grid.

Re-measured after the change, HRX0, balanced power mode, three interleaved rounds:

dd74f6b this PR
Qwen3-4B pure IQ3_XXS tg128 32.99 / 32.07 / 32.09 31.99 / 31.87 / 32.27
Qwen3.8-27B UD-IQ2_S tg128 3.06 / 3.07 / 3.08 8.38 / 8.30 / 8.34

The first round of each build includes warm-up. Rounds 2 and 3 average 32.08 vs 32.07, so the cost is gone.

  • UD-IQ2_S logits against dd74f6b: KLD 0.00013, same top token 99.1%.
  • test-backend-ops -b HRX0: 996/996.

🤖 Generated with Claude Code

@bong-water-water-bong
bong-water-water-bong merged commit bd5b297 into 1bit/hrx-vulkan-patched Oct 2, 2026
10 of 24 checks passed
bong-water-water-bong added a commit that referenced this pull request Nov 6, 2026
…ngine ggml-org#1259)

gpu-kernels PR #60 fixes hrx_hc_post_comb: it indexed comb as dst*hc + src while ggml stores it as dst + hc*src, so identity=0 multiplied the residual by the transposed comb. With that kernel built, all six DSV4_HC_POST cases pass (identity=0 ERR 0.078-0.217 -> OK). Remove the named waiver; the TOPK_MOE view waiver remains. This must ride the gpu-kernels pin bump.

Assisted-by: DeepSeek Harness
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