Skip to content

[GG] fix(mla): tail-pad cuBLAS BMM inputs - #140

Closed
voipmonitor wants to merge 2 commits into
fix/gg-pcie-capture-isolation-clean-stacked-20260720from
fix/gg-dcp-output-tail-padding-20260720
Closed

[GG] fix(mla): tail-pad cuBLAS BMM inputs#140
voipmonitor wants to merge 2 commits into
fix/gg-pcie-capture-isolation-clean-stacked-20260720from
fix/gg-dcp-output-tail-padding-20260720

Conversation

@voipmonitor

@voipmonitor voipmonitor commented Jul 20, 2026

Copy link
Copy Markdown

Summary

Fix the GLM MLA cuBLAS BMM layout hazard without reintroducing a blanket .contiguous() copy on the hot path.

This PR adds an explicit 64 KiB tail-padding storage contract for tensors that feed the GLM MLA cuBLAS BMMs, and wires that contract through the B12X sparse MLA / DCP producers.

Companion b12x PR for native MXFP8 linear output padding: local-inference-lab/sparkinfer#51

Stack Position

This PR is stacked on the clean GG reapply chain:

  1. [GG clean] fix(dcp): preallocate packed A2A graph buffers #141 - DCP packed A2A graph-buffer lifetime
  2. [GG clean] fix: profile MRV2 CUDA graph and sparse DCP memory #142 - MRV2 CUDA graph and sparse DCP memory profiling
  3. [GG clean] fix(concurrency): isolate graph state and B12X MoE overlap #143 - graph state isolation and B12X MoE overlap gating
  4. [GG] fix(mla): tail-pad cuBLAS BMM inputs #140 - this cuBLAS tail-padding fix

Do not merge until explicitly approved.

Root cause

The guarded CUDA repro confirmed that the relevant SM120 cuBLAS strided BMM pattern can read past the logical end of the BF16 input tensor up to the next 64 KiB boundary. With ordinary PyTorch caching-allocator outputs this is usually masked by allocator slack. With tight producer-owned storage, especially DCP/B12X IPC/NCCL outputs or custom linear outputs, the read can cross into an unmapped page and trigger Xid31 / FAULT_PDE / CUBLAS_STATUS_INTERNAL_ERROR in _v_up_proj.

Earlier safety fixes that force .contiguous() made the crash go away, but they added unconditional copies and caused DCP1 decode regressions. This PR instead fixes the producer/output-storage contract.

Changes

  • Add vllm.utils.cublas helpers:
    • CUBLAS_BMM_TAIL_PADDING_BYTES = 64 * 1024
    • tail_padded_empty(...)
    • storage_tail_bytes(...)
    • ensure_cublas_tail_padding(...)
  • Mark the B12X MLA backend as requiring 64 KiB BMM tail padding.
  • Set output_tail_padding_bytes on MLA Q projection layers so unquantized and MXFP8 linear producers can write directly into safe storage.
  • Add a tail-padded unquantized GEMM custom op for unbiased linear projections.
  • Forward the tail-padding request through the vLLM B12X MXFP8 linear wrapper.
  • Let B12X DCP pool and packed NCCL A2A reduce paths allocate the final V-up-projection input with mapped tail storage.
  • Keep a fallback ensure_cublas_tail_padding() at the two BMM call sites, but the intended path is producer-padded zero-copy output.
  • Add unit coverage for the storage contract and DCP producer paths.

Validation

Unit / focused tests:

  • tests/model_executor/layers/test_unquantized_linear_tail_padding.py: 2 passed.
  • tests/distributed/test_dcp_a2a.py -k 'test_cublas_tail_padding_preserves_values_and_storage_contract': 1 passed.
  • tests/distributed/test_dcp_a2a.py -k 'test_ag_rs_can_tail_pad_output_for_mla_bmm or test_b12x_lse_reduce_makes_views_contiguous or test_pack_unpack_combine_matches_reference': 26 passed.
  • tests/model_executor/kernels/test_b12x_mxfp8_linear.py -k 'test_b12x_mxfp8_apply_uses_packed_weight or test_b12x_mxfp8_custom_op_body_uses_forward_context': 2 passed.
  • Companion b12x MXFP8 CUDA test with bias: 1 passed.
  • git diff --check: clean.

