贡献 / #1943

#1943 hip: opt-in exact gfx1100 QSA scorer for long prefill

open · @2jztricks · 0 评论 · 去 GitHub 看

BenchmarksSetup & installMulti-GPUAMD / HIPNVIDIA / CUDAModels & quants

说明

Large fresh prompts on gfx1100 spend substantial time in QSA block scoring. This adds an **opt-in, HIP-only exact scorer** that reduces fresh request latency by about 10–23% on an RX 7900 XTX in the measurements below, while keeping the default scorer selected.

This ports the four-lanes-per-query method and original FP32 reduction tree from **xrip's #1825**, pinned to `14bf32150490bb9f5fc4d9c7c5dcfdc96dd98797`. That PR currently excludes HIP. Credit for the algorithm belongs there; this contribution adds the guarded gfx1100 implementation, hardware validation, and reproducible measurement evidence.

### Scope

- Enable with `STRATA_SCORES_THREAD=1` at process startup; **off by default**.
- Exact gfx1100 device check; at least 64 queries and an actual live bound of at least 16,385 index blocks, within allocation capacity. A reserved 256K context alone never engages it.
- Four wave32 lanes per query, all four heads in registers, keys reused through LDS; 64 queries / 32 key-block tiles / 256 threads. Original tail scorer and top-k remain intact.
- Decode, expert placement, CPU kernels, PLE storage and sampling are unchanged by the patch. No extra persistent weights or conversation state are allocated.
- Adds a standalone HIP score/ID parity target, available even when the published tree omits `tests/`. CUDA does not compile the new HIP kernel.

### Before/after on the RX 7900 XTX

RX 7900 XTX 24 GiB, Ryzen 9 7950X3D, 64 GiB installed RAM, Nobara 44, ROCm 10.0.0, observed PCIe 4.0 x16, fixed 272 W cap. OrcaRouter Flash Next IQ3_S; logical context 262,144; int8 KV / 32,768 resident cells; 15 CPU expert workers; prefill 16,384; MTP6/floor0.70; same balanced profile and 8,144 GPU expert slots in every arm. PLE stayed on ext4 SSD with direct I/O. Experiment swap limit zero.

Fresh numerical-source prompts, zero reused prefix tokens, greedy sampling, reasoning disabled, **one generated token**. Values are non-streaming **request latency**, excluding model loading; this is not a sustained decode or streaming-TTFT benchmark. New private worker for each fresh case; OS file cache not flushed.

| Engine family | Actual prompt tokens | Paired trials | Before mean | After mean | Less elapsed time |
| --- | ---: | ---: | ---: | ---: | ---: |
| Tuned 0.1.40.3 control/candidate | 130,978 | 3 | 66.741 s | 59.769 s | 10.45% |
| Tuned 0.1.40.3 control/candidate | 239,906 | 3 | 142.718 s | 110.407 s | 22.64% |
| Current main, **same binary**, flag off/on | 130,978 | 1 | 68.872 s | 60.020 s | 12.85% |
| Current main, **same binary**, flag off/on | 239,906 | 1 | 142.843 s | 111.828 s | 21.71% |

The repeated family used off/on, on/off, off/on and includes the same local prefix-reuse/budget-loan changes in both arms. The separate current-main engine was built from `61b3fb5dd3f1e8ec09cf7e4e05208bc6d3c46406` plus this patch. Its only arm difference is the scorer flag. These families are **not pooled**. All fresh input/output hashes and output counts matched.

At the actual 256-query batch size, the submitted CMake microbenchmark measured the **scorer stage**:

| Live context | Original scorer | New scorer | Stage speedup |
| --- | ---: | ---: | ---: |
| 131,072 | 3.065300 ms | 0.742917 ms | 4.126× |
| 240,000 | 5.264949 ms | 1.389344 ms | 3.790× |

Warmed GPU-event timing, interleaved ABBA, four trials / ten calls per trial. The stage speedup is not presented as whole-task speedup.

### Correctness and build validation

- Submitted HIP CMake test passed **35 cases: 223,664,777 bitwise-equal score values and 11,895,800 equal ID buffer entries**, including padding and allocation guards.
- Boundaries, partial tiles, 256-query batches, one/six-query fallback, capacity versus actual live extent, invalid/absent bounds, ties, signed zero, NaN/Inf, wide exponents and cancellation covered.
- Tuned-model 4K/131K prefill plus first token matched main state byte for byte; separate 64-token output and STOP/resend output checks matched. Full speculative state after 64 MTP tokens can vary even across repeats of the original binary; this is documented rather than claimed as full-state equality.
- Current-main full HIP engine and standalone CMake test target built and ran. The touched CUDA module compiled with CUDA 13.0 for sm_89; no CUDA GPU test or full CUDA-engine build. No SYCL source changed.
- Current-main off/on requests passed, matched output hashes, kept the same 8,144 expert slots, and maintained the 8 GiB available-memory floor; minimum observed 12.249 GiB, experiment swap zero.

### Limits: no default or general agent-speed recommendation

Cached follow-ups processing 2,085 new tokens had only a modest/flat repeated gain: 2.829→2.658 s at 128K; 3.418→3.417 s near240K (two pairs each). The single current-main continuation results are included in the report but do not establish a repeatable large gain.

A separate correction-inclusive 192K-source-archive pilot used xhigh/8,192 reasoning tokens, T0.3, matched seeds and automatic full-suite checks:

| Task | Original | New scorer | Outcome |
| --- | ---: | ---: | --- |
| Go alphametics | 209.136 s | 400.318 s | Both passed; 3 versus 5 turns |
| Rust xorcism | 473.734 s | 304.906 s | Both passed; 6 turns each |
| **Total** | **682.870 s** | **705.225 s** | **New scorer 3.27% slower** |

One pair per task, not an official Aider leaderboard score. The Go repair-path divergence remains unexplained. An earlier 240K archive attempt exceeded the context limit during Rust repairs and is preserved separately as a protocol failure. The general promotion gate failed; no full24 run, no production promotion, and no Luna/frontier/overall quality superiority claim.

Only gfx1100 was validated on hardware. The model comparison used the same locally patched prefix-cache frontend in both arms; the stock latest Python frontend was not benchmarked. The one-token screen cannot establish generation quality. Broader task qualification is needed before any default change.

### Reproduction and artifacts

[Full report, medians/ranges, per-request JSON, exact prompt fixture, configuration/provenance and benchmark script](https://github.com/2jztricks/Strata/tree/hip-gfx1100-exact-qsa-scores/bench/results/2026-10-11-gfx1100-qsa-scores).

```bash
cmake -S . -B build-qsa -G Ninja -DCMAKE_BUILD_TYPE=Release \
  -DSTRATA_ENABLE_HIP=ON -DCMAKE_HIP_ARCHITECTURES=gfx1100 \
  -DSTRATA_BUILD_TESTS=OFF -DSTRATA_PARITY_GFX1100_QSA_SCORES=ON
cmake --build build-qsa --target qsa_scores_gfx1100_parity -j 6
ctest --test-dir build-qsa --output-on-failure -R '^qsa_scores_gfx1100_parity$'
```

The report provides request-screen commands and all tested settings. The script reproduces the frozen fresh/follow request hashes, refuses to overwrite attempts, and rejects accidentally reused prefixes in a fresh case. No credentials, private conversation history, model weights or large profiling traces are included.

本站相关内容

相关页面的快捷入口。