Repository navigation
[CUDA] Add SpeculativePrefixCommit contrib operator - #33474
Akshay Sonawane (apsonawane) wants to merge 17 commits into
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved memory-safety, state-propagation, uninitialized-output, and documentation-validation issues block approval.
6 open issues
Regenerate operator documentation from the updated build · New Initialize the complete public scratch output buffer · New Handle non-finite router logits without generating invalid expert indices · New Return updated fold state through explicit outputs · New Bound rotary-cache accesses to the actual cache extent · New Validate ring metadata before state commit or record access · New
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
MtpMoeprojections andFoldMid2/FoldTailstate 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
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.
There was a problem hiding this comment.
🟡 Changes recommended
Accepted row counts exceed CUDA launch limits, and documentation ordering conflicts with generator validation.
2 open issues
6 resolved since last review
Validate ring metadata before state commit or record access Bound rotary-cache accesses to the actual cache extent Return updated fold state through explicit outputs Handle non-finite router logits without generating invalid expert indices Initialize the complete public scratch output buffer Regenerate operator documentation from the updated build
Review effort: Balanced
|
Pushed 24625bf to address both outstanding review threads and the common root cause of all six failed CUDA/TensorRT/plugin pipelines.
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>
# Conflicts: # docs/ContribOperators.md
efa5ab5 to
a602c0c
Compare
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…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>
…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>
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>
… 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>
### 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>
…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>



Description
Adds the$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.
com.microsoft::SpeculativePrefixCommit(opset 1) CUDA contrib operator for single-launch device-side speculative prefix verification, control/context state commit, and result-ring publication acrossSummary of Changes
com.microsoft::SpeculativePrefixCommitSchema & CUDA Kernelonnxruntime/core/graph/contrib_ops/bert_defs.cc,ms_opset.hcom.microsoft::SpeculativePrefixCommit(1)with attributehead_rows(3..8, default8), 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]) onnext_tokensand propagatinghead_cshape[batch]only whennext_tokenshas a known shapeonnxruntime/contrib_ops/cuda/cuda_contrib_kernels.cc,onnxruntime/contrib_ops/cuda/llm/speculative_fold.{h,cc,cu}SpeculativePrefixCommit(MayInplace(3, 1)andMayInplace(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 forhead_rowsin{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 batchedInferenceSession, multi-run state progression carryingupdated_ctl/updated_ctx_commitacrossRuncalls, muted prefill with variable row counts, shape inference with known and unknownnext_tokensshapes, and rejection of invalidnext_tokensranks, 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
onnxruntime_provider_test --gtest_filter="FoldContribTest.*:SpeculativeFoldTest.*"qwen_flash_next_int4_int8_rc3_contrib_dflash2(Checklist