Skip to content

Experiment: interleaved q8_1 activations for the 2-4 token MMVQ (MTP verify) #39

Closed

Description

@Piggidragon

Idea from Strata by @Niko1221 (MIT), originally fork F4 by Eddoursul: STRATA_MMVQ_IL, the interleaved small-batch matvec (MMVQ_IL_TABLE.md).

  • The decode and verify windows run their dense projections for 2 to 4 tokens through a kernel that reads an interleaved copy of the q8_1 activations: one load reads the same int of every column.
  • A warp takes 1, 2 or 4 matrix rows, from a table per quant type, token count and row-count class.
  • It is bitwise equal to the plain kernels. A table cell is enabled only where the worse of an RTX 3060 and an RTX 5070 gains at least 3%. A related multi-column variant (STRATA_B6_MMVQ_ROWS) measured +0.2-2%.

Why it matters here

Experiment

  1. Prototype in ggml-cuda/mmvq.cu: a quantize_q8_1 variant that also writes the interleaved layout for 2-4 columns, and an MMVQ path that reads it for Q4_K, Q5_K, Q6_K (the types of the production model).
  2. Bit-exact check against the current kernel with test-backend-ops.
  3. Perf: test-backend-ops perf -o MUL_MAT for the production shapes (ncols 2-4), then decode t/s with MTP depth 2 and 3, -sm tensor on 4070 + 3060.

Done when

The verify matmuls are measurably faster (Strata's bar: >= 3% per enabled cell), decode t/s improves within interleaved pairs, and the output is bit-identical.

Activity

  1. Piggidragon commented on Oct 19, 2026

    @Piggidragon
    OwnerAuthor

    First measurements (2026-10-19)

    Where the time goes. nsys, production config (Qwen3.8 27B UD-Q4_K_S, 4070 + 3060 -sm tensor, MTP depth 2, draft vocab list):

    • The verify matmuls (MMVQ, 3 columns) take ~20.5 ms per step on the 4070 and ~21.2 ms on the 3060, of a ~37 ms step.
    • By type: IQ4_XS 8.6 ms, Q4_K 4.0, Q5_K 3.3, Q6_K 2.0 (1.4 of it the output head), Q3_K/IQ3_S ~1.8.
    • With 13.45 GiB of matmul weights split 0.625/0.375 (attention 1:3) that is about 84% of the 4070's bandwidth and 76% of the 3060's.

    Kernel-level comparison. test-backend-ops perf on the 3060 (3 MB L2; the 4070's 36 MB L2 holds these matrices, so its numbers are not usable), 3 columns, the real per-device shapes. The values are time per op against current main's MMVQ; negative is faster.

    1. Interleaved q8_1 activations within our MMVQ block structure. One vector load reads the same int of all columns, and the weight block is decoded once. This is Strata's q8_1_il layout; for IQ4_XS it has to be position-major, because block-major was 70% slower from bad coalescing.

      • Result for IQ4_XS: within ±2% on all shapes.
      • Our 3-column kernel already costs only 3-14% more than the 1-column kernel, so the activation loads are not what limits it.
    2. One warp per R rows with 4 "virtual warps" (Strata's native_mmvq_il_kernel structure). The values are bitwise equal to mul_mat_vec_q. It helps where the K loop does not fill the block (k = 1536 / 2304: 6-9 Q4_K blocks for a block that takes 16 per iteration):

      shape (m x k) IQ4_XS Q4_K Q5_K Q6_K
      5120 x 1536 (attn_output, 4070) -20% -13% -11% -9%
      5120 x 2304 (ssm_out, 3060) -12% -9% -8% -3%
      11008 / 6400 x 5120 (ffn up/gate) -3% 0% +1% +7..16%
      5120 x 11008 / 6400 (ffn_down) +3% +3..5% +3..8% +8..20%

      With R = 1 it is 15-60% slower everywhere; the table uses the better of R = 2 and R = 4.

    Conclusion.

    • Strata's gains are measured against its own plain kernels and do not carry over to ours, except the warp-per-rows layout for small k.
    • Taking it only for k <= ~2304 at 2-4 columns would save about 0.2 ms per step (~0.5% decode). It is a possible small follow-up, not pursued now.
    • The prototype is on local branch llama/strata-exp (env GGML_CUDA_MMVQ_VW, GGML_CUDA_MMVQ_IL, experiment only).
  2. Piggidragon commented on Oct 20, 2026

    @Piggidragon
    OwnerAuthor

    Closed: interleaved q8_1 activations gave nothing in our MMVQ (±2%). Warp-per-rows with virtual warps (bitwise equal) is faster only for k <= 2304 (-8..-20% per op), ~0.5% of decode. Not worth the complexity. The prototype (env GGML_CUDA_MMVQ_IL / GGML_CUDA_MMVQ_VW, plus TBO_PROD_SHAPES perf cases) is kept as a WIP commit on the local branch llama/strata-exp.

    🤖 Generated with Claude Code

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions