Configure MTP models for paged runtime decoding - #2494
Open
Tianlei Wu (tianleiwu) wants to merge 11 commits into
Open
Configure MTP models for paged runtime decoding#2494Tianlei Wu (tianleiwu) wants to merge 11 commits into
Tianlei Wu (tianleiwu) wants to merge 11 commits into
Conversation
This was referenced Aug 28, 2026
Tianlei Wu (tianleiwu)
force-pushed
the
tlwu/20260828/runtime-mtp-config
branch
from
August 29, 2026 00:02
89e252b to
7bf9f3b
Compare
Tianlei Wu (tianleiwu)
force-pushed
the
tlwu/20260828/runtime-mtp-config
branch
from
August 29, 2026 08:51
7bf9f3b to
401cce5
Compare
Tianlei Wu (tianleiwu)
force-pushed
the
tlwu/20260828/runtime-mtp-config
branch
from
August 29, 2026 17:03
401cce5 to
81ef6a1
Compare
Tianlei Wu (tianleiwu)
marked this pull request as ready for review
August 29, 2026 17:04
Contributor
There was a problem hiding this comment.
Pull request overview
This PR wires Multi-Token Prediction (MTP) model metadata into the paged/runtime decoding path so the dynamic-batch engine can run an internal “MTP head” session, and it optionally binds a packed hidden_states decoder output that the MTP drafting loop consumes.
Changes:
- Add
CreateMtpDecoderConfigto projectmodel.mtpmetadata into an internal decoder config suitable for paged decoding. - Extend
VarlenDecoderIO/ CUDA-graph buffer holders to optionally bind an exportedhidden_statesoutput ([packed tokens, hidden_size]). - Add a targeted unit test validating that the projection preserves the paged-attention contract while stripping main-model fixed/sliding state.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/config.h |
Declares CreateMtpDecoderConfig for projecting model.mtp into a decoder-config view. |
src/config.cpp |
Implements CreateMtpDecoderConfig and resets main-model-only decoder state for the MTP projection. |
src/engine/decoders/varlen_decoder_io.h |
Documents and exposes optional packed hidden-states output access on VarlenDecoderIO. |
src/engine/decoders/varlen_decoder_io.cpp |
Allocates/binds optional hidden_states output tensors (including CUDA-graph persistent buffers). |
test/cpp/mtp_config_test.cpp |
Adds a projection-focused unit test for paged MTP decoder configuration. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Tianlei Wu (tianleiwu)
force-pushed
the
tlwu/20260828/runtime-mtp-config
branch
from
August 29, 2026 22:02
81ef6a1 to
fc08ffe
Compare
Tianlei Wu (tianleiwu)
force-pushed
the
tlwu/20260828/runtime-mtp-config
branch
from
August 30, 2026 06:41
fc08ffe to
13d5696
Compare
RequestStepPlan carries a draft count, the composite planner turns any nonzero count into a checkpoint-capturing fixed reservation (and sizes its staging for it), and the hybrid decoder binds the checkpoints output only on such a step, so the operators skip writing it entirely otherwise. Nothing sets a draft count yet, so every step still plans and reserves exactly what it did before. (cherry picked from commit d4abc79)
(cherry picked from commit 0ff9d6d)
A model exported with include_hidden_states emits a [num_tokens, hidden_size] row per packed token alongside its logits. The Engine never bound it, so the paged path had no way to feed an MTP draft head, which consumes exactly that row for the last accepted token. Bind it whenever the config names it and the session actually has it, so every model exported without it runs a byte-identical step. The rows are sized by the packed token count rather than by the logits row count, because a pruned LM head emits only one logits row per request while the hidden states stay per token; PrepareLogits and PrepareHiddenStates now share a TokenCount helper so the two cannot drift apart. VarlenGraphBuffers gains a matching static buffer so a captured step keeps a stable output address. 315 engine unit tests pass, and the tiny paged fixture (now exported with include_hidden_states) still reports exact ragged-batch parity.
The paged Engine should host mtp.onnx directly rather than requiring callers to rewrite and load a second genai_config.json. CreateMtpDecoderConfig copies the main config so device, batching and packed-attention input names remain aligned, then replaces the filename/session options, dimensions, I/O names and shared initializers from model.mtp. The head is one full-attention layer, so the projection explicitly drops the main hybrid model's fixed state groups, convolution metadata and sliding-window state. A focused test verifies both the inherited paged contract and the removed main-model state; all six MtpConfigTest cases pass.
Tianlei Wu (tianleiwu)
force-pushed
the
tlwu/20260828/runtime-mtp-config
branch
from
August 30, 2026 20:19
13d5696 to
413ad82
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Project exported
model.mtpmetadata into the paged decoder configuration used by the dynamic batch engine. Also bind the optional packedhidden_statesdecoder output that chained MTP drafting consumes.This is a runtime-only change and does not depend on an ONNX Runtime package bump or include model-builder changes.
Stack
Depends on #2493.
Changes
hidden_statesoutput inVarlenDecoderIO.Testing
cmake --build build/Linux/Debugengine_unit_tests: 286 passed.