E2E validation on the diagnostic image local/vllm:gilded-gnosis-v20-tailpad-producers-20260720 (sha256:8eb1ef5e416d0c9757b80d146b22e987e70511d9b3d59f7dff5ee777ce8fd56a), with native CUDA allocator and no .clone() workaround:

  • Exact external Xid-style config TP8/DCP2/MTP3, online MXFP8, B12X_PCIE_DMA=1, F8_DMA=ring, long prompt no-prefix-cache run: passed, no new Xid in dmesg.
  • TP8/DCP1/MTP0 NVFP4 A16 orig: decode 82.71 tok/s, prefill64k 5897 tok/s, KV 546752, no Xid.
  • TP8/DCP2/MTP0 NVFP4 A16 orig: decode 69.17 tok/s, prefill64k 5493 tok/s, KV 1038976, no Xid.
  • TP8/DCP4/MTP3 NVFP4 A16 online MXFP8: decode 118.58 tok/s, prefill64k 5295 tok/s, KV 2097152, no Xid.
  • TP6/DCP6/MTP3 MXFP4 A8 online MXFP8: decode 76.57 tok/s, prefill64k 2372 tok/s, KV 1459736, no Xid.

The DCP1 check is the important regression gate for the previous .contiguous() fix: the producer-tail-padding path avoids that hot-path slowdown.

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (1)
  • dev/*

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: fbc05c56-2d61-4eb6-9c5d-ebd85c7944da

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds cuBLAS tail-padding utilities and propagates tail-padding requirements through unquantized and MXFP8 linear layers, MLA attention, and DCP A2A reductions. Tests cover value preservation, contiguous buffers, CUDA graphs, storage-tail contracts, and parameter forwarding.

Changes

cuBLAS storage and linear execution

Layer / File(s) Summary
Storage utilities and tail-padded GEMM
vllm/utils/cublas.py, vllm/model_executor/layers/utils.py, vllm/model_executor/layers/linear.py, tests/model_executor/layers/test_unquantized_linear_tail_padding.py
Adds storage-tail allocation and validation helpers, registers tail_padded_unquantized_gemm, and routes bias-free unquantized linear layers through the new operation when configured.
DCP reduction output handling
vllm/v1/attention/ops/dcp_alltoall.py, vllm/v1/attention/ops/common.py, tests/distributed/test_dcp_a2a.py
Adds tail_pad_output to DCP reduction paths, allocates tail-padded outputs, and tests contiguous buffers and storage-tail requirements.
MLA tail-padding integration
vllm/v1/attention/backends/mla/b12x_mla_sparse.py, vllm/model_executor/layers/attention/mla_attention.py, vllm/model_executor/layers/mla.py
Configures the B12X MLA tail-padding size and applies it to MLA BMM inputs, projections, and DCP reduction calls.
B12X MXFP8 forwarding
vllm/model_executor/kernels/linear/mxfp8/b12x.py, tests/model_executor/kernels/test_b12x_mxfp8_linear.py
Passes output_tail_padding_bytes to the MXFP8 backend and verifies the value in eager and forward-context tests.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant B12xMLASparseImpl
  participant MLAAttention
  participant CUBLASTailPadding
  participant DCPReduction
  B12xMLASparseImpl->>MLAAttention: configure MLA tail padding
  MLAAttention->>CUBLASTailPadding: pad BMM inputs when required
  MLAAttention->>DCPReduction: request tail-padded reduction output
  DCPReduction-->>MLAAttention: return tail-padded output
Loading

Possibly related PRs

Suggested reviewers: lukealonso

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 46.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately reflects the main change: adding tail padding for cuBLAS BMM inputs in MLA paths.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/gg-dcp-output-tail-padding-20260720

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
vllm/utils/cublas.py (1)

30-41: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add strict=True to the zip() call.

tensor.shape and tensor.stride() are always equal length, so this is functionally safe, but Ruff (B905) flags it and it's a one-line fix.

🔧 Proposed fix
         last_item = tensor.storage_offset() + sum(
-            (size - 1) * stride for size, stride in zip(tensor.shape, tensor.stride())
+            (size - 1) * stride
+            for size, stride in zip(tensor.shape, tensor.stride(), strict=True)
         )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@vllm/utils/cublas.py` around lines 30 - 41, Update the zip call in
storage_tail_bytes to pass strict=True when pairing tensor.shape with
tensor.stride(), leaving the surrounding storage-tail calculation unchanged.

Source: Linters/SAST tools

vllm/v1/attention/backends/mla/b12x_mla_sparse.py (1)

976-982: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Tail-padding byte count is decoupled from the configured value across files. The MLA backend configures mla_bmm_tail_padding_bytes (a literal 64 * 1024 in b12x_mla_sparse.py), but only a boolean tail_pad_output flag is propagated through dcp_a2a_lse_reduce/cp_lse_ag_out_rs; every consumer independently re-derives the padding size from the module-level CUBLAS_BMM_TAIL_PADDING_BYTES default in vllm/utils/cublas.py. This is correct today only because both literals coincidentally match — any future divergence (e.g. a backend needing a different tail size) would silently apply the wrong padding amount, risking exactly the cuBLAS unmapped-read/Xid hazard this PR sets out to fix.

  • vllm/v1/attention/backends/mla/b12x_mla_sparse.py#L976-L982: import and reuse CUBLAS_BMM_TAIL_PADDING_BYTES from vllm.utils.cublas instead of the literal 64 * 1024, and consider threading the actual byte value (not just a bool) through the downstream calls.
  • vllm/v1/attention/ops/dcp_alltoall.py#L294-L304: accept the actual tail-padding byte count from the caller (or a module-shared constant import) instead of hardcoding CUBLAS_BMM_TAIL_PADDING_BYTES in the tail_padded_empty call.
  • vllm/v1/attention/ops/dcp_alltoall.py#L876-L892: same fix for the _dcp_a2a_unpack_combine allocation.
  • vllm/v1/attention/ops/common.py#L227-L247: pass the configured byte count into ensure_cublas_tail_padding instead of relying on its default.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@vllm/v1/attention/backends/mla/b12x_mla_sparse.py` around lines 976 - 982,
Use one configured tail-padding byte count throughout the MLA path instead of
independently re-deriving the default. In
vllm/v1/attention/backends/mla/b12x_mla_sparse.py#L976-L982, initialize
mla_bmm_tail_padding_bytes from CUBLAS_BMM_TAIL_PADDING_BYTES and propagate the
value through downstream calls. Update
vllm/v1/attention/ops/dcp_alltoall.py#L294-L304 and `#L876-L892` so
tail_padded_empty and _dcp_a2a_unpack_combine receive and use the caller’s byte
count, and update vllm/v1/attention/ops/common.py#L227-L247 to pass that
configured value to ensure_cublas_tail_padding instead of relying on its
default.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@vllm/utils/cublas.py`:
- Around line 30-41: Update the zip call in storage_tail_bytes to pass
strict=True when pairing tensor.shape with tensor.stride(), leaving the
surrounding storage-tail calculation unchanged.

In `@vllm/v1/attention/backends/mla/b12x_mla_sparse.py`:
- Around line 976-982: Use one configured tail-padding byte count throughout the
MLA path instead of independently re-deriving the default. In
vllm/v1/attention/backends/mla/b12x_mla_sparse.py#L976-L982, initialize
mla_bmm_tail_padding_bytes from CUBLAS_BMM_TAIL_PADDING_BYTES and propagate the
value through downstream calls. Update
vllm/v1/attention/ops/dcp_alltoall.py#L294-L304 and `#L876-L892` so
tail_padded_empty and _dcp_a2a_unpack_combine receive and use the caller’s byte
count, and update vllm/v1/attention/ops/common.py#L227-L247 to pass that
configured value to ensure_cublas_tail_padding instead of relying on its
default.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 669869ef-c8f8-4ea6-9edf-6d51ed408b20

📥 Commits

Reviewing files that changed from the base of the PR and between 433b4ac and 1905e2e.

📒 Files selected for processing (12)
  • tests/distributed/test_dcp_a2a.py
  • tests/model_executor/kernels/test_b12x_mxfp8_linear.py
  • tests/model_executor/layers/test_unquantized_linear_tail_padding.py
  • vllm/model_executor/kernels/linear/mxfp8/b12x.py
  • vllm/model_executor/layers/attention/mla_attention.py
  • vllm/model_executor/layers/linear.py
  • vllm/model_executor/layers/mla.py
  • vllm/model_executor/layers/utils.py
  • vllm/utils/cublas.py
  • vllm/v1/attention/backends/mla/b12x_mla_sparse.py
  • vllm/v1/attention/ops/common.py
  • vllm/v1/attention/ops/dcp_alltoall.py

(cherry picked from commit 1905e2e)
@voipmonitor
voipmonitor force-pushed the fix/gg-dcp-output-tail-padding-20260720 branch from 1905e2e to 4a14a60 Compare July 20, 2026 18:52
@voipmonitor
voipmonitor changed the base branch from dev/gilded-gnosis to fix/gg-pcie-capture-isolation-clean-stacked-20260720 July 20, 2026 18:53
@voipmonitor

Copy link
Copy Markdown
Author

Superseded by the head-major output contract in #147 together with local-inference-lab/sparkinfer#54. That solution passed the guarded cuBLAS reproduction and DCP1/DCP2/DCP4 validation without the KV-capacity and hot-path costs of generic tail padding.

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