Skip to content

Future: NVMe cold tier under Device/Host planner for parked continuations #143

Description

@steve8697

Related: #142 (system-frontier write candidate). This is a later capacity idea, not a substitute for that serve-layer fix.

What we are asking

Would you consider, after the current Device + pinned-Host catalog is settled, a cold NVMe tier under the same planner — not a second cache product.

Today the degradation graph is already monotonic:

Device replica → pinned Host State/KV → drop checkpoint → evict owner

A natural extra step is:

Device (hot) → pinned DDR5 Host (warm, --host-kv-mib) → NVMe (cold) → evict

vLLM/LMCache, TensorRT-LLM host offload, and NVIDIA ICMSP all use this shape for parked context. NInfer is stricter (exact frontier + full StateImage + GDN recurrent bundle), so a disk tier only makes sense if it stores the same checkpoint object the Host extent store already knows, not raw KV pages alone.

What it would help, and what it would not

Measured on this box (RTX 5090 32 GiB, WSL2 64 GiB DDR5, C=2, INT8, Qwen3.8-27B NVFP4):

already true today SSD/DDR5 would not change
Live decode stays on Device Tokens/s of an active lane
--max-concurrency 2 is the GPU lane cap Two 150k chats decoding at once (KV pool is still one 245k Device pool)
Same-turn private_turn_closure is already ~90–125 ms First-token of a hot continuation
gap why a cold tier might help
Returning to a parked 80–120k agent chat after other sessions filled Device+Host Avoid 20–50 s root re-prefill. Fork #73 already showed 118k Device miss → host restore 422 ms vs 53 s. NVMe would be slower than pinned DDR, but still far cheaper than prefill if sequential restore is ~1–3 s for a few GiB.
More retained session count at C=2 C=2 only has 2 active + a handful of Device/Host checkpoints. Extra cold slots raise the chance the next Hermes/OpenCode window is a restore instead of root. That is reuse probability, not live batch width.
Shared system prefix once #142 exists One published 8–30k shared_stable_prefix could sit in Host or NVMe and seed many siblings without occupying Device KV.

So: more parked conversations survive, not higher simultaneous decode concurrency. Worth saying explicitly so this is not read as “SSD makes C=8 on 32 GiB”.

Constraints that match current contracts

From docs/serving.md and resource-scheduling-and-context-cache.md:

  • A reusable checkpoint is KV and complete continuation state (Linear Attention image, MTP watermark, boundary hidden). Disk must round-trip that bundle or the restore is unsound (this is exactly the class of bug #73 hit when only part of the slot was restored).
  • Pressure already compares immediate transfer work vs later recovery / re-prefill. A disk target is another cost coefficient (context-cost-transfer), not a new policy language.
  • Reads stay exact-identity. No approximate / block-hash prefix cache.
  • Live decode must never stream KV from NVMe. Cold tier is admission-time materialize-to-Device/Host, then run.
  • Opt-in, default off: --cold-kv-dir PATH --cold-kv-gib N. Empty path = current two-tier behavior.
  • On WSL2, the directory must be Linux ext4 (~/…), not /mnt/c NTFS.

Suggested shape (if you ever do it)

Keep one catalog. Add one placement:

tier media role
Device GPU HBM active + hottest checkpoints
Host pinned DDR5 (--host-kv-mib) warm park, sub-second restore
Cold NVMe files / extent log overflow of Host, sequential dump/restore of sealed checkpoints

Evict Host → Cold as a planner successor of “Device → Host-only”. Restore Cold → Device (or Host) as NeedsTransfer. If restore cost ≥ predicted prefill, skip and root (same degrade-instead-of-crash rule as #73 after the stale-plan fix).

Do not bolt on #73’s separate content-addressed store next to HostKVArena. Same axis, two LRUs.

Why we are filing this now

Single-user C=2 agent serving (Hermes / OpenCode / Pi) already wants more than 2–4 retained 100k histories. Pinned 16 GiB Host is the right warm tier; consumer NVMe is the only place left once that fills. Happy to prototype measurements on 5090 if a disk placement exists; not asking for it before #142.

No local numbers for NVMe restore yet — we only have Device/Host. This is a design vote, not a perf claim.

Activity

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