Skip to content

[Spec Decode] Add Qwen3 architecture support for EAGLE3 - #43132

Merged
vllm-bot merged 11 commits into
vllm-project:mainfrom
CentML:qwen-base-arch-eagle
Jun 21, 2026
Merged

[Spec Decode] Add Qwen3 architecture support for EAGLE3#43132
vllm-bot merged 11 commits into
vllm-project:mainfrom
CentML:qwen-base-arch-eagle

Conversation

@benchislett

Copy link
Copy Markdown
Member

Purpose

As proven by DFlash, the Qwen3 base architecture is more stable for EAGLE3 training due to the extra norms in the attention module. We can improve performance of EAGLE3 and P-EAGLE by using Qwen3 as a base architecture and leveraging the higher learning rates now possible in training. I have manually ablated this and confirmed the results.

This PR is experimental as no public checkpoints currently use the Qwen3 base arch for EAGLE3 or P-EAGLE.

If this becomes likely, I will update and merge the PR accordingly. Until then, it will remain a draft.

Signed-off-by: Benjamin Chislett <bchislett@nvidia.com>
Signed-off-by: Benjamin Chislett <bchislett@nvidia.com>

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request adds support for the Eagle3 speculative decoding architecture for Qwen3 models by implementing the Qwen3Eagle3DecoderLayer, Qwen3Eagle3Model, and Eagle3Qwen3ForCausalLM classes. These changes include logic for auxiliary hidden states, specialized weight loading, and parallel drafting support. The model is also registered and integrated into the speculative decoding proposer. I have no feedback to provide.

@orestis-z

Copy link
Copy Markdown
Contributor

Hey @benchislett — I tested this PR with speculators-format Qwen3 Eagle3 checkpoints (trained with --draft-arch qwen3 in speculators) and hit a bug: loading fails with KeyError: 'layers.0.self_attn.k_norm.weight'.

Root cause: The speculators config loader in vllm/transformers_utils/configs/speculators/algos.py hardcodes Eagle3LlamaForCausalLM as the architecture for all Eagle3 models (line 39), ignoring transformer_layer_config.model_type. So Qwen3-based drafters get loaded with the Llama model class, which doesn't have q_norm/k_norm.

Fix: Resolve the architecture from model_type:

diff --git a/vllm/transformers_utils/configs/speculators/algos.py b/vllm/transformers_utils/configs/speculators/algos.py
--- a/vllm/transformers_utils/configs/speculators/algos.py
+++ b/vllm/transformers_utils/configs/speculators/algos.py
@@ -36,7 +36,13 @@
         "norm_before_residual", True
     )
     pre_trained_config["norm_before_fc"] = config_dict.get("norm_before_fc", False)
-    pre_trained_config["architectures"] = ["Eagle3LlamaForCausalLM"]
+    eagle3_arch_map = {
+        "qwen3": "Eagle3Qwen3ForCausalLM",
+    }
+    model_type = pre_trained_config.get("model_type", "llama")
+    pre_trained_config["architectures"] = [
+        eagle3_arch_map.get(model_type, "Eagle3LlamaForCausalLM")
+    ]
     if config_dict.get("eagle_aux_hidden_state_layer_ids"):

I verified this fixes the issue — Qwen3 Eagle3 drafters load and run correctly with speculative decoding after the change. Happy to open a PR against your branch if that helps.

@orestis-z

Copy link
Copy Markdown
Contributor

Hey @benchislett, I have a qwen3-arch based checkpoint here: https://huggingface.co/inference-optimization/Qwen3-8B-from-Qwen3-8B_regen-speculators.eagle3-qwen3arch-ckpt1.
Do you need anything else to get this in?

@orestis-z

Copy link
Copy Markdown
Contributor

Same issue applies to P-EAGLE with Qwen3 draft architecture — three additional changes are needed on top of the Eagle3 fix above:

1. Architecture resolution for P-EAGLE (algos.py) — update_peagle() hardcodes PeagleLlamaForCausalLM, same pattern as Eagle3:

