[TRTLLM-11508][refactor] Merge Eagle3 and MTP-eagle one-model workers - #12353
Conversation
98b1417 to
9f923d9
Compare
|
/bot run |
|
PR_Github #39589 [ run ] triggered by Bot. Commit: |
|
PR_Github #39589 [ run ] completed with state
|
9f923d9 to
01b1fe7
Compare
|
/bot run |
|
PR_Github #39733 [ run ] triggered by Bot. Commit: |
|
PR_Github #39733 [ run ] completed with state
|
01b1fe7 to
5a1ef63
Compare
|
/bot run |
|
PR_Github #39814 [ run ] triggered by Bot. Commit: |
|
PR_Github #39814 [ run ] completed with state
|
|
/bot run |
|
PR_Github #39819 [ run ] triggered by Bot. Commit: |
|
PR_Github #39819 [ run ] completed with state
|
|
/bot run |
|
PR_Github #39828 [ run ] triggered by Bot. Commit: |
|
PR_Github #39828 [ run ] completed with state
|
7e82c9c to
f4f8ac6
Compare
|
/bot run |
|
PR_Github #40431 [ run ] triggered by Bot. Commit: |
|
PR_Github #40431 [ run ] completed with state
|
8ed37a4 to
67e4428
Compare
Eagle3OneModelWorker on the MTP Eagle path consumes the target model's
hidden_states argument directly (prepare_1st_drafter_inputs and
_run_draft_forward both gate the spec_metadata.hidden_states read on
not is_mtp_eagle), so the layer-capture machinery is never read.
Configuring layers_to_capture={last} for MTP_EAGLE_ONE_MODEL still had
two visible side effects:
- modeling_deepseekv3 / modeling_glm / modeling_gpt_oss disable
POST_MOE_FUSION / POST_MLP_FUSION whenever spec_metadata.is_layer_capture(
layer_idx) is true. MTP Eagle paid that cost despite never using the
capture.
- Eagle3OneModelSpecMetadata allocated a (max_num_tokens, hidden_size)
hidden_states buffer (and Eagle3ResourceManager pre-allocated one too)
that the MTP Eagle worker never reads.
Opt out of capture for MTP_EAGLE_ONE_MODEL:
- MTPDecodingConfig.num_capture_layers returns 0 for one-model (1 stays
for two-model MTP_EAGLE, which still feeds captured hidden states into
the separate draft engine).
- Eagle3OneModelSpecMetadata.__post_init__ defaults layers_to_capture to
() for MTP_EAGLE_ONE_MODEL and skips the hidden_states allocation.
- get_spec_metadata() stops passing layers_to_capture={last} on the
MTP_EAGLE_ONE_MODEL branch and lets the metadata default kick in.
With layers_to_capture empty, is_layer_capture() is false for every
layer and maybe_capture_hidden_states() is a no-op for-loop, so post-MLP
/ post-MoE fusion stays enabled and no capture buffer is allocated.
Signed-off-by: ZhaoyangWang <zhaoyangw@nvidia.com>
Bundle of small fixes from the merge-eagle-mtp PR review:
- Drop the historical `kv_lens_cuda` save/restore NOTE in
`Eagle3OneModelWorker._prepare_attn_metadata_for_spec_dec()`. The note
was internal context for the merge commit and is not useful as inline
documentation of the current state.
- Remove the `if self.is_mtp_eagle:` gate around the Mamba-hybrid state
update in `Eagle3OneModelWorker.forward()`. The
`isinstance(kv_cache_manager, MambaHybridCacheManager)` check already
no-ops on non-Mamba caches, so spec-mode gating was unnecessary and
would prevent Eagle3 from picking up Mamba support if a Mamba-style
Eagle draft ever lands.
- Delete the `__getattr__` backward-compat shim in `mtp.py` that
re-exported `MTPEagleWorker` from `eagle3.py`. No in-tree caller
imports `MTPEagleWorker` from `tensorrt_llm._torch.speculative.mtp`
anymore (both `speculative/__init__.py` and `speculative/utils.py`
import it directly from `.eagle3`).
- Drop the relaxed-acceptance fields
(`use_relaxed_acceptance_for_thinking`, `relaxed_topk`,
`relaxed_delta`, `begin_thinking_phase_token`,
`end_thinking_phase_token`) from `EagleDecodingConfig`. The unified
worker's relaxed-acceptance branch is already guarded by
`getattr(spec_config, 'use_relaxed_acceptance_for_thinking', False)`,
so an `EagleDecodingConfig` without these fields naturally short-
circuits the path. `MTPDecodingConfig` keeps the same fields
unchanged. Limits the user-facing surface of relaxed acceptance to
the MTP family, per review preference (relaxed acceptance degrades
the spec-dec output distribution and is questionable for Eagle).
- Rewrite the "Eagle engine takes ``draft_len`` tokens" comment in
`_forward_linear_draft_loop()` to mention both Eagle3 and MTP Eagle,
matching the unified worker that path now drives.
- Expand the comment around the `num_tokens` subtract in
`Eagle3OneModelSpecMetadata.prepare()` to explain that the value is
consumed only by the attention-DP allgather in `model_engine`, that
both modes share `prepare_1st_drafter_inputs()` and therefore feed
the same input_ids tensor to the kernel, and that the subtract
asymmetry exists solely to preserve the pre-refactor shape-hint
convention of each mode. The previous wording ("MTP Eagle uses
max_draft_len + 1 tokens... Eagle3 follows the standard tree/linear
path") incorrectly implied an input-shape difference.
Signed-off-by: ZhaoyangWang <zhaoyangw@nvidia.com>
Factor the duplicated spec_metadata distributed-token-count assignments (all_rank_num_tokens, all_rank_num_seqs, and the Eagle3/MTP-eagle one-model subseq_all_rank_num_tokens) into a shared helper _set_spec_metadata_all_rank_num_tokens, called from _apply_incremental_update, _prepare_tp_inputs, and _prepare_tp_inputs_no_cache. Signed-off-by: ZhaoyangWang <zhaoyangw@nvidia.com>
fde907a to
9051c11
Compare
|
/bot run |
|
PR_Github #51578 [ run ] triggered by Bot. Commit: |
|
PR_Github #51578 [ run ] completed with state
|
|
/bot run |
1 similar comment
|
/bot run |
|
PR_Github #51718 [ run ] triggered by Bot. Commit: |
|
PR_Github #51718 [ run ] completed with state
|
|
/bot run |
|
PR_Github #51777 [ run ] triggered by Bot. Commit: |
|
PR_Github #51777 [ run ] completed with state
|
|
/bot run |
|
PR_Github #51934 [ run ] triggered by Bot. Commit: |
|
PR_Github #51934 [ run ] completed with state |
…NVIDIA#12353) Signed-off-by: ZhaoyangWang <zhaoyangw@nvidia.com> Signed-off-by: NVFB <186336021+NVFB@users.noreply.github.com>
…NVIDIA#12353) Signed-off-by: ZhaoyangWang <zhaoyangw@nvidia.com>
…revert Remove all 14 deepseek-v32-fp4 perf-sanity test waivers (nvbugs 6280721, 6280649, 6085022, 6200257). These were skipped due to the gen-server CUDA-graph capture crash introduced by NVIDIA#12353, which is reverted in this branch, so the cases can run again.
…DIA#12353)" This reverts commit 8e5d9e2 (NVIDIA#12353). The MTP-eagle / Eagle3 one-model worker merge regresses the GB200 2-node disagg perf-sanity gen-only test: test_perf_sanity.py::test_e2e[disagg_upload-gen_only- gb200_deepseek-v32-fp4_1k1k_con2048_ctx1_dep4_gen1_dep4_eplb0_mtp1_ccb-NIXL] The GEN server (MTP speculative decoding, num_nextn_predict_layers=1) crashes during executor init while capturing the generation-phase CUDA graphs: _run_cuda_graph_warmup -> _capture_generation_cuda_graphs -> torch.cuda.synchronize() torch.AcceleratorError: CUDA error: unspecified launch failure All 4 gen ranks abort (exit 134). Bisect between the last passing post-merge commit (33b0a32) and the first failing one (316430f) isolates NVIDIA#12353 as the only change touching the spec-decode / model_engine CUDA-graph capture path; the remaining commits in the range are AutoDeploy, test, and infra changes. Reverting restores the gen server startup and unblocks the perf-sanity test. Signed-off-by: Chenfei Zhang <chenfeiz@nvidia.com>
…revert Remove all 14 deepseek-v32-fp4 perf-sanity test waivers (nvbugs 6280721, 6280649, 6085022, 6200257). These were skipped due to the gen-server CUDA-graph capture crash introduced by NVIDIA#12353, which is reverted in this branch, so the cases can run again. Signed-off-by: Chenfei Zhang <chenfeiz@nvidia.com>
Resolve conflicts in speculative decoding introduced by upstream's "[TRTLLM-11508][refactor] Merge Eagle3 and MTP-eagle one-model workers" (NVIDIA#12353): - interface.py support_dynamic_draft_len(): take the union of both sides' mode lists (this PR's is_mtp_one_model/is_pard/is_dflash/ is_draft_target_one_model/is_sa plus upstream's is_mtp_eagle_one_model). - mtp.py: drop the local MTPEagleWorker. Upstream moved it to eagle3.py as a thin subclass of Eagle3OneModelWorker, which already implements the dynamic draft-length behavior this PR added; __init__.py/utils.py now import it from eagle3.py. - mtp.py change_attn_metadata(): upstream added a kv_lens_cuda clamp using its local mtp_num_modules, which this PR had renamed to runtime_draft_len; the auto-merge left a dangling reference, fixed to clamp(min=runtime_draft_len). Signed-off-by: Zheyu Fu <zheyuf@NVIDIA.com>
…-model merge #12353) Squashed probe equal to the tree of upstream commit 8e5d9e2 ([TRTLLM-11508][refactor] Merge Eagle3 and MTP-eagle one-model workers #12353), rebased onto its parent 910826b so CI builds exactly that commit's tree. Authored/signed-off by chenfeiz to satisfy DCO (original commit's signoff name did not match its author). Signed-off-by: chenfeiz <chenfeiz@nvidia.com>
Summary by CodeRabbit
Release Notes
Description
Unify
Eagle3OneModelWorker(Eagle3 one-model) andMTPEagleWorker(MTP-eagle one-model) into a single worker class in
tensorrt_llm/_torch/speculative/eagle3.py, branching onself.is_mtp_eagle = spec_dec_mode.is_mtp_eagle_one_model(). The twocode paths were ~85% duplicated; this PR collapses them into one
implementation while preserving backward-compatible imports.
MTPEagleWorkerbecomes a thin backward-compatible subclass ineagle3.py.mtp.pyretains a module-level__getattr__shim sofrom tensorrt_llm._torch.speculative.mtp import MTPEagleWorkercontinues to resolve.
Key changes
eagle3.py): new helpers_get_step_all_rank_num_tokens,_run_draft_forward,_prepare_flash_mla_generation_layout,draft_sampler(TP-aware);sample_and_accept_draft_tokensgains aninput_idsparameter andthe relaxed-thinking acceptance path previously exclusive to
MTPEagleWorker.Eagle3OneModelSpecMetadata): new fieldsslot_idsandsubseq_all_rank_num_tokens.prepare()skipsnum_tokenssubtraction for MTP-eagle and populatesslot_idsfromthe resource manager.
Eagle3ResourceManagerowns the relaxed-acceptancerelaxed_delta_poolso the Eagle3 path can also use thinking-phaserelaxed acceptance.
Eagle3DraftModel.forwardtakes an optionalall_rank_num_tokenskwarg and wraps its body in try/finally thatrestores
attn_metadata.all_rank_num_tokenson exit — the workerloop no longer mutates
attn_metadatafor Eagle3.EagleDecodingConfiggains the five relaxed-acceptance fieldsmirrored from
MTPDecodingConfig.SpeculativeDecodingMode.is_mtp_one_model()is narrowed tovanilla MTP only;
MTP_EAGLE_ONE_MODELbecomes a first-classone-model mode in
use_one_engine,without_logits,needs_kv_cache_rewind,support_overlap_scheduler,support_capturable_guided_decoder,support_dynamic_draft_len,has_spec_decoder. Per-model checks inmodeling_deepseekv3,modeling_glm,modeling_exaone_moe,modeling_nemotron_h,modeling_qwen3_next,modeling_speculative, andmodel_configare extended accordingly.
utils.py) routesMTP_EAGLE_ONE_MODELtoEagle3OneModelSpecMetadata,Eagle3OneModelSampler,Eagle3ResourceManager, and the unified worker.model_engine.pypopulatesspec_metadata.subseq_all_rank_num_tokensfor both Eagle3 andMTP-eagle one-model at all three attention-DP allgather sites.
Test Coverage
PR Checklist
Please review the following before submitting your PR:
PR description clearly explains what and why. If using CodeRabbit's summary, please make sure it makes sense.
PR Follows TRT-LLM CODING GUIDELINES to the best of your knowledge.
Test cases are provided for new code paths (see test instructions)
Any new dependencies have been scanned for license and vulnerabilities
CODEOWNERS updated if ownership changes
Documentation updated as needed
Update tava architecture diagram if there is a significant design change in PR.
The reviewers assigned automatically/manually are appropriate for the PR.
Please check this after reviewing the above items as appropriate for this PR.
GitHub Bot Help
To see a list of available CI bot commands, please comment
/bot help.