Skip to content

QSA host KV tier: give each layer its own slot map (decode at 231K 6.8 -> 15.6 tok/s) #621

Open

Description

@gdevenyi

Before you start

  • I have read the Roadmap and this is not already planned there.
  • I have read the FAQ.
  • I have searched existing issues and found no duplicate.

Applies to

Engine

What problem does this solve

With --kv-host-pages (#499), every QSA layer shares one GPU slot map. At depth the 12 layers' selections (up to ~72 pages each) compete for the same ~515 resident pages, so they evict each other on every decode step. Every miss also copies the page's K/V rows for all layers over PCIe (~860 KB instead of the ~72 KB the layer needs). On Qwen3.8-Flash-Next this was the largest decode cost past 32K tokens: about 36 ms of a ~128 ms step at 64K.

Proposed solution

Give each layer its own residency: phys_of / logical_of / usage become [num_layers, ...], and the fused-copy descriptor is split per layer (that layer's K, V and fp8 scale banks only). The write pages are computed once per forward but ensured and translated per layer, before that layer's store; invalidate_pages clears every layer. GPU memory is unchanged. Reference implementation: gdevenyi@34d087eddf43

Measured on a GTX 1080 Ti, Qwen3.8-Flash-Next NVFP4, 32K tokens on the GPU plus 3584 host pages, together with the indexer change in the legacy-GPU issue:

  • 231K-token prompt: time to first token 2 h 20 min -> 29.5 min, decode 6.8 -> 15.6 tok/s, recall 3/3
  • a 2048-token prefill chunk at 64K depth: 41.8 s -> 13.4 s
  • the "selected pages dropped" warnings near 250K are gone

Alternatives considered

A larger --kv-reserve-tokens on the GPU hides the thrash up to that depth, but costs expert-cache slots.

Activity

  1. gdevenyi commented on Oct 13, 2026

    @gdevenyi
    ContributorAuthor

    Re-tested in the 1080 Ti deployment branch, rebuilt today on main 9c635a1 (torch 2.14.1+cu126, Triton 3.8, GTX 1080 Ti sm_61, Qwen3.8-Flash-Next-NVFP4 at 262K), through the server with --kv-host-pages 3584 (recall = three codes planted at 5/50/95%):

    Prompt tokens TTFT Prefill tok/s Decode tok/s Recall
    19,639 1.6 min 199 17.1 3/3
    115,368 13.0 min 148 16.5 3/3
    255,951 36.3 min 118 15.3 3/3

    Past ~220K depth, four prefill chunks logged selected pages dropped (a chunk's selection spanned more than the 443 slots); recall was unaffected. tests/kvcache/test_kv_host_offload.py passes on sm_61.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions