Skip to content

Optimize GDP Inference for GB200 - #7666

Closed
Waterpine wants to merge 7 commits into
NVIDIA:mainfrom
Waterpine:perf/gdp-inference-gb200
Closed

Waterpine wants to merge 7 commits into
NVIDIA:mainfrom
Waterpine:perf/gdp-inference-gb200

Conversation

@Waterpine

Copy link
Copy Markdown
Contributor
  • I, the PR author, have personally reviewed every line of this PR.

What does this PR do?

Improve GDP decode inference on GB200 by reducing redundant recurrent-path work and avoiding repeated transposed-weight copies in the batch-invariant Triton TE GEMM.

Changes

  • Compute GDP decay only for the first Householder update.
  • Zero padding outputs inside the recurrent kernel, removing a separate masked_fill operation.
  • Prefetch recurrent inputs for multi-token speculative decode.
  • Handle noncontiguous speculative decode outputs and projection padding.
  • Pass transposed weights directly to the stride-aware Triton GEMM without copying them on every forward.
  • Add bit-exact, CUDA-graph, and strided-weight tests, plus a reproducible GDP kernel benchmark.

Performance

Measurements use one GB200, batch size 32, BF16 inputs, and FP32 recurrent state.

GB200 GDP decode performance

The isolated recurrent-kernel benchmark compares the original main (80e5f8a) with this PR (bb8ee60). It uses FP32 recurrent state and 12 paired CUDA-graph runs per case.

Case Baseline p50 Optimized p50 Speedup
B=32, S=1 23.721 µs 19.467 µs 1.219×
B=32, S=4 81.576 µs 67.462 µs 1.209×

For the complete GDP mixer and decode step, unmodified main fails before timing in the global batch-invariant configuration. Their baseline is original main with only the runtime fixes needed to handle padded projection rows and non-contiguous speculative-decode output. The candidate is the full PR. Measurements use a fixed three-layer model, one GB200 per paired experiment, CUDA graphs, and FP32 recurrent state.

Case Measurement Baseline p50 Optimized p50 Speedup
B=32, S=1 Decode step 1628.433 µs 1496.369 µs 1.088×
B=32, S=1 GDP mixer 260.206 µs 104.170 µs 2.498×
B=32, S=4 Decode step 4794.273 µs 4126.704 µs 1.162×
B=32, S=4 GDP mixer 301.662 µs 151.673 µs 1.989×

The mixer results use four paired runs per case. The complete-step results use 24 paired runs for S=1 and eight for S=4; generated-token hashes matched across the paired complete-step runs.

The mixer and complete-step results measure the combined effect of the PR changes beyond the two runtime fixes. They should not be attributed solely to removal of the Triton TE weight copy. These measurements exercise the global batch-invariant Triton path; they do not measure the default te_native path.

Validation

  • GDP kernel tests: 264 passed.
  • Static/dynamic inference equivalence: 140 passed, including TP=2.
  • CUDA-graph end-to-end equality: 8 passed.
  • Bit-exact determinism: 8 passed and 2 XPASS; no failures or skips.
  • New GDP no-copy/CUDA-graph tests: 2 passed. The expanded strided-weight TE test passed all 15 cases.
  • FP32 output, cache, and snapshot comparisons matched bit for bit across 26 cases.
  • isort, black, and ruff checks passed on the edited files.

Issue tracking

Linked issue: N/A

Contribution process

Pre-checks

  • I have added relevant unit tests
  • I have added relevant functional tests
  • If this PR adds or changes a GPU kernel (Triton, jit_fuser/torch.compile, CUDA extension, TE or external-library dispatch, or a scatter/index accumulation), I have added or updated its bit-exact determinism test and registered it in tests/unit_tests/determinism/kernels/manifest.py (guide)
  • I have added proper typing to my code Typing guidelines
  • I have added relevant documentation
  • I have run the autoformatter.sh on my PR

Code review

Feel free to message or comment @NVIDIA/mcore-oncall to help accelerate your merge into main. The less complex your PR is, the faster it will be approved and merged!

All PRs start as draft. If you open a non-draft PR, it will be automatically converted to draft.

Step 1: Mark PR as "Ready for Review"

  1. When your PR is ready, click Ready for Review.
  2. An oncall reviewer is auto-assigned and expert reviewers are notified based on your changes.
    • Some PRs may jump straight to step 2. This is determined by .github/CODEOWNERS.

⚠️ Only mark as ready once merge-conflicts are resolved and the CI is passing.
Final Review might get declined if these requirements are not fulfilled.

Step 2: Final Review

For PRs that change megatron/core, once all expert reviewers have approved, the Final Review label is applied automatically and final reviewers are assigned.

For PRs outside megatron/core, this step is skipped.

Step 3: Approved

Once all required reviewers have approved, the Approved label is applied automatically.

Merge

Any member of mcore-engineers will be able to merge your PR.

Waterpine and others added 7 commits September 25, 2026 19:19
Compute the per-token decay only for the first Householder copy. Preserve
zero decay on later copies and the bitwise eager-reference output.

On GB200 at the 800M shape, CUDA-graph decode-preparation latency drops
from 3.07 to 2.86 us for one token and from 7.96 to 7.73 us for a
four-token speculative step. Add a reproducible graph benchmark and keep
the original determinism stress shape alongside the 800M shape.

Signed-off-by: Waterpine <biansonghz@gmail.com>
Write zero output for padding slots inside the Triton recurrence and remove the separate masked_fill launch. Preserve state and snapshot masking, and test non-finite padding buffers.

Restore token-only padding in dynamic SSM inference for the FA4 CUDA-graph path. Record exact source hashes in the graph benchmark.

On GB200, paired graph samples improve B=32 recurrent decode by 1.221x at S=1 and 1.065x at S=4. Kernel, dynamic, FA4 end-to-end, and determinism suites pass.

Signed-off-by: Waterpine <biansonghz@gmail.com>
Keep the retained loop for single-token decode and prefetch the next folded step when a decode call includes speculative tokens. Preserve the arithmetic order and bitwise outputs across padding, snapshots, static and dynamic slots, and CUDA graphs.

On GB200, paired graph samples improve B=32 S=4 recurrent latency by 1.134x versus the retained kernel, with B=32 S=1 unchanged. Kernel, dynamic inference, FA4 graph end-to-end, and determinism suites pass.

Signed-off-by: Waterpine <biansonghz@gmail.com>
Signed-off-by: Waterpine <songb@nvidia.com>
Signed-off-by: Waterpine <songb@nvidia.com>
Signed-off-by: Song B <songb@nvidia.com>
Signed-off-by: Waterpine <biansonghz@gmail.com>
@copy-pr-bot

copy-pr-bot Bot commented Sep 28, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@Waterpine
Waterpine requested review from a team as code owners September 28, 2026 04:17
@svcnvidia-nemo-ci
svcnvidia-nemo-ci marked this pull request as draft September 28, 2026 04:17
@github-actions

Copy link
Copy Markdown
Contributor

This PR has been automatically converted to draft because all PRs must start as drafts.

When you are ready for review, click Ready for Review to begin the review process. This will:

  1. Add the oncall reviewer (optional reviewer)
  2. Add required review teams based on your changes

See the contribution guide for more details.

@Waterpine Waterpine changed the title Perf/gdp inference gb200 gdp inference optimization over gb200 Sep 28, 2026
@Waterpine Waterpine changed the title gdp inference optimization over gb200 Optimize GDP Inference for GB200 Sep 28, 2026
@santhnm2 santhnm2 self-assigned this Sep 28, 2026
@santhnm2
santhnm2 self-requested a review September 28, 2026 04:43
@Waterpine

Copy link
Copy Markdown
Contributor Author

This PR is now covered by #7754, so I am closing it

@Waterpine Waterpine closed this Oct 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants