Issues / #2261

#2261 [0.1.43.1] RTX PRO 6000 96 GB: setup keeps KV streaming on although every expert fits in VRAM - turning it off gives decode +9.5 %, agent decode +13 %, 16K TTFT -23 %

open · @beastrobin · 0 commentaires · Sur GitHub

BenchmarksSetup & installMulti-GPUAMD / HIPNVIDIA / CUDAModels & quantsWindows

Description

## What setup chose, and why it is wrong here

setup.py decides KV streaming from system RAM ("the owner's rule", `--kv-streaming auto`, around the code that prints "the KV cache stays in VRAM (fewer cached experts)"). With this install (`iq3_s`, `--max-context 262144 --kv int8`) it wrote `--kv-resident 32768`: at contexts above 64K the K/V streams from pinned RAM and only 32768 cells per QSA layer stay in VRAM. The reasoning is sound when the KV competes with an expert cache that cannot hold everything. On this PC it cannot:

- all 24576 of 24576 experts are VRAM resident from boot ("R4 hit path ON", zero-doorbell graph);
- after everything loads there are still ~29 GiB VRAM free;
- the whole 262144-token int8 K/V is small enough to live there entirely (observed VRAM use went 60.9 -> 69.7 GiB when I made it fully resident).

So streaming costs PCIe and stalls and buys nothing. The engine log confirms the cost during prompt reads: `KV streaming: 47-65 % of block reads hit VRAM, 50-365 MiB read from RAM` per request at 40-64K context.

## A/B (same machine, same day, same session)

Engine 0.1.43.1 (release build, a0116b27), RTX PRO 6000 Blackwell Workstation Edition (96 GiB, sm_120), Core Ultra 9 285K, 253 GiB RAM, Windows 11 26200, driver 610.74, GPU power capped at 300 W for both arms. Suite: `python tools/strata_bench.py --url http://127.0.0.1:8200 --long --runs 2`. Only one setting differs: `--kv-resident 32768` vs `--kv-resident 0` (the latter means "all cells in VRAM"). Medians of two runs each.

| Test | kv-resident 32768 (as installed) | kv-resident 0 (fully resident KV) | change |
|---|---:|---:|---:|
| short chat decode tok/s | 179.4 (150.2-244.8, n=6) | 196.4 (163.1-247.5, n=6) | +9.5 % |
| agent session decode tok/s | 164.7 (n=10) | 186.6 (n=10) | +13.3 % |
| 4K prompt tok/s | 3034 (1964-4104 — very noisy) | 4148 (4122-4174, stable) | +37 %, and the variance disappears |
| 16K prompt tok/s / TTFT | 4117 / 4.13 s | 5086 / 3.20 s | +23.5 % / -23 % |
| 32K prompt tok/s / TTFT | 4867 / 6.64 s | 5106 / 6.31 s | +4.9 % / -5 % |
| chat first token | 0.24 s | 0.22 s | -8 % |

Both results folders (`results.json` + engine log excerpts) can be attached: `bench/results/2026-10-13-community-rtx-pro-6000-blackwell-worksta-qwen3-8-flash-next-iq3-s` and `-2`.

## Suggested rule (one sentence before code)

When `--expert-cache auto` fills every slot (all experts resident) **and** the free VRAM after loading is more than `max_context x the int8 K/V per token`, keep the KV fully in VRAM regardless of context size — i.e. treat "streaming from 64K" as a consequence of the expert cache's needs, not of the context length alone. The RAM test stays the guard it is today when some experts are *not* resident.

## Not tested

Not tested: contexts above 262144 (where full residency may genuinely not fit), `--kv k8v4`, multi-GPU splits with this setting, vision-heavy sessions at long context, and whether one intermediate kv-resident value between 32768 and full captures most of the gain on smaller big cards (24-32 GB). Two runs per arm only; the ranges for the chat numbers are wide because batch windows interleave.

---

<details>
<summary>Arm A — as installed (--kv-resident 32768)</summary>

# Community benchmark on NVIDIA RTX PRO 6000 Blackwell Workstation Edition

Measured on 2026-10-13 with `tools/strata_bench.py` (suite 1, 2 runs per test, medians with ranges). Speeds are the engine's own timings; first-token times are measured by the client over HTTP. Speed only: no correctness check was run.

## Hardware and software

