Skip to content

[codex] cuda GH200 KV cache optimizations#189

Closed
DominikBucko wants to merge 1 commit into
antirez:mainfrom
DominikBucko:codex/gh200-kv-cache-optimizations
Closed

[codex] cuda GH200 KV cache optimizations#189
DominikBucko wants to merge 1 commit into
antirez:mainfrom
DominikBucko:codex/gh200-kv-cache-optimizations

Conversation

@DominikBucko

Copy link
Copy Markdown

Summary

This PR adds CUDA-side KV cache storage options intended for large-context DS4 inference on Hopper/GH200-class GPUs.

  • Add selectable CUDA KV cache storage via DS4_CUDA_KV_CACHE_TYPE=f32|f16|fp8 and legacy DS4_CUDA_KV_CACHE alias.
  • Store raw, compressed attention, and index KV cache rows through cache-aware allocation/view helpers instead of assuming float row layout.
  • Add f16 and fp8 cache load/store paths, including fp8 per-64-value scaling metadata.
  • Update context memory estimates so they reflect the selected CUDA KV cache type.
  • Use managed KV cache only for very large allocations where it is needed to start long-context runs.
  • Fix the raw-only single-token decode path in the online mixed-attention kernels so layers without compressed KV attend the visible raw KV rows correctly.

Why

On a 96GB GH200, DS4 was limited by CUDA KV cache memory when pushing single-user long-context inference. The original CUDA path stored KV cache rows as f32 everywhere, which made large contexts unnecessarily expensive and prevented practical tests near the expected memory envelope.

The new f16 cache mode roughly halves KV cache memory while preserving coherent model behavior in the GH200 tests. fp8 mode is also available for experimentation, though it is currently slower/lower quality than f16 in my runs.

GH200 validation

Environment used for the main long-context profile:

DS4_CUDA_KV_CACHE_TYPE=f16 DS4_METAL_PREFILL_CHUNK=512 DS4_CUDA_NO_Q8_F16_CACHE=1

Observed on GH200 / sm_90:

  • make cuda CUDA_ARCH=sm_90 completed.
  • CUDA long-context regression passed: cuda long-context regression: OK.
  • ds4-eval --questions 20 -n 4096 with f16 KV passed 18/20 questions.
  • 32k context benchmark after the fix:
    • f16 KV: prefill ~1157 tok/s, generation ~27 tok/s, context buffers ~442 MiB.
    • fp8 KV: prefill ~860 tok/s, generation ~22 tok/s, context buffers ~163 MiB.
  • f16 mode could start and serve with ctx=1800000 on the 96GB GH200, with context buffers reported around 13.28 GiB.

Notes

The env var name currently says CUDA because these paths are CUDA-specific. The surrounding function names still use the existing metal_graph_* naming convention from the repo.

@DominikBucko

Copy link
Copy Markdown
Author

Closing in favor of a replacement PR with neutral branch and title naming.

@DominikBucko
DominikBucko deleted the codex/gh200-kv-cache-optimizations branch May 18, 2026 13:22
ivp5 added a commit to ivp5/ds4 that referenced this pull request May 27, 2026
…irez#192 doctrine

Per the spaghetti-refactor doctrine (shift antirez#189 — geohotz/Knuth lead;
Carmack/Tao consult; 'delete BoundaryHandler entirely, inline as direct
if-ladder') and the cargo-cult cut doctrine (shift antirez#192 — 'any customer
pull elevates back to mod.ts; until then the cut stands'):

ds4_pillars.{c,h} was a 219-line + 90-line facade declaring an
ds4_icb_*/ds4_hot_expert_*/ds4_spec_decode_* API with ZERO callers in
the inference path (ds4.c / ds4_metal.m / ds4_server.c).

The REAL ICB record→replay mechanisms live in-place in ds4_metal.m as
4 independent opt-in pipelines (DS4_ICB_ACTIVE / DS4_ICB_TOPK_MASK /
DS4_ICB_SOFTPLUS / DS4_ICB_WEIGHTS_ONE). The facade was scaffolding
that didn't earn its keep.

Changes:
- mv ds4_pillars.c → ~/.Trash/ds4_pillars.c.<ts>.bak (reversible)
- mv ds4_pillars.h → ~/.Trash/ds4_pillars.h.<ts>.bak (reversible)
- ds4_metal.m: removed vestigial #include 'ds4_pillars.h' (no symbols
  were used from it)
- Makefile: removed ds4_pillars.o from CORE_OBJS

Build verified clean both modes:
- Default:  ds4-bench 840KB → 837KB (-3KB)
- JOURNAL=1: ds4-bench builds clean too (839KB after)

Carmack lens: 'ship simplest WORKING — anything that doesn't earn its
keep is dead code'. 309 lines (.c + .h) removed for identical behavior.

Aphyr-grade totality: every (function × caller) cell was 0; no
behavior change possible from removing a function with zero callers.

Reversible per CLAUDE.md 'NEVER use rm — use mv ~/.Trash/'. If future
pillar-orchestration need emerges, restore from ~/.Trash and re-add to
Makefile CORE_OBJS. Documented in DS4_M1_OPERATING_RECIPE.md under
'ICB record→replay status'.

Next-session reads operating-recipe + this commit message; no surprise.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant