You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[ROCm/gfx1201] PFlash scorer: FP stage ~45x slower than the CUDA reference (343s for S=120k vs 7.68s on a 3090), so PFlash is net-negative at long context #752
On a R9700 (gfx1201, RDNA4) with the official ghcr.io/luce-org/lucebox-hub:rocm image, PFlash's scorer forward spends 98% of its time in the FP stage, and that stage runs ~45× slower than the CUDA reference for a shorter sequence:
Compare with the CUDA log in #147 for the same stage at a longer sequence:
[qwen3-0.6b-fp] forward 7.68s (S=130197, ...)
S=119925 → 343.3 s here, S=130197 → 7.68 s there. Both are the 0.6B scorer; A_compute (2.16 s) and B_compute (3.49 s) are entirely reasonable, so it is specifically FP that is pathological.
Effect on end-to-end prefill
The compression cost is not included in the reported prefill_ms, so the engine number looks excellent while the wall clock does not:
prompt tokens
wall
engine prefill_ms
compression (wall − prefill)
40,553
55.4 s
8.8 s (4,618.7 tok/s)
46.6 s
119,926
448.8 s
100.7 s (1,190.8 tok/s)
348.1 s
Compression cost vs S: 20k → 15.5 s, 40k → 46 s, 120k → 348 s — close to O(S²), i.e. the scorer is behaving like dense attention over the whole sequence rather than a sparse/reduced path.
Resulting end-to-end gain at 120k is 1.38–1.51×, not the ~10× the engine figure implies. Same prompt, same box:
configuration
wall
NIAH retrieval
PFlash off (q4_0 KV, reference)
618.3 s
YES
PFlash always
409.2–448.8 s
YES
plain llama.cpp Vulkan (same box, same class of weights)
~235 s TTFT
YES
So on this card PFlash is a net loss against the alternative at the top of the context range, even though retrieval quality survives.
Things I checked before filing
LUCE_FP_USE_BSA=1 LUCE_FP_ALPHA=0.85 (per PFlash NIAH benchmark on RTX 5090 #82) makes no difference on gfx1201. Startup confirms fp_use_bsa = ON and there is no fallback warning. 40k: 55.4 s vs 54.5 s without it. 120k: 448.8 s vs 445.5 s.
Not thermals: junction 54 °C, mclk locked at 1258 MHz, 175 W, no throttling during the run.
Not the drafter GGUF: tried two (unsloth/Qwen3-0.6B-BF16.gguf and a converted variant), same behaviour. Each request logs [compress] loading drafter — worth a separate look, but the 343 s is measured inside the forward, not the load.
Not n-max / block size: --draft-block-size 16 and 8 behave the same for the compression stage.
Not the KV type: q8_0 and q4_0 give identical prefill at 40.5k (452.5 vs 452.2).
Hypothesis
The FP stage (flash-prefill / block-sparse scorer) has no working RDNA4 implementation in the published ROCm build, so it is silently running a fallback. Supporting evidence:
PFlash NIAH benchmark on RTX 5090 #82: on CUDA the scorer needs DFLASH_FP_USE_BSA=1 set explicitly; without it the path is 3.4× slower and NIAH fails at 32k. Here, setting it changes nothing — consistent with the flag having nothing to switch to.
server/docs/HIP_PERF_PLAN.md describes RDNA effort concentrated on mul_mat_q paths.
Is the FP/flash-prefill stage expected to be usable on gfx1201/ROCm 7.2.4 today? If not, would you consider refusing or loudly warning when --prefill-compression is enabled on an arch where the fast path is missing, rather than silently spending 45× longer? Right now the only symptom is a wall-clock that contradicts the reported prefill_ms.
If it is expected to work, is there a build flag / env var we are missing beyond DFLASH_FP_USE_BSA / DFLASH_FP_ALPHA? I'm happy to rebuild any branch and rerun on this box.
Worth documenting the "compression time is not in prefill_ms" caveat next to the PFlash throughput claims — independently of the arch issue, it makes the headline number hard to compare with any other engine's end-to-end prefill.
then POST a ~120k-token prompt to /v1/chat/completions and read the [qwen3-0.6b-fp] forward line from docker logs. Per-request figures come from the response's own prefill_ms / decode_tokens_per_sec fields, compared against wall clock measured around the HTTP call.
Summary
On a R9700 (gfx1201, RDNA4) with the official
ghcr.io/luce-org/lucebox-hub:rocmimage, PFlash's scorer forward spends 98% of its time in theFPstage, and that stage runs ~45× slower than the CUDA reference for a shorter sequence:Compare with the CUDA log in #147 for the same stage at a longer sequence:
S=119925→ 343.3 s here,S=130197→ 7.68 s there. Both are the 0.6B scorer;A_compute(2.16 s) andB_compute(3.49 s) are entirely reasonable, so it is specificallyFPthat is pathological.Effect on end-to-end prefill
The compression cost is not included in the reported
prefill_ms, so the engine number looks excellent while the wall clock does not:prefill_msCompression cost vs
S: 20k → 15.5 s, 40k → 46 s, 120k → 348 s — close to O(S²), i.e. the scorer is behaving like dense attention over the whole sequence rather than a sparse/reduced path.Resulting end-to-end gain at 120k is 1.38–1.51×, not the ~10× the engine figure implies. Same prompt, same box:
off(q4_0 KV, reference)alwaysSo on this card PFlash is a net loss against the alternative at the top of the context range, even though retrieval quality survives.
Things I checked before filing
LUCE_FP_USE_BSA=1 LUCE_FP_ALPHA=0.85(per PFlash NIAH benchmark on RTX 5090 #82) makes no difference on gfx1201. Startup confirmsfp_use_bsa = ONand there is no fallback warning. 40k: 55.4 s vs 54.5 s without it. 120k: 448.8 s vs 445.5 s.mclklocked at 1258 MHz, 175 W, no throttling during the run.--max-ctx(Oversized--max-ctxsilently destroys attention throughput (20× prefill slowdown at 32K, 8× at 64K) #10): 131072 vs a tight 81920 at 76k differs by 1.2%.unsloth/Qwen3-0.6B-BF16.ggufand a converted variant), same behaviour. Each request logs[compress] loading drafter— worth a separate look, but the 343 s is measured inside the forward, not the load.--draft-block-size 16and 8 behave the same for the compression stage.q8_0andq4_0give identical prefill at 40.5k (452.5 vs 452.2).Hypothesis
The
FPstage (flash-prefill / block-sparse scorer) has no working RDNA4 implementation in the published ROCm build, so it is silently running a fallback. Supporting evidence:DFLASH27B_HAVE_SM80_FLASHPREFILLout asymmetrically, so flash-prefill kernels were compiled out entirely on HIP.DFLASH_FP_USE_BSA=1set explicitly; without it the path is 3.4× slower and NIAH fails at 32k. Here, setting it changes nothing — consistent with the flag having nothing to switch to.server/docs/HIP_PERF_PLAN.mddescribes RDNA effort concentrated onmul_mat_qpaths.#456only fixes the compile on ROCm ≥ 7.2.What I'm asking for
FP/flash-prefill stage expected to be usable on gfx1201/ROCm 7.2.4 today? If not, would you consider refusing or loudly warning when--prefill-compressionis enabled on an arch where the fast path is missing, rather than silently spending 45× longer? Right now the only symptom is a wall-clock that contradicts the reportedprefill_ms.DFLASH_FP_USE_BSA/DFLASH_FP_ALPHA? I'm happy to rebuild any branch and rerun on this box.prefill_ms" caveat next to the PFlash throughput claims — independently of the arch issue, it makes the headline number hard to compare with any other engine's end-to-end prefill.Reproduction
Image
ghcr.io/luce-org/lucebox-hub:rocm(built 2026-09-21, commit2785c22), R9700 32 GB, ROCm 7.2.4:then POST a ~120k-token prompt to
/v1/chat/completionsand read the[qwen3-0.6b-fp] forwardline fromdocker logs. Per-request figures come from the response's ownprefill_ms/decode_tokens_per_secfields, compared against wall clock measured around the HTTP call.