Use Q8_K_128 for IQ1_S_R4 and IQ1_M_R4 matrix multiplications#194
Conversation
Done. [1]3.7099,[2]4.6162,[3]3.5438,[4]3.4199,[5]3.5375,[6]3.5710,[7]3.5428,[8]3.6748,[9]3.7417,[10]3.6724,[11]3.7879,[12]3.9602,[13]4.0477,[14]4.1439,[15]4.2809,[16]4.1981,[17]4.3853,[18]4.5141,[19]4.4493,[20]4.3848,[21]4.4664,[22]4.3290,[23]4.1912,[24]4.1799,[25]4.0693,[26]4.0135,[27]4.0672,[28]4.0459,[29]4.1110,[30]4.1116,[31]4.1261,[32]4.1192,[33]4.1756,[34]4.2340,[35]4.3112,[36]4.3722,[37]4.3822,[38]4.4260,[39]4.4568,[40]4.5164,[41]4.5661,[42]4.5563,[43]4.5975,[44]4.5821,[45]4.6738,[46]4.7199,[47]4.7029,[48]4.6934,[49]4.6900,[50]4.7087,[51]4.7637,[52]4.7736,[53]4.8515,[54]4.8776,[55]4.9119,[56]4.9504,[57]4.9769,[58]5.0124,[59]5.0024,[60]5.0545,[61]5.1015,[62]5.1639,[63]5.2095,[64]5.2599, No more |
|
Thank you for this! The decisive hint to solve it was the discussion about DeepSeek-R1 being dumb with |
…staged, parallel folds) — byte-identical, 7.1 t/s v2 removes v1's serial-fold bottleneck (each lane folds its own row in parallel) and stages weights through SMEM for coalesced global reads, but is SLOWER (7.1 vs MMQ 27.1): lane-strided 18-byte SMEM block reads cause heavy bank conflicts, the per-row cooperative load is partly serial, and 18KB/block SMEM caps occupancy. Gate now also requires ne00%256==0 (the tiled load needs nb%8==0). Three byte-identical designs measured, all < MMQ (v0 9.4 / v1 16.7 / v2 7.1 vs 27.1). Strong evidence the byte-identity constraint (MMQ's exact serial reduction order) forbids the lean warp-reduce that gave stock mmvq its +27% (ikawrakow#194). Decode-GEMV A-vs-B fork re-opens with data. Byte-identity itself remains PROVEN+correct (test ALL OK). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…8) — +27.3% tg128 User chose path B (np-invariance reframe): route small-batch decode quantized matmuls to the self-batch-invariant MMVQ GEMV instead of force-dispatching MMQ. MMVQ computes each output column as an INDEPENDENT GEMV reduction (mmvq-templates.cuh:98-116, tmp[j][i]), so it is byte-identical ACROSS ncols => np1==npK holds for the whole decode range ne11<=MMVQ_MAX_BATCH_SIZE (=8); the MMVQ/MMQ crossover sits at 8, above the NPC np range, so no slot crosses the boundary mid-decode. Mirrors the original NPC.4 fix (which forced MMQ to avoid an in-range crossover) but forces MMVQ instead — faster. Measured tg128 34.45 vs MMQ 27.07 = +27.3% (matches ikawrakow#194's +27.4%). Output differs from the prior MMQ path by ~ULP (different reduction order) => default-OFF behind GGML_CUDA_DECODE_MMVQ (+ extern C ggml_cuda_decode_mmvq_set_enabled for the NPC harness) until the one-time NPC re-baseline lands and deploy is approved. Byte-identical-to-MMQ GEMV (path A, ec00bb6..) retained as the np-safe zero-re-baseline fallback. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@saood06 is still observing NaNs for DeepSeek-R1 quantized with
IQ1_S_R4. As I don't see what else could be wrong, I'm making the following hypothesis:fp16is used for some of the attention tensors, I hypothesize that there are activations that go beyond the range offp16floats, which get truncated when converted fromfp32forfp16for multiplications with somefp16model tensor.Q8_1as quantization type for activations, asIQ1_S_R4does, can be futile:f16range. This is likely to be the case asQ8_0attention tensors are reported to behave better thanfp16.Q8_1we also computefp16. If one gets unlucky, it can overflow, despiteIQ1_S_R4dot product with this block. To make the calculation more efficient onAVX2, we use ternary quants_mm256_maddubs_epi16) , and then recover the correct result by subtractingfp16range), this does not work and we get a wrong result.To test this hypothesis, this draft PR uses$d$ , hence we cannot run into 16-bit float range issues. Perplexity for DeepSeek-Lite is slightly lower compared to using
Q8_K_128forIQ1_S_R4andIQ1_M_R4matrix multiplications.Q8_K_128is a new 8-bit quantization type similar toQ8_Kbut with blocks of 128 (so I can test with DeepSeek-Lite). It is draft because I haven't done theARM_NEONimplementation.Q8_K_128uses a 32-bit float scale, and the sums over blocks of 32 are stored asint16_twithout multiplying withQ8_1, which indicates that there may be non-fatal truncation effects also there (normally one expects a slightly higher accuracy from usingQ8_0orQ8_1because of the smaller block size).Would appreciate if this gets tested with DeepSeek-R1.