Skip to content

CUDA Q5_K gemv/gemm read a non-ggml block layout (qh bit order; gemm also qh/qs offsets and scale unpacking) #3111

Open

Description

@noahgift

Found while fixing the CPU readers in #3110 (PMAT-1101). I read the CUDA Q5_K kernels in crates/aprender-gpu/src/kernels/quantize/q5k/ against ggml's block_q5_K (d, dmin, scales[12], qh[32] at offset 16, qs[128] at offset 48; value l of sub-block s takes its fifth bit from bit s of qh[l]; sub-blocks 2c/2c+1 share qs[32c..32c+32], low nibbles then high). Neither kernel matches.

gemv.rs (Q5KGemvKernel, the M=1 decode path; WeightQuantType::Q5K => GemvKernel::Q5K)

  • qs offset and nibble selection match ggml.
  • The fifth bit is read from qh[val_idx / 8] >> (val_idx % 8), a sequential bitmask. ggml puts it at qh[val_idx % 32] >> (val_idx / 32), so it differs for most values.

gemm.rs (Q5KKernel)

  • Assumes qs sits at 16..144 and qh at 144..176. ggml has qh at 16..48 and qs at 48..176.
  • Takes sub-block s's qs bytes from 16 + s*16 + lane/2, and the bit from (s*32 + lane) as a sequential bitmask.
  • Unpacks the scales as a 12-bit stride (bit_offset = s*12) and normalises by 1/63. That is not ggml's get_scale_min_k4.

Not measured yet. This comes from reading the code. The plan is to reuse the gguf-py golden super-block from FALSIFY-QDOT-009 (#3110) as a GPU-side test: gemv against the gguf-py dot, and gemm against the reference matmul. It will run on lambda (sm_89) and gx10 (sm_121), then the kernels get fixed.

Impact, if confirmed: --gpu on any model with Q5_K tensors (every Q5_K_M/Q5_K_S file, plus the Q5_K tensors inside Q4_K_M files) computes wrong projections on CUDA, and the CUDA release assets ship that path.

Activity

  1. added this to the 0.67.0 milestone on Sep 11, 2026
  2. added
    bugSomething isn't working
    P0Critical priority
    on Sep 11, 2026
  3. noahgift commented on Sep 11, 2026

    @noahgift
    MemberAuthor

    Measured on an RTX 4090 (lambda), 2026-09-11. This is no longer just a reading of the code. The GEMV was run on the FALSIFY-QDOT-009 golden super-block from #3110, which is real bytes from a llama.cpp-quantized GGUF:

    • Shipped indexing: the ramp dot comes out 2.659; gguf-py gives 0.622.
    • Fixed indexing: both new GPU tests pass (FALSIFY-QDOT-010, 2/2, no skips): a one-hot activation returns each of the 256 gguf-py values, and a ramp reproduces gguf-py's dot.

    GEMV fix → #3113 (PMAT-1104). It is stacked on #3110 and has auto-merge on.

    Q5KKernel (the GEMM) still has its own wrong layout: qh/qs offsets and the scale unpack. Inference never dispatches it; only q5k_matvec in the layer-trace path and tests call it. This issue stays open for it.

  4. noahgift commented on Sep 12, 2026

    @noahgift
    MemberAuthor

    Train #3127 landed (squash cb829fc, 2026-09-12T09:12Z) with #3110 (CPU + apr import Q5_K readers, oracle = gguf-py on a real block) and #3113 (CUDA Q5_K GEMV: the fifth bit read from a sequential bitmask). This issue also names the GEMM's qh/qs offsets — not claimed by either row, so it stays open until a GEMM-path receipt against the same oracle exists. Milestone follows the freeze.

  5. modified the milestones: 0.67.0, 0.68.0 on Sep 12, 2026
  6. noahgift commented on Sep 12, 2026

    @noahgift
    MemberAuthor

    slipped_from: 0.67.0 — §4.1 freeze (06x-release-schedule), 2026-09-12: the train landed #3110 + #3113 (CPU, apr import, CUDA GEMV); the GEMM qh/qs half has no receipt against the gguf-py oracle yet.

  7. modified the milestones: 0.68.0, 0.69.0, 0.72.0 on Sep 16, 2026
  8. noahgift commented on Sep 25, 2026

    @noahgift
    MemberAuthor

    Parked by APR-EPIC-001: over E3 budget (rank 10/79). Reopen = pull. Applied by aprender-d1 under a 3-lane quorum receipt (handoff/balance-quorum-rev4.json).

  9. 11 remaining items

  10. noahgift commented on Oct 12, 2026

    @noahgift
    MemberAuthor

    GEMM half re-cut on current main: branch fix/3111-q5k-gemm-r2 @ 2695cd0. This is a cherry-pick of 232c198 onto main 6bd89b0. It applied cleanly: main has not touched any of the 5 files since the old base. No PR is open; the branch waits for a slot.

    Re-measured on an RTX 4090 (sm_89) at 2695cd0:

    • cargo test -p aprender-gpu --features cuda --lib q5k_: 35/35 pass, including q5k_gemm_matches_the_cpu_matmul and q5k_dequant_matches_the_cpu_reader.
    • cargo test -p aprender-serve --features cuda --lib q5k_matvec: 2/2 pass, including test_3111_q5k_matvec_matches_cpu_dequant.
    • Mutant (gemm.rs:147, qh offset 16→144): q5k_gemm_matches_the_cpu_matmul FAILS with gpu 1259.49 vs cpu 1052.54, the same numbers as the 09-26 receipt. The file was restored afterwards.
    • cargo fmt --all -- --check: clean.

    The GEMV half landed in #3113. Once this branch merges, both halves named in this issue have a receipt against the oracle.

  11. added
    P2Medium priority
    and removed
    P0Critical priority
    on Oct 14, 2026
  12. noahgift commented on Oct 14, 2026

    @noahgift
    MemberAuthor

    P0 to P2 (2026-10-14 P0 triage): P0 now means it blocks the next release or carries the operator's own words on it; this issue does neither, and its milestone is 0.72.0.

  13. noahgift commented on Oct 14, 2026

    @noahgift
    MemberAuthor

    merged into #5312 (master ticket for epic #3994; triage rule 7b, 2026-10-14). It is a checklist row there; reopen this issue when work on it starts or its PR opens.

  14. noahgift commented on Oct 14, 2026

    @noahgift
    MemberAuthor

    Moved: this sub-ticket is now a row in #5323 (CUDA quantized kernels: correct block layouts, cache keys and precision), split out of #5312 by theme.

  15. modified the milestones: 0.72.0, backlog on Oct 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium prioritybugSomething isn't workingowner:la-0.71Owned by the 0.71 look-ahead slotsize:MK̂ 3-4 h

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions