Issues / #2010

#2010 0.1.43 on Linux CUDA: STRATA_ADAPT_OVERLAP costs 21% decode (single GPU, hybrid CPU, native expert pack)

open · @Krypto-Whitehat · 6 comentarios · En GitHub

BenchmarksServer & APINVIDIA / CUDAModels & quantsWindowsLinux

Descripción

### Summary

v0.1.43 makes `STRATA_ADAPT_OVERLAP` default **on** for Linux CUDA (commit `7c035d72`, where it
was made opt-in on Windows after measuring -2.6% / -2.1% on an RTX 5070 with the canonical Q2_0
pack). On my rig the overlap costs **21% decode**: 106.6 tok/s with `STRATA_ADAPT_OVERLAP=0`
against 84.6 tok/s with the default, measured at the same context with the same config and an
engine built minutes apart from the same tree.

The control run on v0.1.42 at the same time and with the same config gave 98.1 tok/s, so the
v0.1.43 default is also **13.8% below the previous release** on this machine.

### Environment

| | |
|---|---|
| GPU | NVIDIA GeForce RTX 5090 Laptop GPU, 24 GiB, PCIe Gen5 **x8**, probe 28.7 GB/s host->device |
| CPU | Intel Core Ultra 9 275HX, **8 P + 16 E cores**, 24 logical, AVX2 + avx_vnni, **no AVX-512** |
| RAM | 64 GiB physical, WSL limit 52 GiB, expert arena 39.97 GiB in 42 GiB hugepages |
| OS | Ubuntu 24.04 under WSL2, driver KMD 617.42 |
| Model | Qwen3.8-Flash-Next GSQ-RCO **IQ3_XXS**, native pack, 10,320 expert slots / 16.78 GiB cache |
| Engine (bad) | `7695859a` (v0.1.43), nvcc 13.4.92, `-DCUDAToolkit_ROOT=/usr/local/cuda`, arch 120 |
| Engine (control) | `61b3fb5d` (v0.1.42), same toolchain |

Config, identical in all three runs:

```
--pool-workers 12 --kv-grow --kv k8v4 --vram-reserve-mib 300 --max-context 262144
--spec 4 --spec-min-p 0.5 --prefill auto:16384 --expert-cache auto --expert-cache-per-layer
env: STRATA_PF_FUSED=1
```

### Reproduction

Three engine swaps, identical config, identical prompt (~182,779 tokens), 5 generations of 256
tokens each. The numbers are the server's own log line
(`prompt N tokens = ... M generated in T ms (X tok/s)`), medians:

| Engine | `STRATA_ADAPT_OVERLAP` | decode median | min | max | hit rate |
|---|---|---|---|---|---|
| v0.1.42 (`61b3fb5d`) | not applicable | **98.1** tok/s | 79.7 | 112.9 | 92.6 % |
| v0.1.43 (`7695859a`) | default (on) | **84.6** tok/s | 69.8 | 87.9 | 92.5 % |
| v0.1.43 (`7695859a`) | `0` | **106.6** tok/s | 89.1 | 108.6 | 91.1 % |

The separation is clean: **the minimum of the fixed run (89.1) is above the maximum of the
default run (87.9)**, so this is not measurement noise.

The same ordering held earlier the same evening on a second 0.1.42 run (102.7 tok/s).

### What was ruled out

- **Thermals / power.** GPU at 65 C idle, `nvidia-smi -q -d PERFORMANCE` reports
  `SW Power Cap`, `HW Slowdown`, `HW Thermal Slowdown` and `SW Thermal Slowdown` all
  `Not Active`; the session's `SW Thermal Slowdown` counter is 1.57 s in total. No
  `HW Slowdown`, no clock capping.
- **`--pcie-frac` is unchanged.** Both builds log
  `PCIe probe: 28.7 GB/s host->device -> pcie_frac 0.55 (default 0.55)`.
- **Prompt reuse** is the same across runs (the second generation of each set reuses the
  checkpoint), and **draft acceptance** is 69-78 % in all three runs.

So the only variable between the fast and slow 0.1.43 runs is the overlap switch.

### Suspected area

`STRATA_ADAPT_OVERLAP`, introduced for v0.1.43: "adaptive-tier copies overlap on CUDA"
(release notes) / `7c035d72` "STRATA_ADAPT_OVERLAP: opt-in on Windows (RTX 5070, Q2_0:
story -2.6%, code -2.1% with it, 5 pairs; IQ3_XXS neutral); Linux CUDA keeps it on".

Two differences from the measurement the flag was tuned on, both of which plausibly make the
overlap much more expensive here:

1. **Pack type.** The upstream number is on the canonical **Q2_0** pack. I run a **native
   IQ3_XXS** pack with `--expert-cache-per-layer`, so the adaptive tier swaps in and out of a
   per-layer slot arena (10,320 slots, 169 per layer) rather than a shared ring.
2. **CPU class.** The adaptive tier competes with a **hybrid** CPU pool. On this machine the
   pool is barrier-synchronised per layer and 12 worker threads sit at 100% of a core each
   (measured per-thread from `/proc/<pid>/task/*/stat`: 13 threads saturated, all others ~1%).
   The tier's copy overlapping therefore contends directly with pool threads that are already
   the critical path.

### Workaround (tested, works)

Put this in the config's `env` block (`strata-iq3_xxs.json`), next to `STRATA_PF_FUSED`:

```json
"env": { "STRATA_PF_FUSED": "1", "STRATA_ADAPT_OVERLAP": "0" }
```

`strata-iq3_xxs.json` is git-ignored (`/strata-*.json`), so the override survives updates and
engine rebuilds. With it the same build measures 106.6 tok/s, i.e. 8.7% **above** v0.1.42.

### Suggested upstream fix

1. **Make the overlap opt-in on Linux CUDA as well**, not just on Windows. The feature was
   measured as a loss on one CUDA card and is currently only disabled on Windows.
2. Or **measure it for native packs with per-layer expert slots** before turning it on - that
   is the configuration the default most affects, and it is not the one the flag was tuned on.
3. **Log the state in both directions in the startup banner.** The line
   `strata serve: adaptive overlap (STRATA_ADAPT_OVERLAP=0 turns it off): ...` is printed only
   while the overlap is actually active (the `if (adapt_overlap())` block in
   `src/program/generate.cpp`), and nothing at all is logged when it is off. So with
   `STRATA_ADAPT_OVERLAP=0` in the config there is no way to see from the log that the overlap
   was switched off. One line naming the state either way would do.

### Impact

A 13.8% decode regression on the previous release's speed, silently introduced by a default
that is only reported as a feature in the release notes. On a hybrid-CPU laptop build it is
the single largest speed factor I measured - larger than `--pool-workers`, `--kv-grow`,
`--vram-reserve-mib` and `--pcie-frac` combined.

### Reporter

`Krypto-Whitehat` - RTX 5090 Laptop (24 GiB), Core Ultra 9 275HX, 64 GiB, WSL2 Ubuntu 24.04,
engine built from source (nvcc 13.4.92, arch 120). Qwen3.8-Flash-Next IQ3_XXS, 262,144-token
context. Earlier report from this rig: #954 (fused/ring hang, resolved in v0.1.40.1), plus the
conversation-cache parking admission note.

En el sitio

Enlaces a install, modelos, releases.