[Spec Decode] Add Qwen3 architecture support for EAGLE3 - #43132
Conversation
Signed-off-by: Benjamin Chislett <bchislett@nvidia.com>
Signed-off-by: Benjamin Chislett <bchislett@nvidia.com>
There was a problem hiding this comment.
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.
|
Hey @benchislett — I tested this PR with speculators-format Qwen3 Eagle3 checkpoints (trained with Root cause: The speculators config loader in Fix: Resolve the architecture from 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. |
|
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. |
|
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 ( 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 ( 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 ( 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 = TrueVerified 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>
|
@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 |
Signed-off-by: Benjamin Chislett <bchislett@nvidia.com>
|
@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. |
Signed-off-by: Benjamin Chislett <bchislett@nvidia.com>
| self.vocab_size = self.config.vocab_size | ||
|
|
||
| # Get drafter's quantization config | ||
| self.quant_config = get_draft_quant_config(vllm_config) |
There was a problem hiding this comment.
@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.
There was a problem hiding this comment.
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
left a comment
There was a problem hiding this comment.
LGTM, just the seemingly bad call on get_cache_scale
Signed-off-by: Benjamin Chislett <bchislett@nvidia.com>
## 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>
…#43132) Signed-off-by: Benjamin Chislett <bchislett@nvidia.com>
…#43132) Signed-off-by: Benjamin Chislett <bchislett@nvidia.com> Signed-off-by: Qiang Li <qiang.li2@amd.com>
…#43132) Signed-off-by: Benjamin Chislett <bchislett@nvidia.com>
…#43132) Signed-off-by: Benjamin Chislett <bchislett@nvidia.com>
…#43132) Signed-off-by: Benjamin Chislett <bchislett@nvidia.com>
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.