[XPU] Fix Eagle3 initialization on XPU (#43957)
Signed-off-by: Chaojun Zhang <chaojun.zhang@intel.com> Co-authored-by: Andreas Karatzas <akaratza@amd.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: Kunshang Ji <kunshang.ji@intel.com>
Chaojun Zhang committed
Jul 6, 2026 at 08:46 UTC
d2ec433e3795ad3ef7314c8c0f87f03d24d47960
3 files changed
+44
-1
.buildkite/intel_jobs/misc_intel.yaml
+20
@@ -76,6 +76,26 @@ steps:
76
pytest -v -s v1/sample/test_logprobs.py &&
77
pytest -v -s v1/sample/test_logprobs_e2e.py'
78
79
+- label: Basic Models Tests (Initialization)
80
+ timeout_in_minutes: 60
81
+ device: intel_gpu
82
+ no_plugin: true
83
+ working_dir: "."
84
+ env:
85
+ REGISTRY: "public.ecr.aws/q9t5s3a7"
86
+ REPO: "vllm-ci-test-repo"
87
+ VLLM_TEST_DEVICE: "xpu"
88
+ source_file_dependencies:
89
+ - vllm/
90
+ - tests/models/test_initialization.py
91
+ - tests/models/registry.py
92
+ commands:
93
+ - >-
94
+ bash .buildkite/scripts/hardware_ci/run-intel-test.sh
95
+ 'export VLLM_XPU_FUSED_MOE_USE_REF=1 &&
96
+ cd tests &&
97
+ pytest -v -s models/test_initialization.py::test_can_initialize_large_subset[Eagle3MiniMaxM2ForCausalLM]'
98
+
99
- label: XPU CPU Offload
100
timeout_in_minutes: 60
101
device: intel_gpu
vllm/model_executor/models/llama_eagle3.py
+4
-1
@@ -233,7 +233,10 @@ class LlamaModel(nn.Module):
233
) -> tuple[torch.Tensor, torch.Tensor]:
234
if input_embeds is None:
235
input_embeds = self.embed_input_ids(input_ids)
236
- assert hidden_states.shape[-1] == input_embeds.shape[-1]
236
+ torch._assert(
237
+ hidden_states.shape[-1] == input_embeds.shape[-1],
238
+ "hidden_states and input_embeds must have the same last dimension",
239
+ )
240
241
residual = None
242
for layer in self.layers:
vllm/v1/spec_decode/llm_base_proposer.py
+20
@@ -1468,6 +1468,26 @@ class SpecDecodeBaseProposer:
1468
"Sharing target model embedding weights with the draft model."
1469
)
1470
1471
+ if share_embeddings:
1472
+ draft_embed = self.model.model.embed_tokens
1473
+ # Only share when both models use the same embedding width.
1474
+ # Guard with isinstance so non-Tensor weights (e.g. in tests)
1475
+ # are not affected — mirrors the weight-equality check above.
1476
+ if isinstance(target_embed_tokens.weight, torch.Tensor) and isinstance(
1477
+ draft_embed.weight, torch.Tensor
1478
+ ):
1479
+ target_dim = target_embed_tokens.weight.shape[-1]
1480
+ draft_dim = draft_embed.weight.shape[-1]
1481
+ if target_dim != draft_dim:
1482
+ share_embeddings = False
1483
+ logger.info(
1484
+ "Target embedding dim (%d) differs from draft "
1485
+ "embedding dim (%d). Keeping separate embedding "
1486
+ "weights.",
1487
+ target_dim,
1488
+ draft_dim,
1489
+ )
1490
+
1491
if share_embeddings:
1492
if hasattr(self.model.model, "embed_tokens"):
1493
del self.model.model.embed_tokens