diff --git a/vllm/transformers_utils/configs/speculators/algos.py b/vllm/transformers_utils/configs/speculators/algos.py
--- a/vllm/transformers_utils/configs/speculators/algos.py
+++ b/vllm/transformers_utils/configs/speculators/algos.py
@@ -53,7 +59,13 @@
     PEagle specific fields:
     ...
     """
-    pre_trained_config["architectures"] = ["PeagleLlamaForCausalLM"]
+    peagle_arch_map = {
+        "qwen3": "PeagleQwen3ForCausalLM",
+    }
+    model_type = pre_trained_config.get("model_type", "llama")
+    pre_trained_config["architectures"] = [
+        peagle_arch_map.get(model_type, "PeagleLlamaForCausalLM")
+    ]

2. Model registry (registry.py) — add the Qwen3 P-EAGLE entry:

diff --git a/vllm/model_executor/models/registry.py b/vllm/model_executor/models/registry.py
--- a/vllm/model_executor/models/registry.py
+++ b/vllm/model_executor/models/registry.py
     "Eagle3Qwen3ForCausalLM": ("qwen3_eagle3", "Eagle3Qwen3ForCausalLM"),
+    "PeagleQwen3ForCausalLM": ("qwen3_eagle3", "Eagle3Qwen3ForCausalLM"),

3. Parallel drafting for P-EAGLE (speculative.py) — peagle method should enable parallel_drafting (only needed when method is explicitly passed, since base.py already handles auto-detection):

diff --git a/vllm/config/speculative.py b/vllm/config/speculative.py
--- a/vllm/config/speculative.py
+++ b/vllm/config/speculative.py
-        if self.method in ("dflash",):
+        if self.method in ("dflash", "peagle"):
             self.parallel_drafting = True

Verified with a Qwen3-arch P-EAGLE checkpoint — all three changes are required for correct loading and serving.

Signed-off-by: Benjamin Chislett <bchislett@nvidia.com>
@benchislett
benchislett marked this pull request as ready for review June 16, 2026 15:53
@benchislett

Copy link
Copy Markdown
Member Author

@orestis-z I added support for speculators models as you suggested. I did not add the "method": "peagle" check since this is not a supported method, we should always be using either "eagle" (with or without "parallel_drafting": True) or "dflash".

I added some tests to ensure the correct behaviour here. They're passing locally. Let me know if you want me to remove them until official nm-testing checkpoints are released, or merge as-is and we can follow-up with LTS checkpoints when they are available

@benchislett benchislett changed the title [Spec Decode][Experimental] Add Qwen3 architecture support for EAGLE3 [Spec Decode] Add Qwen3 architecture support for EAGLE3 Jun 16, 2026
Signed-off-by: Benjamin Chislett <bchislett@nvidia.com>
@orestis-z

orestis-z commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

@benchislett Thanks for adding the tests! I'd say merge as-is. We can swap in official nm-testing checkpoints in a follow-up once they're published.

Comment thread vllm/model_executor/models/qwen3_eagle3.py Outdated
Comment thread vllm/transformers_utils/configs/speculators/algos.py Outdated
Signed-off-by: Benjamin Chislett <bchislett@nvidia.com>
@benchislett benchislett added the ready ONLY add when PR is ready to merge/full CI is needed label Jun 17, 2026
self.vocab_size = self.config.vocab_size

# Get drafter's quantization config
self.quant_config = get_draft_quant_config(vllm_config)

@shanjiaz shanjiaz Jun 18, 2026

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.

@benchislett Just curious, are quantized eagle3 drafters supported now? Are we planning on supporting quantized dflash drafters as well? (Just saw in qwen3-dflash seems like dflash also supports quantized draft now) Very cool.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I see no blockers for quantized drafters. It's planned to be supported but we don't really have any FP8 drafter checkpoints that we can use to pipeclean.

Signed-off-by: Benjamin Chislett <bchislett@nvidia.com>

@mgoin mgoin left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM, just the seemingly bad call on get_cache_scale

Comment thread vllm/model_executor/models/qwen3_eagle3.py Outdated
@vllm-bot
vllm-bot merged commit 89bd2c1 into vllm-project:main Jun 21, 2026
79 of 81 checks passed
shanjiaz pushed a commit to vllm-project/speculators that referenced this pull request Jun 22, 2026
## Summary
- Change the default drafter architecture from Llama to Qwen3 in the
training script (`--draft-arch`) and Eagle3 config
(`transformer_layer_config`)
- Qwen3 is now the recommended default for new speculator training

## Blocked by
- vllm-project/vllm#43132

## Jira
- [INFERENG-8024](https://issues.redhat.com/browse/INFERENG-8024)

## Test plan
- [ ] Verify `--draft-arch` defaults to `qwen3` when not specified
- [ ] Verify `Eagle3SpeculatorConfig` uses `Qwen3Config` as default
`transformer_layer_config`
- [ ] Run training with default args and confirm Qwen3 layers are used
- [ ] Run existing tests

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: Orestis Zambounis <orestis.zambounis@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
nkzhenhua pushed a commit to nkzhenhua/vllm that referenced this pull request Jun 24, 2026
…#43132)

Signed-off-by: Benjamin Chislett <bchislett@nvidia.com>
qli88 pushed a commit to qli88/vllm that referenced this pull request Jun 26, 2026
…#43132)

Signed-off-by: Benjamin Chislett <bchislett@nvidia.com>
Signed-off-by: Qiang Li <qiang.li2@amd.com>
Dao007forever pushed a commit to Dao007forever/vllm that referenced this pull request Jul 18, 2026
…#43132)

Signed-off-by: Benjamin Chislett <bchislett@nvidia.com>
philippesic pushed a commit to philippesic/vllm-semantic-cache that referenced this pull request Jul 19, 2026
…#43132)

Signed-off-by: Benjamin Chislett <bchislett@nvidia.com>
plasticchris pushed a commit to plasticchris/vllm that referenced this pull request Jul 20, 2026
…#43132)

Signed-off-by: Benjamin Chislett <bchislett@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new-model Requests to new models qwen Related to Qwen models ready ONLY add when PR is ready to merge/full CI is needed speculative-decoding v1

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants