Repository navigation
Conversation
attn_chunk_kernel<1> saturates the SM's shared-memory pipe on Turing: its
time grew linearly with the queries while the SMs were half empty (two
16-byte q reads per head per cell with a two-way bank conflict, and 12
warp_sums = 60 shuffles per cell).
attn_chunk_q8_v3_kernel computes the same operations in the same order:
- the lane's slice of the 12 query heads is read into registers once;
- the 12 lane sums are reduced with reduce12_gfx906 (16 shuffles, every
sum warp_sum's pairs);
- the probabilities are stored cell-major, so the value loop reads a
cell's 12 as three 16-byte broadcasts.
RTX 2080 Ti, with the merge: 2051 selected cells, 1-4 queries
51.6/78.5/110/146 -> 34.5/41.0/73.0/84.9 us; 600 cells
45.9/74.6/105/137 -> 28.6/32.8/33.5/33.3 us. qsa_prompt_attn_parity
reports the same errors with STRATA_ATTN_V3=0 and 1.
Default on sm_75 only; STRATA_ATTN_V3=0 keeps the default kernel, =1 takes
this one on any CUDA card.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Same-day verification of this PR (merged onto v0.1.43.1 = Correctness gates: ctest 7/7 passed; A/B, same prompts, temperature 0, both binaries built from source the same hour (
Prefill and TTFT sitting exactly on the noise floor matches the PRs' scope (decode-window kernels only) and says the A/B is clean. Decode medians move in the predicted direction, but the single-run spread on this rig (one noisy chat run swung -13 %) keeps this an indicator, not proof. Not tested: |
attn_chunk_kernel<1> saturates the SM's shared-memory pipe on Turing: its
time grew linearly with the queries while the SMs were half empty (two
16-byte q reads per head per cell with a two-way bank conflict, and 12
warp_sums = 60 shuffles per cell).
attn_chunk_q8_v3_kernel computes the same operations in the same order:
- the lane's slice of the 12 query heads is read into registers once;
- the 12 lane sums are reduced with reduce12_gfx906 (16 shuffles, every
sum warp_sum's pairs);
- the probabilities are stored cell-major, so the value loop reads a
cell's 12 as three 16-byte broadcasts.
RTX 2080 Ti, with the merge: 2051 selected cells, 1-4 queries
51.6/78.5/110/146 -> 34.5/41.0/73.0/84.9 us; 600 cells
45.9/74.6/105/137 -> 28.6/32.8/33.5/33.3 us. qsa_prompt_attn_parity
reports the same errors with STRATA_ATTN_V3=0 and 1.
Default on sm_75 only; STRATA_ATTN_V3=0 keeps the default kernel, =1 takes
this one on any CUDA card.
#2222) are opt-in with STRATA_SM75_PERF=1 No sm_75 card is available here to confirm the series, so the kernels that were on by default for compute capability 7.5 in the submitted PRs now follow one switch, include/strata/core/sm75_series.hpp. Each keeps its own variable, which wins in both directions. The one-read prompt top-k (#2093) was on for every CUDA card as submitted; it is now Turing only like the rest. STRATA_EMULATE_CC=75 counts as a Turing card, so a 75-virtual build on an sm_86 GPU runs the series for tests.
|
Thanks rafatxf, good work. We ported this with your authorship kept. We have no Turing card, so we could not confirm the speed. What we did check: the default path is byte-identical to before (identity gate on RTX 3060, P100 and A4000), and with the new path forced on, including a build that runs the real sm_75 device code on an sm_86 card, the gate is identical too. Because we cannot measure it on sm_75 it ships as opt-in (STRATA_SM75_PERF=1, plus your own variable STRATA_ATTN_V3), documented in docs/DETAILS.md. If a Turing owner confirms the gain we will consider turning it on by default. |
|
Ported in 0.1.45, thanks! Turing numbers for |
The decode attention over the QSA selection (
attn_chunk_kernel<1>, INT8 pools) saturates the SM's shared-memory pipe on Turing. Its time grew linearly with the queries while the SMs were half empty: per cell, every warp reads two 16-byte slices of each of the 12 query heads from shared memory (a two-way bank conflict atlane * 8) and runs 12warp_sums, 60 shuffles; the value loop then reads the 12 probabilities of a cell as 12 scalar loads. Loading the K/V codes earlier (software prefetch) changed nothing, so it is not memory latency.attn_chunk_q8_v3_kerneldoes the same operations in the same order:reduce12_gfx906(16 shuffles; every sum iswarp_sum's pairs, as its comment says);The chunk partials and the merged output are bit for bit the default kernel's. It is used by both entry points (
qsa_decode_attn_batch,qsa_decode_attn_step), so the MTP drafter's attention gets it too. Default on sm_75 only;STRATA_ATTN_V3=0keeps the default kernel,=1takes this one on any CUDA card. Lane-cell scoring (STRATA_ATTN_LANECELL=1) keeps its path.Setup
RTX 2080 Ti 22 GB (sm_75), i7-6700, CUDA 13.0, SM 1650 MHz, 240 W. Flash-Next, canonical Q2_0 pack,
--kv int8,--max-context 524288,--serve.Kernel (chunk kernel + merge, synthetic INT8 pools, permuted page table, 200 calls)
Partials and outputs compared with
memcmpagainst the default kernel in every case: identical. With the swizzle andreduce12alone (the gfx906 variants, also bitwise on CUDA) the 2,051-cell / 3-query case is 78 µs; the register copy of the query is what takes it to 73 µs, and further at fewer cells. At 2,051 cells and 3-4 queries the registers allow two blocks per SM (198-264 blocks: two waves); forcing three spills.qsa_prompt_attn_parityreports the same errors withSTRATA_ATTN_V3=0and1(its reference is this decode kernel: int8 32K / 2,048 queries 71.5 → 36.0 ms per chunk).Engine
Together with the Q2_0 matvec change of #2221 (both bitwise, measured as one step), 512 new tokens, two runs each: Spanish chat 86.0 → 87.8 t/s, code 103.1 → 106.1, English at 32K 75.3 → 78.4.
Part of the Turing set tracked in #2197.
🤖 Generated with Claude Code