Repository navigation
Description
Summary
rustingstrata bench completes a 131072-token prefill (and a 131072-token prompt at --ctx 262144), but a single prefill of 192k or 256k tokens panics inside the expert routing/cache path. The same prompt lengths work fine at smaller contexts, so the trigger is the length of one prefill, not the KV size.
Environment
- rustingstrata 1.2.1,
main@ 7264e57 (2026-11-10),cargo build --release - Arch Linux, kernel 7.2.11-arch1-1
- AMD Radeon RX 9060 XT 16 GB (gfx1200, RADV, Mesa 26.2.6-arch1.1)
- Ryzen 7 5700X, 62 GB RAM
- Model:
ISTA-DASLab/Qwen3.8-Flash-Next-GSQ-RCO-GGUF,IQ3_XXS(Qwen3.8-Flash-Next-GSQ-RCO-IQ3_XXS-00001-of-00002.gguf, 47.0 GB + 28.8 GB PLE shard; 176.94B params,qwen4exp) - Run with
--device 1(single GPU),--backend vulkan,--kv q8,--vram-margin 512
Reproduction
rustingstrata bench \
--model Qwen3.8-Flash-Next-GSQ-RCO-IQ3_XXS-00001-of-00002.gguf \
--gpu --backend vulkan --device 1 \
--pp 262144 --tg 64 --reps 1 --ctx 262144 --kv q8 --vram-margin 512
Observed
| ctx | prompt | result |
|---|---|---|
| 32768 | 32768 | prefill 259.4 t/s, decode 22.5 t/s |
| 65536 | 65536 | prefill 221.0 t/s, decode 21.9 t/s |
| 131072 | 131072 | prefill 169.3 t/s, decode 20.0 t/s |
| 262144 | 131072 | prefill 170.3 t/s, decode 18.2 t/s |
| 196608 | 196608 | panic |
| 262144 | 262144 | panic |
The model loads fine at 256k: plan: weights+state+scratch 8924 MB (KV 3265 MB for 262208 tokens, prefill 1432 MB), expert slots 6764 MB, resident experts 4062/24576.
Panics
- Baseline build, 262144-token prompt:
thread 'main' panicked at src/expert_cache.rs:202:24:
index out of bounds: the len is 24576 but the index is 18446744073263861996
(self.counts[il * self.n_expert + e as usize], e: i32 — the index is a negative id cast to usize.)
- With a local guard in
record()(usize::try_from(e), skip ife >= n_expert || il >= layers.len()), the same 262144-token prompt now fails later, at the consumer:
thread 'main' panicked at src/gpu_model/prefill.rs:375:41:
index out of bounds: the len is 513 but the index is 356189108
(the values are -1/garbage, not a valid 0..511 expert id; off[e as usize + 1]).
- 196608-token prompt at
--ctx 196608: sameprefill.rs:375, index18446744073592964713(a negative value).
--chunk 4096 does not change the outcome for the 262144-token prompt.
Where the ids come from
prefill.rs:370 reads them straight from the GPU scratch buffer:
let ids = g.get::<i32>(&pf.ints, 0, t * k)?;
The buffer is allocated as gpu.zeros::<i32>(3 * chunk * k) (prefill.rs:66), and prefill_with feeds the chunked path with tokens.chunks(chunk), so t <= chunk should hold. The fact that 131072 works but 196608 does not (with the same chunking) suggests something positional/size-dependent in the routing path rather than the chunk size, but I could not reduce it further.
Expected
Either complete the prefill, or fail with a clean anyhow error. A panic kills the server process, so serve with --ctx 262144 is unusable for any request that carries more than ~128k tokens of prompt.
Workaround
--ctx 131072, or keep single prefill batches <= 131072 tokens and rely on prompt caching for follow-up turns.
Happy to run any instrumented build or enable rustingstrata's diagnostic options; the failure is deterministic.
Activity
Vasyl-Trefilov commentedon Nov 11, 2026
So, I tried to Reproduce your error, but I can't I think this is AMD specific, so can you pull from main(I added more logs to understand what is the problem) and run it with
Thanks again!
ksergk commentedon Nov 11, 2026
More data on d7f739a, same machine (RX 9060 XT 16 GB, gfx1200, RADV Mesa 26.2.6, kernel 7.2.11).
All runs: same IQ3_XXS model,
--pp 196608 --ctx 196608 --kv q8 --vram-margin 512 --device 1.the NAN trace prints finite values at pos 131072, layers 0-2, then the GPU hangs:
Kernel:
STRATA_VK_NO_COOP=1(same command): no hang, but a clean error at pos 53248, layer 3:STRATA_VK_NO_COOP=1+STRATA_NAN_TRACE=40960: hangs at pos 40960 after layer 10, and nonon-finite value was printed before the hang (the probes change timing).
--chunk 1024(cooperative matrices on, trace from 131000): the full 196608-token prefill completes:The trace has 0 non-finite lines, including pos 131072, 176128 and 195584.
So this is not a hard position limit: 131072 is crossed fine with 1024-token chunks. The failure depends
on the interaction of chunk size and prompt length (chunk 4096 + more than ~131072 tokens), and the NAN
trace shows the numbers stay finite until the GPU hangs.
The kernel side is a ring timeout, so a dispatch that becomes too long/invalid with 4096-token chunks is
plausible. Is there a per-chunk buffer or index that scales with chunk (
3*chunk*k, or a state offset), ora dispatch whose size grows with chunk and can exceed a driver limit?
--chunk 1024is a working workaround for now, but it costs about 3x prefill throughput(52.6 vs 169 t/s at 128k).
Vasyl-Trefilov commentedon Nov 11, 2026
Okay, my one more try, the fix is on main, please pull it and rerun your chunk-4096 command with cooperative matrices on. If it still hangs, rerun with STRATA_VK_ATTN_BUDGET=16777216 and send the log. A run with STRATA_VK_PROF=1 --pp 100000 would also help.
Thank you so much for your time, since I have no AMD gpu, I can't reproduce bug and your help is really very helpful, thank you again
ksergk commentedon Nov 12, 2026
Pulled main again and rebuilt: HEAD = 9dd6340 ("Merge pull request #28 from yugt/sm61-clear-error", plus 6fd27b3 "eviction fix", 4f054a5 "vulkan support for DeepSeekV4.1 1017"). Same machine, RX 9060 XT 16 GB, gfx1200, RADV Mesa 26.2.6, kernel 7.2.11, IQ3_XXS.
STRATA_NAN_TRACE=131000,--pp 196608 --ctx 196608 --kv q8 --vram-margin 512 --device 1) - still hangs, identically to d7f739a:Note: the trace stops after layer 2 and the hang is in layer 3 at pos 131072, i.e. it is reproducible at a fixed place, not a random race.
FWIW the diff d7f739a..9dd6340 touches only Parked/PartCopy in gpu_model.rs (parking of a saved conversation state); prefill.rs and the shaders are unchanged, so this outcome was expected.
STRATA_VK_ATTN_BUDGETdoes not exist in 9dd6340 -grep -rover the whole tree finds nothing, and the env var is silently ignored. The VK vars that do exist are: STRATA_VK_NO_COOP, NO_COND, NO_TQ, DP_OLD, SMEM_LIMIT, STATS, PROF, F. Did that change stay in a branch, or under another name? I can rerun as soon as it is on main.STRATA_VK_PROF=1 --pp 100000 --ctx 196608 --kv q8(default chunk 4096; this length is below the failing point and completes):Caveat: the profiled total is ~33 s against ~558 s of prefill, because dispatches recorded inside compute graphs are not timestamped.
attn_prefill_256is nevertheless the longest single dispatch (~62 ms, grid[t/64, n_head], each workgroup loops over the whole KV), and its duration grows linearly withstep, so it is my prime suspect for the ring timeout at step > 131072 with t = 4096.--pp 196608 --ctx 196608 --kv q8, coopmat on):So 3072 is a much better workaround than 1024 (~2.5x faster prefill) and 196608 tokens load, prefill and decode correctly with it. What is special about chunk 4096 at >131072 tokens? Does any dispatch become invalid above some size (grid dimension, push-constant count, or a descriptor/buffer range that assumes at most 32 chunks)?
ksergk commentedon Nov 12, 2026
One more data point, and it narrows the cause considerably: the failure position does not depend on the quantization.
Two different quants, same command shape (
--ctx 262144 --kv q8 --chunk 3072 --vram-margin 512 --device 1,--pp 262144), RX 9060 XT 16 GB / gfx1200 / RADV Mesa 26.2.6:Same failing position (202752), different layers (31 vs 7), different sign of the garbage id. 66 chunks of 3072 were processed cleanly in both runs; the 67th is the first bad one. VRAM was never the issue in either run - both plans fit with margin 512 and the error is the non-finite hidden state, not an allocation failure.
So the wall is not quantization-specific and not layer-specific: it is a position/length-dependent path whose limit depends on the chunk size. For comparison, with the default chunk 4096 the same model dies much earlier, at pos 131072, and as a GPU ring timeout rather than a clean error:
Both walls look like an index/counter that overflows at a chunk-size-dependent point (131072 = 32 x 4096, 202752 = 66 x 3072), so whatever scales with
chunk(or with the number of chunks fed so far) is the thing to look at - a state offset, a chunk counter, or a buffer sized from chunk x something.I am not running further configs for now (each failed run costs ~25 minutes), but I can test
--chunk 1024 --ctx 262144or any build you want to try. For daily use I am staying at--ctx 196608 --chunk 3072(196608 tokens verified end to end), since 262144 does not complete yet with any chunk tried so far.vulkan: bound prefill attention work per submit (#25)
Vasyl-Trefilov commentedon Nov 12, 2026
Thanks again for this report again! Sorry for the runaround:
STRATA_VK_ATTN_BUDGETwas never merged — it lived in a local branch, which is whygrepfound nothing in 9dd6340. It is in main now as 8554f84.What changed:
t * (pos + t)passes a budget (STRATA_VK_ATTN_BUDGET, default 268435456 query-key pairs;0disables slicing). This applies to both the cooperative-matrix and no-coop paths.STRATA_VK_NO_COOP=1path: its online softmax started the accumulator at zero and rescaled it byexp(0 - first_score). For a strongly negative first key that is0 * inf= NaN — which matches the "router gave expert id ... hidden state is non-finite" you saw at pos 53248 withSTRATA_VK_NO_COOP=1. Fixed too.Could you pull main and rerun, cooperative matrices on:
--pp 196608 --ctx 196608 --chunk 4096(the run that hung at 131072)STRATA_VK_ATTN_BUDGET=16777216--pp 262144 --ctx 262144 --chunk 3072(the clean error at 202752)STRATA_VK_NO_COOP=1 --pp 196608 --chunk 4096to confirm the non-finite error at 53248 is goneThe case I'm least sure the budget fixes is (3): that one was cooperative matrices on and failed in a later layer, not in the first attention layer. If it persists, please add
STRATA_NAN_TRACE=200000for that run and send the last finite layer / first non-finite layer. And if (2) still hangs, it is not simple dispatch length — your profile showed ~62 ms per attention dispatch at 100k, far under the 10 s job timeout — so theSTRATA_VK_PROF=1 --pp 100000output plus the ring timeout lines again would help. Thanks!ksergk commentedon Nov 13, 2026
Pulled main, HEAD = a821cdd (contains 8425eb9 "vulkan: bound prefill attention work per submit", plus 9a4310f and a821cdd itself). Rebuilt, same machine (RX 9060 XT 16 GB, gfx1200, RADV Mesa 26.2.6, kernel 7.2.11). Coopmat results first, then the NO_COOP test.
--pp 196608 --ctx 196608 --chunk 4096 --kv q8(the run that hung at 131072): full pass.Skipped
STRATA_VK_ATTN_BUDGET=16777216(IQ3_XXS, same command as 1): the default (2^28) already fixed it, so no need. See point 4 for a BUDGET=0 A/B anyway.Q2_0,
--pp 262144 --ctx 262144 --chunk 3072 --kv q8(the clean error at 202752), withSTRATA_NAN_TRACE=200000: full pass.The trace ran to pos 261120, layer 47, all values finite. So the case you were least sure about is fixed too: 262144 prefill and decode end to end on Q2_0.
STRATA_VK_NO_COOP=1, IQ3_XXS,--pp 196608 --ctx 196608 --chunk 4096 --kv q8: still broken, and now in a different way. Three runs:a) before the fix (9dd6340), IQ3_XXS, same command, for reference: clean error at pos 53248, layer 3, "router gave expert id -1559426103 ... the hidden state is non-finite".
b) a821cdd, IQ3_XXS, default budget: GPU hang instead of an error.
It died early, within about a minute of starting the first chunks.
c) a821cdd, IQ3_XXS, same command with
STRATA_NAN_TRACE=1: the trace prints 483 lines and the last complete line is pos 45056 layer 2, so it hangs in layer 3 at pos 45056. Zero "non-finite" lines. Layer 3 is the first full-attention layer of this model (attention at 3, 7, 11, ... every 4th layer, DeltaNet in between), and layer 3 printed healthy finite values at pos 4096 through 40960, for example:d) a821cdd, IQ3_XXS, same command with
STRATA_VK_ATTN_BUDGET=0(slicing off): a clean error again, but elsewhere and at a different length.Summary for the tiled path: the specific "0 * inf" NaN at 53248 is gone (no non-finite value is printed now), but the path still fails around 45 to 53k, and the failure mode depends on the budget setting: hang in layer 3 with slicing on (default), out-of-range expert id at layer 43 with slicing off. Coopmat, which is the default on this GPU, is unaffected.
Practical note: on this RX 9060 XT the default budget is enough, 262144 tokens prefill at 80 t/s and decode at 12.5 t/s, so a full 256k context now works. RDNA4 users should keep cooperative matrices on (do not set
STRATA_VK_NO_COOP) until the tiled path is fixed.ksergk commentedon Nov 14, 2026
There's one remaining issue, but it's not from the original report: the STRATA_VK_NO_COOP=1 (tiled attention) path still breaks -it freezes in layer 3 at 45056 with tiling enabled, and there's an error with a garbage ID in layer 43 at 49152 with BUDGET=0. The original repro didn't use this flag, but in my map, coopmat is enabled by default and works. So this is a separate bug from a different path.