Skip to content

Qwen3.5 batched prefill has no f32 dequant for IQ2_XXS, IQ3_S, IQ3_XXS, Q2_K: apr run --gpu exits 14 on Qwen3.5-0.8B-UD-IQ2_XXS #4952

Closed

Description

@noahgift

Sub-ticket of #3953. apr run --gpu on Qwen3.5-0.8B-UD-IQ2_XXS.gguf exits 14 at main 9259972. It fails closed: generation falls back to the CPU, and --gpu refuses to call that a success.

Cause

  • The Qwen3.5 batched prefill dequantizes every projection weight to f32 (qwen35_dequant_f32, crates/aprender-serve/src/cuda/executor/gdn_prefill_ops.rs) before its GEMM.
  • It does this in every APR_QWEN35_PREFILL_GEMM mode. The f16 mode caches an f16 copy of each weight, but it builds that copy from the same f32 dequant.
  • APR_QWEN35_SESSION_PREFILL=per-token does not avoid it either, because the parity probe always runs the batched prefill.
  • qwen35_dequant_f32 has device kernels for Q4_K, Q5_K, Q6_K, Q8_0, F16 and IQ4_XS. Any other type returns InvalidParameter("no f32 dequant kernel").
  • The IQ2_S (ggml 22) has no CUDA GEMV — 0.69.1 release blocker #3953 branch adds IQ2_S, bit-exact on the device (see below).

This model holds five types with no prefill dequant. The decode GEMVs for all five are on main. #3953's "four types" counted the missing GEMVs; IQ3_S already had a GEMV but has no dequant.

type ggml id tensors in the model CPU oracle
IQ2_S 22 5 dequantize_iq2_s. Done on the #3953 branch
IQ2_XXS 16 96 dequantize_iq2_xxs
IQ3_S 21 5 dequantize_iq3_s
IQ3_XXS 18 24 dequantize_iq3_xxs
Q2_K 10 3 dequantize_q2_k

Rows

  • IQ2_XXS -> f32 dequant
  • IQ3_S -> f32 dequant
  • IQ3_XXS -> f32 dequant
  • Q2_K -> f32 dequant
  • apr run --gpu rc 0 on the model, with the parity probe passing, on sm_89 (RTX 4090)

Acceptance (each row)

The IQ2_S dequant on the #3953 branch passed each of these:

Decided by a planted quorum round (3 of 3 counted lanes, degraded: same-family): the IQ2_S dequant lands alone under #3953, and the other four go here, started at once, not deferred.

Owner: aprender-wprodmodels.

Activity

  1. added this to the 0.71.0 milestone on Oct 9, 2026
  2. noahgift commented on Oct 11, 2026

    @noahgift
    MemberAuthor

    Landed in #5131, merge commit 5f8f904 on main. The Qwen3.5 batched prefill now has f32 dequant kernels for IQ2_S, IQ2_XXS, IQ3_S, IQ3_XXS and Q2_K, so apr run --gpu on Qwen3.5-0.8B-UD-IQ2_XXS.gguf no longer exits 14.

    Receipts, all measured on the tree #5131 merged:

    • GB10 device tests (--features cuda): 893 passed, 0 failed, 0 SKIP lines. Every real tensor of each type in the model (sha256 a369165c…53e54) is bit-exact against the CPU oracle: IQ2_XXS 95, IQ3_XXS 24, IQ3_S 5, Q2_K 3, IQ2_S 5.
    • Planted faults: all 16 turned at least one test RED, and the restored tree is GREEN (868 passed).
    • sm_89 RTX 4060 Laptop: apr run --gpu … --trace exited 0 with Backend: GPU (CUDA, NVIDIA GeForce RTX 4060 Laptop GPU …) and batched prefill: 12 tokens in 13 ms (… attention cuBLAS f32).
    • sm_89 RTX 4090: release cuda apr, sha256 d50193db49f3fcad7c3cce62d4fc49fd652e1197b27da6e2e14101a20256672e. apr run --gpu … --trace exited 0 with Backend: GPU (CUDA, NVIDIA GeForce RTX 4090, 24035 MB VRAM), the F2 guard passed fresh, and batched prefill: 12 tokens in 4 ms (2722 tok/s …). Receipt: fix(cuda): Qwen3.5 batched prefill f32 dequants for IQ2_S, IQ2_XXS, IQ3_S, IQ3_XXS and Q2_K #5120 (comment)
    • CI on head deb92d6: 10 checks passed and 2 skipped. Two seat reviews approved, and the C314 signed.

    Follow-up: #5119, the Q2_K kernel gives NaN on a non-finite d/dmin where the CPU gives 0.

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

    P1High priorityowner:la-0.71Owned by the 0.71 look-ahead slotsize:MK̂ 3-4 h

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions