Skip to content

FP8 batched GEMM multiplies a STALE activation on mixed-quant models: the PMAT-084 cache key (ptr, count) aliases across layers — #3602's cosine 0.4153 #3727

Closed as not planned

Description

@noahgift

Root cause of #3602's cosine 0.4153 (localized in #3602 (comment)), 0.69.1 row under #3710.

cublas_prefill_fp8_gemm (crates/aprender-serve/src/cuda/executor/layers/cublas_prefill/gemm.rs) reuses its converted FP8 activation whenever (packed_input_ptr, m·k) equals the last conversion's key (PMAT-084). The key is cleared only when the scratch buffer is reallocated, never when the input's contents change. Any content change behind an unchanged (ptr, count) therefore multiplies a stale activation.

It fires on every mixed-quant model. qwen2.5-coder-0.5b's hidden size of 896 is not a multiple of 256, so Q/K/V/O/gate/up are Q5_0/Q8_0 and take non-FP8 routes, and only ffn_down (Q4_K/Q6_K) is FP8. PREFILL_DETAIL_TRACE=1 shows 23 hits, all ptr=0x71aec6600000 count=238336 (49 × 4864): layers 1–23 reuse layer 0's activation. It fails on lambda (batched prefill is the default at cc 89) and identically on gx10 with BATCHED_PREFILL=1.

done_when

  • A hit is only possible between GEMMs that share an input inside one phase (QKV, gate+up). Every non-FP8 route invalidates the key, and every phase that writes a fresh input opens a new scope, so the (ptr, count) aliasing class is closed, not just this instance.
  • A test drives a mixed-quant layer sequence (6 non-FP8 GEMMs, then an FP8 ffn_down on the same buffer, × N layers) and asserts 0 cross-layer hits. Today's code gives N−1. An all-FP8 sequence still gives 3 hits per layer (K, V, up). A mutant that removes the invalidation turns it RED.
  • qwen2.5-coder-0.5b Q4_K_M: GPU backend with no fallback, apr run correct, apr qa golden 3/3, on lambda (default path) AND on gx10 with BATCHED_PREFILL=1. PREFILL_DETAIL_TRACE shows 0 hits for it and 84 for qwen2.5-coder-7b.

Activity

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

    @noahgift
    MemberAuthor

    milestone → 0.73.0 per docs/roadmaps/milestone-triage-2026-09-23.md (#4024), operator approval 2026-09-23 (relayed by aprender-cf). Reason: performance/decode-prefill path: llama.cpp Parity (#3999)

  4. added
    P2Medium priority
    and removed
    P0Critical priority
    on Oct 14, 2026
  5. 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.73.0.

  6. 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.

  7. 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.

  8. noahgift commented on Oct 14, 2026

    @noahgift
    MemberAuthor

    Measured on main @ 3064c77 (the fix reached main through the v0.69.3 merge-back, #4338: fp8_activation_cache.rs, share_next / begin_dispatch). Built with --features cuda.

    Unit tests (done_when 2). a_mixed_quant_model_never_reuses_an_earlier_layers_activation, an_all_fp8_model_keeps_its_three_shared_input_hits_per_layer and the other 5 cache tests pass on an RTX 4090 (21/21 tests under the fp8_ filter).

    Models (done_when 3). apr run --gpu with PREFILL_DETAIL_TRACE=1, then apr run --format json and apr qa --json:

    device / env model FP8 GEMMs PMAT-084 hits backend.ran / fell_back qa golden
    RTX 4090 sm_89, default qwen2.5-coder-0.5b Q4_K_M 48 0 gpu / false 3/3
    RTX 4090 sm_89, default qwen2.5-coder-7b Q4_K_M 392 168 = 84 + 84 gpu / false 3/3
    GB10 sm_121, BATCHED_PREFILL=1 FP8_PREFILL=1 0.5b 48 0 gpu / false 3/3
    GB10 sm_121, BATCHED_PREFILL=1 FP8_PREFILL=1 7b 392 168 = 84 + 84 gpu / false 3/3

    Every done_when item now has a measurement. This comment does not close the issue; closing is the triage call.

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

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions