Skip to content

[CUDA] Add SpeculativePrefixCommit contrib operator - #33474

Open
Akshay Sonawane (apsonawane) wants to merge 17 commits into
mainfrom
asonawane/main-ops-mtp-fold-state
Open

Akshay Sonawane (apsonawane) wants to merge 17 commits into
mainfrom
asonawane/main-ops-mtp-fold-state

Conversation

@apsonawane

@apsonawane Akshay Sonawane (apsonawane) commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Description

Adds the com.microsoft::SpeculativePrefixCommit (opset 1) CUDA contrib operator for single-launch device-side speculative prefix verification, control/context state commit, and result-ring publication across $3 \le S \le 8$ verification rows ($B \ge 1$). The operator runs entirely on the device with zero host synchronization or dynamic allocation so it can be captured and replayed inside a CUDA Graph.

Summary of Changes

com.microsoft::SpeculativePrefixCommit Schema & CUDA Kernel

File Change
onnxruntime/core/graph/contrib_ops/bert_defs.cc, ms_opset.h Registers com.microsoft::SpeculativePrefixCommit(1) with attribute head_rows (3..8, default 8), 7 inputs (next_tokens, input_ids, status, ctl, ctx_commit, prefixes, ptrs), and 3 required outputs (head_c, updated_ctl, updated_ctx_commit), enforcing rank 1 ([rows]) or rank 2 ([batch, rows]) on next_tokens and propagating head_c shape [batch] only when next_tokens has a known shape
onnxruntime/contrib_ops/cuda/cuda_contrib_kernels.cc, onnxruntime/contrib_ops/cuda/llm/speculative_fold.{h,cc,cu} Implements SpeculativePrefixCommit (MayInplace(3, 1) and MayInplace(4, 2)), launching one thread per batch item (PrefixCommitKernel) to match verifier predictions against draft tokens (input_ids[b, 1:rows]), write the updated 16-word control state (updated_ctl) and 2-word context pair (updated_ctx_commit) in-place or to disjoint output buffers, and publish an 8-word record to the per-request result ring after __threadfence_system()

Tests and Documentation

  • onnxruntime/test/contrib_ops/cuda_kernels/speculative_fold_test.cc, cmake/onnxruntime_unittests.cmake: Kernel-level tests (FoldContribTest.*) covering all accepted prefix lengths for head_rows in {3, 4, 8}, in-place and disjoint state output buffers, multi-batch per-item state and result-ring progression, muted prefill (ctl[3] != 0), invalid metadata / ring validation flags (ctl[5]), verifier status aggregation, and CUDA Graph capture/replay.
  • onnxruntime/test/contrib_ops/speculative_fold_op_test.cc: Session-level tests (SpeculativeFoldTest.*) covering batched $S=8$ commits through InferenceSession, multi-run state progression carrying updated_ctl / updated_ctx_commit across Run calls, muted prefill with variable row counts, shape inference with known and unknown next_tokens shapes, and rejection of invalid next_tokens ranks, missing required state outputs, or partially overlapping buffers.
  • docs/ContribOperators.md, docs/OperatorKernels.md, docs/contrib_ops/cuda/speculative_fold.md: Regenerates schema/kernel tables and documents the operator interface, state aliasing contract, result-ring layout, error flags, and graph wiring.

Testing

  • Run provider unit tests:
    onnxruntime_provider_test --gtest_filter="FoldContribTest.*:SpeculativeFoldTest.*"
  • End-to-end verification on qwen_flash_next_int4_int8_rc3_contrib_dflash2 ($S=8$ DFlash2 speculative decoding).

Checklist

  • Tests added/updated
  • No breaking changes (or documented in description)
  • Documentation updated (if applicable)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Unresolved memory-safety, state-propagation, uninitialized-output, and documentation-validation issues block approval.

6 open issues
What changed in this PR

Adds CUDA contrib operators for multi-token prediction and speculative decoding directly on main, replacing the earlier stacked PR.

Changes:

  • Implements NVFP4 MtpMoe projections and FoldMid2/FoldTail state updates.
  • Adds schemas, CUDA registrations, and operator documentation.
  • Adds internal kernel tests; fresh GPU execution remains outstanding.
File Description
onnxruntime/​test/​contrib_ops/​cuda_kernels/​speculative_fold_test.cc Tests acceptance, state updates, and muted calls.
onnxruntime/​test/​contrib_ops/​cuda_kernels/​mtp_moe_test.cc Tests routing and reference projection arithmetic.
onnxruntime/​core/​graph/​contrib_ops/​ms_opset.h Registers the three schemas.
onnxruntime/​core/​graph/​contrib_ops/​contrib_defs.cc Defines operator contracts and types.
onnxruntime/​contrib_ops/​cuda/​llm/​speculative_fold.h Declares fold launchers.
onnxruntime/​contrib_ops/​cuda/​llm/​speculative_fold.cu Implements speculative state kernels.
onnxruntime/​contrib_ops/​cuda/​llm/​speculative_fold.cc Adds fold validation and CUDA wrappers.
onnxruntime/​contrib_ops/​cuda/​llm/​mtp_moe.h Defines dimensions and launcher interfaces.
onnxruntime/​contrib_ops/​cuda/​llm/​mtp_moe.cu Implements routing and expert projections.
onnxruntime/​contrib_ops/​cuda/​llm/​mtp_moe.cc Adds validation and output allocation.
onnxruntime/​contrib_ops/​cuda/​cuda_contrib_kernels.cc Registers CUDA implementations.
docs/​ContribOperators.md Documents the new operators.
cmake/​onnxruntime_unittests.cmake Includes internal tests and kernel sources.

Review effort: Balanced

Comment thread docs/ContribOperators.md Outdated
Comment thread onnxruntime/contrib_ops/cuda/llm/mtp_moe.cc Outdated
Comment thread onnxruntime/contrib_ops/cuda/llm/mtp_moe.cu Outdated
Comment thread onnxruntime/contrib_ops/cuda/llm/speculative_fold.cc Outdated
Comment thread onnxruntime/contrib_ops/cuda/llm/speculative_fold.cu Outdated
Comment thread onnxruntime/contrib_ops/cuda/llm/speculative_fold.cu Outdated
Keep router expert indices valid for non-finite logits, initialize the public scratch buffer, return fold state through declared reusable outputs, and guard rotary and ring metadata before committing. Add session-level and kernel regressions and regenerate operator documentation.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Comment thread docs/ContribOperators.md Outdated
Comment thread onnxruntime/contrib_ops/cuda/llm/mtp_moe.cu Outdated
@apsonawane

Copy link
Copy Markdown
Contributor Author

Pushed 24625bf to address both outstanding review threads and the common root cause of all six failed CUDA/TensorRT/plugin pipelines.

  • Fixed speculative-fold session test compilation: explicitly include the status assertion header and reuse typed output names for the gsl::span-based Run overload in all three calls.
  • Restore experimental operators to the correct support-level group in the generated documentation TOC.
  • Validate the documented MtpMoe 1–65535 row range before output allocation and before any low-level CUDA access; add boundary regressions.

Validation: full-PR lintrunner apply/check-only passes, git diff --check passes, affected schema/kernel documentation matches the official Python renderer with source-derived metadata, entire TOC support-level/name ordering passes, and static validation placement checks pass.

No local builds or compilation were run. The new native tests were not executed locally. Fresh CI is triggered by this push and is not claimed green.

Preserve FoldMid2/FoldTail v1, add explicit aliased state outputs and deferred ring publication, and cover S1-S4 acceptance and captured replay.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ty, optional in-place ctl/ctx) and remove unused MtpMoe

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@tianleiwu
Tianlei Wu (tianleiwu) force-pushed the asonawane/main-ops-mtp-fold-state branch from efa5ab5 to a602c0c Compare October 23, 2026 23:39
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@tianleiwu Tianlei Wu (tianleiwu) changed the title Add fused MTP MoE and speculative state fold CUDA operators [CUDA] Add FoldMid2 and FoldTail speculative state fold contrib operators Oct 24, 2026
…hema docs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ification)

- Widen FoldMid2 head_rows attribute and shape inference from 2..4 to 2..8, and FoldTail ctl_slot to {-1, 2, 8..13}.
- Pack tokens[4..7] into the upper 32-bit halves of ring record words 1, 2, 3, and 5 while preserving the 8-word (64-byte) ring record layout and S<=4 compatibility.
- Extend FoldContribTest to verify 8-row prefix acceptance, upper-32-bit token packing, and ctl_slot=13.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Tianlei Wu (tianleiwu) added a commit that referenced this pull request Oct 24, 2026
…2 QMoE, and PR cleanups

- Extend FoldMid2/FoldTail to head_rows<=8 and pack tokens[4..7] into ring record words 1, 2, 3, and 5.
- Add state_update_capacity (0..8) support to CausalConvWithState and enable state_update_capacity > 0 in QwenS2 GatedDeltaNetDecodeWarpKernel.
- Raise kMaxProfiledExpandedRows to 80 in moe_gemv.h and kFusedRouteMaxRows to 8 in qmoe_fused_route.cuh; add fast INT3 and offline SM80 INT2/INT4 prepack QMoE support.
- Eliminate pq[8][ROWS] local register array in HcUpPreKernel and sync PR cleanups (#33469, #33470, #33471, #33472, #33474, #33548, #33569).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@tianleiwu
Tianlei Wu (tianleiwu) marked this pull request as draft October 24, 2026 23:17
auto-merge was automatically disabled October 24, 2026 23:18

Pull request was converted to draft

…veStepPublish

- Rename com.microsoft::FoldMid2 to com.microsoft::SpeculativePrefixCommit
  and com.microsoft::FoldTail to com.microsoft::SpeculativeStepPublish so
  the public schema names describe speculative prefix verification/commit and
  step publication rather than internal graph topology.
- Update ContribOperators.md, OperatorKernels.md, speculative_fold.md, and
  speculative_fold_op_test.cc accordingly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@tianleiwu Tianlei Wu (tianleiwu) changed the title [CUDA] Add FoldMid2 and FoldTail speculative state fold contrib operators [CUDA] Add SpeculativePrefixCommit and SpeculativeStepPublish contrib operators Oct 25, 2026
… SpeculativePrefixCommit

- Remove unused com.microsoft::SpeculativeStepPublish (formerly FoldTail) operator, TailKernel, and LaunchTail.
- Remove unused hidden/head_hidden padding path (HiddenKernel) from SpeculativePrefixCommit and always publish the ring record directly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@tianleiwu Tianlei Wu (tianleiwu) changed the title [CUDA] Add SpeculativePrefixCommit and SpeculativeStepPublish contrib operators [CUDA] Add SpeculativePrefixCommit contrib operator Oct 25, 2026
@tianleiwu
Tianlei Wu (tianleiwu) marked this pull request as ready for review October 25, 2026 05:37
### Summary
Extends com.microsoft::SpeculativePrefixCommit (introduced in #33474) to
support batch_size >= 1 for batched speculative decoding:
- Schema and shape inference (bert_defs.cc): Propagates the batch
dimension from next_tokens ([batch, rows] or [rows]) to outputs 0..6
(head_ids, head_c, slot_ids, seqlens, cos_out, sin_out, sel).
- CUDA kernel (speculative_fold.h/.cc/.cu): Launches
MidKernel<<<batch_size, 256, 0, stream>>> with per-slot strides for ctl,
ctx_commit, prefixes, prefix2, per-slot result ring buffers, and
per-slot muted flags.
- Unit test (speculative_fold_op_test.cc): Adds
SupportsBatchedSpeculativePrefixCommitS8 covering batch = 3, head_rows =
8 with mixed acceptance lengths and a muted slot.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

State propagation and unknown-batch shape inference have correctness issues, and generated documentation does not match the schema.

3 open issues
2 resolved since last review

Review effort: Balanced

Comment thread onnxruntime/core/graph/contrib_ops/bert_defs.cc Outdated
Comment thread onnxruntime/core/graph/contrib_ops/bert_defs.cc Outdated
Comment thread docs/ContribOperators.md Outdated
Comment thread onnxruntime/contrib_ops/cuda/llm/speculative_fold.cc Outdated
Comment thread onnxruntime/contrib_ops/cuda/llm/speculative_fold.cc Outdated
…pdated-state outputs

Remove inputs, outputs, attributes and modes that the Qwen3.8-Flash-Next rc3
graph and the GenAI runtime do not consume:
- rotary gather path (cos_cache/sin_cache inputs, cos_out/sin_out outputs),
  head-preparation outputs (head_ids, slot_ids, seqlens, sel)
- redundant prefix2 input (duplicates prefixes[2..3]) and the size-2*batch
  ptrs layout (GenAI always passes {ring address, ring size})
- head_capacity attribute and the cache-capacity/rotary error bits
- legacy head_rows 2 layout (8-word ctl, 2-word prefixes), the rows < head_rows
  clamp and the always-true publish_ring parameter

updated_ctl and updated_ctx_commit are now required outputs that the kernel
always writes (unchanged words are copied when the output does not alias the
input), so state is never mutated through const_cast and a CPU-backed feed can
no longer lose the update while a ring record is published. The kernel now runs
one thread per batch item.

Schema inference leaves the batch dimension unknown unless next_tokens has a
known shape, and both inference and the kernel reject next_tokens ranks other
than 1 and 2. head_rows defaults to 8 and must be in [3, 8].

Tests cover aliased and separate state outputs, batched per-item ring/state,
muted prefill, invalid metadata, state carried across session runs, rank-3
rejection and shape inference.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Update docs/ContribOperators.md and docs/OperatorKernels.md to match the pruned
schema (7 inputs, 3 required outputs, head_rows in [3, 8]) and rewrite
docs/contrib_ops/cuda/speculative_fold.md to describe the final operator
(interface, state/aliasing contract, result ring layout, muted/error handling,
graph wiring and tests) instead of the removed hidden-row, rotary and S1-S4 paths.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

This branch has not been deployed

No deployments
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.

3 participants