Skip to content

[GG] kv: restore nvfp4_ds_mla writer after consolidation - #115

Closed
voipmonitor wants to merge 4 commits into
dev/gilded-gnosis-old-basefrom
fix/gg-nvfp4-ds-mla-kv-20260717
Closed

[GG] kv: restore nvfp4_ds_mla writer after consolidation#115
voipmonitor wants to merge 4 commits into
dev/gilded-gnosis-old-basefrom
fix/gg-nvfp4-ds-mla-kv-20260717

Conversation

@voipmonitor

Copy link
Copy Markdown

Summary

Forward-port the write side and public dtype from the already merged #82 onto dev/gilded-gnosis. The original authors and commits are preserved.

GG already contains the newer B12X read/plan path for the 432-byte nvfp4_ds_mla record, including GLM-specific shape handling, but the consolidation lost:

  • the CacheDType CLI value;
  • the SM100/SM120 E2M1 + E4M3 MLA writer;
  • the stable-libtorch schema and binding;
  • the Python dispatch/fallback wrapper;
  • the dtype-size mapping;
  • the CUDA dequant-reference test.

This left a split implementation: the reader referenced nvfp4_ds_mla, while vllm serve --kv-cache-dtype nvfp4_ds_mla failed argument parsing before startup. The generic upstream nvfp4 cache dtype is not an alias: it has a different non-MLA record contract.

Integration details

The three conflicts with GG were resolved in favor of GG because GG already has newer versions of those reader-side changes:

  • sparse-MLA dtype canonicalization;
  • B12X 432/368-byte shape and kernel-format plumbing;
  • KV cache page-size accounting.

Only the missing writer-side pieces are introduced. The v17 runtime SM100+ guard and independent public-dispatch test reset are retained.

Validation

  • Ruff check and format check pass.
  • git diff --check passes.
  • CacheDType contains nvfp4_ds_mla.
  • dtype maps to torch.uint8.
  • B12X cache shape resolves to (num_blocks, block_size, 432).
  • vllm serve --help exposes nvfp4_ds_mla.
  • Full SM120 CUDA writer test and GLM/NF3 E2E validation will run in the release image built from this PR.

Closes the FF-to-GG consolidation gap for merged PR #82.

davidsyoung and others added 4 commits July 17, 2026 23:31
Adds an opt-in "nvfp4_ds_mla" KV cache dtype for the B12X sparse-MLA
backend: the 512-dim MLA latent is stored as packed NVFP4 (E2M1 data +
per-16-group E4M3 scales) instead of fp8, shrinking the per-token record
from 656 B to 432 B per layer (256 B FP4 NoPE + 32 B E4M3 scales + 16 B
alignment pad + 128 B BF16 RoPE) for +39-48% KV pool at equal budget.

Behavior is unchanged unless opted in: every change is gated on
kv_cache_dtype == "nvfp4_ds_mla", and fp8_ds_mla serving takes
byte-identical code paths — including the b12x call signatures. The
scale_format / caps kwargs are forwarded to b12x ONLY for the FP4
record, so fp8 serving keeps working on a b12x tree without the nvfp4
read-path port.

Write side: csrc concat_and_cache_nvfp4_mla, in-tree in
libtorch_stable/cache_kernels.cu (+ ops.h decl, _C_cache_ops schema),
guarded by ENABLE_NVFP4_SM100/SM120 with a clear error on pre-Blackwell
builds. _custom_ops falls back to loading a companion
vllm/_nvfp4_mla_cache_C.so iff the main build lacks the op, so the
feature can also ship as an overlay on an existing image.

Read side: requires the b12x ScaleFormat.NVFP4_E4M3 (== 2) decode/extend
path (companion b12x PR to follow); until that lands, requesting
nvfp4_ds_mla fails loudly at plan construction with an unexpected-kwarg
error. B12X_MLA_SPARSE only; FLASHMLA_SPARSE still canonicalizes to
fp8_ds_mla.

Validated on GLM-5.2 753B @ TP4/DCP4 on 4x RTX PRO 6000 (SM120):
KV pool 454,510 vs 307,547 tokens (+47.8%) at util 0.96; GPQA-Diamond
174/198 vs 175/198 for fp8 KV on the same checkpoint (statistically
tied); NIAH 30/30 from 4k to 360k; needle retrieved at 460k depth;
decode speed within noise of fp8 at matched context; zero OOMs.

Signed-off-by: David Young <davidseanyoung@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JzPRoS8j7b78iivwSmFv4y
…group scales

Quantizes a random MLA latent through the op and dequantizes the cache
record with a torch reference (E2M1 nibble table x per-group E4M3
scales): asserts the stored scales match E4M3(group_amax/6) within half
a mantissa step, bounds the per-element NoPE error by the E2M1 grid
half-gap (1.25x group scale), and checks the 16-byte pad is zeroed, the
16-bit RoPE lane is copied verbatim, and unmapped slots stay untouched.
Skips cleanly without CUDA, on ROCm, and below SM100.

Signed-off-by: David Young <davidseanyoung@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JzPRoS8j7b78iivwSmFv4y
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@voipmonitor, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 29 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e636a6be-5cfc-47ec-b103-fa1db1c50012

📥 Commits

Reviewing files that changed from the base of the PR and between 5b116d1 and 3cae13b.

📒 Files selected for processing (7)
  • csrc/libtorch_stable/cache_kernels.cu
  • csrc/libtorch_stable/ops.h
  • csrc/libtorch_stable/torch_bindings.cpp
  • tests/kernels/attention/test_cache.py
  • vllm/_custom_ops.py
  • vllm/config/cache.py
  • vllm/utils/torch_utils.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/gg-nvfp4-ds-mla-kv-20260717

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@voipmonitor voipmonitor changed the title [KV cache] Restore nvfp4_ds_mla writer after GG consolidation [GG] kv: restore nvfp4_ds_mla writer after consolidation Jul 18, 2026
@voipmonitor

Copy link
Copy Markdown
Author

Superseded by the canonical dev/gilded-gnosis consolidation. The corresponding implementation is present in commit(s): c266677,505acd14a4,6428dee087,67d5d7cc9f,bb88242e51. Closing the old-base PR so future work targets the canonical GG branch.

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.

2 participants