- GPU and VRAM: NVIDIA RTX PRO 6000 Blackwell Workstation Edition, 96 GiB VRAM
- CPU: Intel(R) Core(TM) Ultra 9 285K (24 cores, 24 threads); installed RAM: 253.4 GiB; storage: not measured
- OS: Windows 11 (10.0.26200); GPU driver: 610.74; CUDA: not read
- Strata: project 0.1.43.1, commit not a git checkout; engine 0.1.43.1
- Background workloads and power limits: not recorded

## Model and configuration

- Model and quantization: qwen3.8-flash-next-iq3_s
- Context: 262144 tokens; parallel slots: 2
- Settings: the install's own configuration, unchanged; thinking off for the suite; temperature 0

## Method

Run by `python tools/strata_bench.py --long --runs 2` against the HTTP API of a Strata server (already running); model loading is not timed. One warm-up chat and a 1K prompt are discarded first. Every prompt starts with a unique tag, so the conversation cache cannot help the fresh-prompt tests.

- short chat: the three questions of `tools/ab_engine.py`, up to 100 new tokens, 2 runs
- 4K / 16K prompts: generated word lists sized by a calibration request, 24 new tokens, 2 fresh prompts each
- agent session: system prompt and four tools, then 5 turns that each add about 1500 words of a project file and continue from the model's own earlier answers (the way agent clients resend a conversation), 64 new tokens per turn, 2 sessions; the cache numbers come from the answer's usage (`cached_tokens`) and timings (`prompt_n`)
- concurrency (when run): N requests sent at the same moment, total tokens over the wall time of the burst, latency over all requests

## Results

| Configuration | Actual prompt tokens | Reused tokens | Generated tokens | Runs | Prompt tok/s median and range | Decode tok/s median and range | TTFT seconds median and range |
| --- | ---: | ---: | ---: | ---: | --- | --- | --- |
| short chat | 46 (43-51) | 0 | 100 (100-100) | 6 | not measured | 179.3 (150.2-244.8) | 0.24 (0.22-0.32) |
| 4K prompt, fresh | 4019 (4019-4019) | 0 (0-0) | 24 cap | 2 | 3034.1 (1963.8-4104.4) | not measured | 1.54 (1.00-2.08) |
| 16K prompt, fresh | 16058 (16058-16058) | 0 (0-0) | 24 cap | 2 | 4117.3 (3219.6-5015.0) | not measured | 4.13 (3.23-5.02) |
| 32K prompt, fresh | 32049 (32049-32049) | 0 (0-0) | 24 cap | 2 | 4867.2 (4648.4-5086.1) | not measured | 6.64 (6.34-6.94) |
| agent session, follow-up turns | 14473 (14450-14496) at the last turn | see below | up to 64 | 2 | see below | 164.7 (110.7-198.8) | 0.95 (0.62-2.66) |

Ranges are the lowest and highest of the runs; `Runs` counts requests that returned a token.

### Agent session (conversation cache)

Cache hit over the follow-up turns: 68.8 % (68.8-68.8); earlier-turn tokens read again per session: 4 (3-4) (earlier turns that the cache did not hold; the 13634 (13634-13635) new tokens of the files are read once); first turn (nothing cached) first token: 0.77 s (0.71-0.83).

| Turn (run 1) | Prompt tokens | Reused | Read | Prompt tok/s | First token (s) | Decode tok/s |
| ---: | ---: | ---: | ---: | ---: | ---: | ---: |
| 0 | 609 | 0 | 609 | 757.7 | 0.828 | 176.2 |
| 1 | 3717 | 634 | 3083 | 1174.8 | 2.66 | 194.6 |
| 2 | 5250 | 3780 | 1470 | 1681.0 | 0.9 | 162.5 |
| 3 | 8694 | 5314 | 3380 | 1463.0 | 2.352 | 166.8 |
| 4 | 11612 | 8752 | 2860 | 1195.1 | 2.412 | 170.3 |
| 5 | 14496 | 11650 | 2846 | 1534.7 | 1.874 | 149.5 |

Per-request data: `results.json`. Engine log lines from the start: `engine-log-excerpt.txt` (when this run started the server).

## Correctness and limitations

Not measured: this is a speed suite. The conversation uses the model's own replies, so token counts differ a little between runs. Machine details come from the server, `nvidia-smi`/`rocm-smi` and the OS; background load and power limits are not recorded. Total time of the suite: 52 s.

</details>

<details>
<summary>Arm B — proposed setting (--kv-resident 0)</summary>

# Community benchmark on NVIDIA RTX PRO 6000 Blackwell Workstation Edition

Measured on 2026-10-13 with `tools/strata_bench.py` (suite 1, 2 runs per test, medians with ranges). Speeds are the engine's own timings; first-token times are measured by the client over HTTP. Speed only: no correctness check was run.

