Pull requests / #1904

#1904 adaptive tier: --adapt-async 1 in the arena mode (one GPU, copy-in only), x1.07-1.11 cold decode on an RTX 3090 + Ryzen 5 5600X

open · @RubenTorney · 0 comentários · No GitHub

BenchmarksServer & APIAMD / HIPNVIDIA / CUDADocumentationWindows

Descrição

## Title
Issue: #1903

## Summary

In the arena mode the blocking adaptive tier creates and joins a thread every verify window and the next window waits for its
copies: ~3.2 of 25.9 ms per window on this machine (the interval #1863 found outside the timing breakdown). This lets
`--adapt-async 1` run in the arena too. The arena holds every expert in RAM, so a round is a copy-in only: no copy back, no RAM
move, no exchange buffers. Opt-in; without `--adapt-async 1` (and in the resident RAM mode, and on several GPUs) nothing changes.

Cold A/B against the v0.1.42 tag (12 distinct prompts x 2 rounds, fresh server per arm and round, paired): **x1.07, faster on
12 of 12 prompts** (97.2 → 107.7 tok/s; x1.11 in an earlier run the same day, when the learned profile was younger and the tier
swapped more). One cold window: 25.9 → 21.6 ms, adapt wait 0.41 ms, join 0.

## What changed

- `src/program/generate.cpp`
  - The `--adapt-async` gates accept the arena (`srcp == &arena_src`) on one GPU; a layer split stays on the blocking tier.
  - The asynchronous tier's state machine, arena case: `exchange = false`, the source blob is `ArenaExpertSource::blob_at()`,
    the RAM-move steps are skipped. The evicted slot is marked non-resident and `res_upload` runs before the round's copies are
    posted; an expert becomes resident only once its copy's event has completed.
  - `STRATA_ADAPT_ASYNC_WAIT=1` (default in the arena): the tick after a round waits for that round, so the window in which an
    expert turns GPU-resident does not depend on timing. `STRATA_ADAPT_PICK_INLINE=1` (default in the arena): the pick runs on
    the host thread, one round per window. `STRATA_ADAPT_ASYNC_BATCH=N` caps the copies posted per tick (default 0 = all;
    16 measured 16 % slower here). Arena rounds are as large as the blocking tier's (`--adapt-swaps`, not capped at 96).
  - Fences: every K/V grow (`kvg_ensure`'s quiesce lambdas), `kv_quiesce` and the `VRAM` command now land the round in flight
    (`adapt_quiesce`) — they only called `apply_pending(true)`, so a swap still copying could write a slot just lent to the K/V.
    This also applies to the resident mode's asynchronous tier. A failed round still drains its copies before slots move.
  - `STRATA_DECODE_TIMING=1`: the serial `--serve` line adds `adapt wait X join Y, Z swaps/window` (part of #1863).
  - `--adapt-async` help text.
- `src/core/expert_source.cpp`, `include/strata/core/expert_source.hpp`: `ArenaExpertSource::blob_at()`, `blob()` without the
  read counter (it runs on the job thread).
- `docs/DETAILS.md`: the arena paragraph next to `--adapt-async 1`.
- `bench/results/2026-10-11-community-rtx3090-5600x-arena-async/`: method, numbers, raw data (sha256 of every answer), harness.

## How the default path was checked

- Bit-exact mode (`STRATA_IQ_MT_MIN=1 --pcie-frac 0 --adapt-every 0`), greedy, 6 prompts, two fresh v0.1.42 engines and one of this branch:
  on the 5 prompts that v0.1.42 reproduces between two of its own fresh engines, v0.1.42 and this branch without
  `--adapt-async` give the same answers byte for byte (sha256), with `--expert-cache auto` and with a fixed size. The 6th
  prompt differs between two runs of v0.1.42 itself in that mode on this machine.
- Built: CUDA only (Windows, VS 2022 17.14, CUDA 12.8, sm_86). **Not built: HIP, SYCL** (no such hardware here); the change is
  host code in `generate.cpp` / `expert_source.cpp`, no backend-specific path.

## Extra Notes

- Like the resident mode's asynchronous tier, answers are not bit-exact from run to run with the option on (which window first
  computes a swapped-in expert on the GPU). On this machine greedy answers already differ between two fresh engines of the
  unpatched build (the CPU/GPU split of the misses depends on timing).
- After a long prompt the gain shrinks: the prompt itself has moved its experts into VRAM (hit rate 97-99 %), the tier has
  little left to swap: level with v0.1.42 at 56K and 117K tokens (95.3 / 97.3 and 97.0 / 96.1 tok/s).
- Robustness (full test branch: this change plus other opt-in switches): 63K-token prompt then 4 follow-up turns, K/V grown
  to 65,536 cells during the conversation, no `ERR`.
- Reviewed for fence correctness before the A/B (VRAM command after STOP, K/V grow, request start drain, error path).

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

https://claude.ai/code/session_015oFHMEgBzk7kQSqUVWoc67

No site

Links install, modelos, releases.