Pull requests / #2071

#2071 sm_75: a faster tiled FP32 block scorer (STRATA_SELECT_SIMT=2), and the case for SIMT on RTX 20 by default

open · @rafatxf · 0 commentaires · Sur GitHub

BenchmarksSetup & installServer & APINVIDIA / CUDAModels & quantsDocumentationWindows

Description

On Turing the prompt path's QSA block scores run the warp kernel (no TF32 tensor cores, so `qsa_block_scores_tc` falls back), and at long context they dominate the prompt. `STRATA_PREFILL_TIMING=1` on an RTX 2080 Ti, appending 16K tokens to a 390K conversation (`--serve`, conversation cache reused):

| phase | default | `STRATA_SELECT_SIMT=1` |
|---|---:|---:|
| qsa select | 19.0 s (61.5 %) | 3.5 s (23.0 %) |
| whole 16K read | 31.5 s (521 tok/s) | 15.9 s (1031 tok/s) |

This PR adds `STRATA_SELECT_SIMT=2`: `block_scores_simt_kernel` with 32 queries × 128 blocks per CTA (8 × 8 products per thread instead of 8 × 4) and the next K chunk's loads in registers while the current one is used. Every (row, block) dot is the same `fmaf` chain over k = 0..127 and the same relu sum over the heads, so its scores are **bitwise those of `=1`**. `qsa_select_bench` gets an optional hash of the fast scorer's bytes (`QSA_BENCH_HASH=1`) to show it: the same hash for `=1` and `=2` at 131K, 262K, 400K and 510K.

`=2` stays opt-in like `=1`. The second half of this description is the data I'd offer for turning SIMT on by default on sm_75 (your call, as with `STRATA_BF16_TC`).

## Setup

RTX 2080 Ti 22 GB (sm_75, PCIe 3.0 x16), i7-6700, 56 GB DDR4-2133, CUDA 13.0, driver 595, SM clock locked at 1650 MHz, 240 W. `v0.1.43` built from source with `-DSTRATA_BUILD_TESTS=ON`. Model Q2_0, `--resident-experts`, `--spec 4 --spec-min-p 0.7`, `--max-context 524288` (YaRN ×2), `--kv int8 --kv-resident 32768`.

## Scorer: `qsa_select_bench CTX 256 5 524288`

| context | warp kernel | SIMT=1 | SIMT=2 |
|---|---:|---:|---:|
| 131K | 7.66 ms | 1.21 ms | 0.95 ms |
| 262K | 15.25 ms | 2.01 ms | 1.87 ms |
| 400K | 23.24 ms | 2.96 ms | 2.82 ms |
| 510K | 29.60 ms | 3.77 ms | 3.57 ms |

Selections against the warp kernel: 256/256 identical at 262K, 400K and 510K, 255/256 at 131K (0.0002 % of cells). Accuracy against FP64: max error 5.8e-5 vs the warp kernel's 2.1e-5 (2.3e-7 of the score scale).

## Engine, one-shot, `STRATA_SELECT_SIMT` 0 vs 2

Prompt read, same binary, real text (the 256K token file of the benches):

| prompt | default | SIMT=2 | |
|---|---:|---:|---:|
| 49K | 1349 tok/s | 1451 | +7.6 % |
| 98K | 1230 | 1434 | +16.6 % |
| 147K | 1129 | 1407 | +24.6 % |
| 197K | 1042 | 1380 | +32.4 % |

Decode does not change: it scores with `block_scores_multi_kernel`, which this does not touch.

## Quality: teacher-forced, the two paths against each other

The method from #655 (docs/UNSLOTH_Q4.md): a `--serve` engine with `--adapt-every 100000`, the first P tokens read by the prompt path (the path this changes) as one request, then the next 2,048 tokens resumed at P through the verify windows with `--short-read`, `STRATA_LOGPOS` with `STRATA_LOGPOS_TOPK=20` writing every position. Raw text (Don Quixote, Spanish).

| prefix read batched | positions | argmax agreement | KL (off ‖ on) | perplexity off / on | argmax where off's top-2 gap ≥ 0.5 |
|---|---:|---:|---:|---:|---:|
| 32,768 | 2,047 | 97.9 % | 0.0099 | 4.552 / 4.620 | 1954 / 1970 |
| 98,304 | 2,047 | 95.3 % | 0.0136 | 5.409 / 5.416 | 1672 / 1686 |

- **Noise floor:** two runs with SIMT off write identical files (KL 0, every position the same), so every difference above is the scorer's summation order.
- **Near-ties:** where the off run's two most likely tokens are at least 0.5 nats apart, the argmax agrees at 1954 of 1970 positions (32K) and 1672 of 1686 (98K). Perplexity moves by +1.5 % and +0.1 %.
- **For scale:** the KL is that of `STRATA_BF16_TC` in #655 (0.0085-0.011) and below the 0.02-0.05 that DETAILS.md lists for other prompt-path changes.
- **First-token logits** after prompts of 48K / 98K / 147K / 197K tokens (`STRATA_DUMP_FIRST_LOGITS`, full vocabulary): KL 7.5e-4 / 9.6e-3 / 7.3e-6 / 2.9e-4; the same argmax in 3 of 4 (at 98K the two candidates were a near-tie, and SIMT gave the real next token the higher probability).
- **Needles:** 2 of 2 at 352K tokens through the server (`/v1/chat/completions`, thinking off).

The server here runs 0.1.43 with this patch and `STRATA_SELECT_SIMT=2` since 2026-10-12.

## Tests

`qsa_parity`: 0 failures. `qsa_select_bench` with `QSA_BENCH_HASH=1`: the same hash for `=1` and `=2` at every context above.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Sur le site

Liens install, modèles, releases.