## Hardware and software

- GPU and VRAM: NVIDIA RTX PRO 6000 Blackwell Workstation Edition, 96 GiB VRAM
- CPU: Intel(R) Core(TM) Ultra 9 285K (24 cores, 24 threads); installed RAM: 253.4 GiB; storage: not measured
- OS: Windows 11 (10.0.26200); GPU driver: 610.74; CUDA: not read
- Strata: project 0.1.43.1, commit not a git checkout; engine 0.1.43.1
- Background workloads and power limits: not recorded

## Model and configuration

- Model and quantization: qwen3.8-flash-next-iq3_s
- Context: 262144 tokens; parallel slots: 2
- Settings: the install's own configuration, unchanged; thinking off for the suite; temperature 0

## Method

Run by `python tools/strata_bench.py --long --runs 2` against the HTTP API of a Strata server (already running); model loading is not timed. One warm-up chat and a 1K prompt are discarded first. Every prompt starts with a unique tag, so the conversation cache cannot help the fresh-prompt tests.

- short chat: the three questions of `tools/ab_engine.py`, up to 100 new tokens, 2 runs
- 4K / 16K prompts: generated word lists sized by a calibration request, 24 new tokens, 2 fresh prompts each
- agent session: system prompt and four tools, then 5 turns that each add about 1500 words of a project file and continue from the model's own earlier answers (the way agent clients resend a conversation), 64 new tokens per turn, 2 sessions; the cache numbers come from the answer's usage (`cached_tokens`) and timings (`prompt_n`)
- concurrency (when run): N requests sent at the same moment, total tokens over the wall time of the burst, latency over all requests

## Results

| Configuration | Actual prompt tokens | Reused tokens | Generated tokens | Runs | Prompt tok/s median and range | Decode tok/s median and range | TTFT seconds median and range |
| --- | ---: | ---: | ---: | ---: | --- | --- | --- |
| short chat | 46 (43-51) | 0 | 100 (100-100) | 6 | not measured | 196.4 (163.1-247.5) | 0.22 (0.21-0.30) |
| 4K prompt, fresh | 4019 (4019-4019) | 0 (0-0) | 24 cap | 2 | 4147.9 (4122.1-4173.8) | not measured | 1.00 (0.99-1.01) |
| 16K prompt, fresh | 16058 (16058-16058) | 0 (0-0) | 24 cap | 2 | 5085.5 (5073.5-5097.5) | not measured | 3.20 (3.19-3.22) |
| 32K prompt, fresh | 32049 (32049-32049) | 0 (0-0) | 24 cap | 2 | 5106.2 (5085.5-5126.9) | not measured | 6.31 (6.29-6.33) |
| agent session, follow-up turns | 14468 (14451-14484) at the last turn | see below | up to 64 | 2 | see below | 186.6 (122.8-215.6) | 0.88 (0.58-1.13) |

Ranges are the lowest and highest of the runs; `Runs` counts requests that returned a token.

### Agent session (conversation cache)

Cache hit over the follow-up turns: 68.7 % (68.7-68.8); earlier-turn tokens read again per session: 40 (5-74) (earlier turns that the cache did not hold; the 13634 (13633-13635) new tokens of the files are read once); first turn (nothing cached) first token: 0.64 s (0.57-0.71).

| Turn (run 1) | Prompt tokens | Reused | Read | Prompt tok/s | First token (s) | Decode tok/s |
| ---: | ---: | ---: | ---: | ---: | ---: | ---: |
| 0 | 609 | 0 | 609 | 1128.0 | 0.572 | 168.7 |
| 1 | 3714 | 634 | 3080 | 3467.3 | 0.923 | 212.1 |
| 2 | 5247 | 3777 | 1470 | 2687.9 | 0.58 | 188.2 |
| 3 | 8691 | 5240 | 3451 | 3159.7 | 1.131 | 154.5 |
| 4 | 11605 | 8745 | 2860 | 3338.4 | 0.898 | 215.6 |
| 5 | 14484 | 11638 | 2846 | 3353.8 | 0.877 | 122.8 |

Per-request data: `results.json`. Engine log lines from the start: `engine-log-excerpt.txt` (when this run started the server).

## Correctness and limitations

Not measured: this is a speed suite. The conversation uses the model's own replies, so token counts differ a little between runs. Machine details come from the server, `nvidia-smi`/`rocm-smi` and the OS; background load and power limits are not recorded. Total time of the suite: 41 s.

</details>

Sur le site

Liens install, modèles, releases.