Skip to content

Commit e58f055

Browse files
authored
[CI][xlite] Match xlite backend with the current main and add e2e MoE model test coverage (vllm-project#12272)
### What this PR does / why we need it? This PR brings the `xlite` backend in line with the current main and `vllm==0.24.0`, and adds e2e coverage for the xlite graph mode to catch future changes. Refer to PR vllm-project#12019 for the context. - vLLM version: v0.24.0 - vLLM main: vllm-project/vllm@85c09e9 Signed-off-by: Sijie Fu <fusijie@huawei.com>
1 parent c0d4198 commit e58f055

4 files changed

Lines changed: 129 additions & 27 deletions

File tree

.github/workflows/scripts/test_config.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,7 @@
577577
tests:
578578
- tests/ut/xlite
579579
- tests/e2e/pull_request/one_card/test_xlite.py
580+
- tests/e2e/pull_request/two_card/test_xlite.py
580581

581582
# Batch Invariant
582583
- name: batch_invariant
@@ -756,6 +757,7 @@ estimated_times:
756757
tests/e2e/pull_request/two_card/test_shared_expert_dp.py: 400
757758
tests/e2e/pull_request/two_card/test_sp_pass.py: 260
758759
tests/e2e/pull_request/two_card/test_hccl_weight_transfer.py: 110
760+
tests/e2e/pull_request/two_card/test_xlite.py: 180
759761
tests/e2e/pull_request/four_card/_310p/test_dense_model_310p.py: 410
760762
tests/e2e/pull_request/four_card/_310p/test_moe_model_310p.py: 510
761763
tests/e2e/pull_request/four_card/_310p/test_vl_model_310p.py: 360
Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (c) 2025 Huawei Technologies Co., Ltd. All Rights Reserved.
2+
# Copyright (c) 2026 Huawei Technologies Co., Ltd. All Rights Reserved.
33
# Copyright 2023 The vLLM team.
44
#
55
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,39 +27,53 @@
2727

2828
import pytest
2929

30-
from tests.e2e.pull_request.utils import PROMPTS_SHORT, LLMTestCase, compare_logprobs
30+
from tests.e2e.conftest import wait_until_npu_memory_free
31+
from tests.e2e.pull_request.utils import PROMPTS_SHORT, compare_logprobs
3132

3233
os.environ["VLLM_ASCEND_ENABLE_NZ"] = "2"
3334

34-
CASE_DECODE_ONLY = LLMTestCase(
35-
model="Qwen/Qwen3-0.6B",
36-
prompts=PROMPTS_SHORT,
37-
)
38-
39-
CASE_FULL = LLMTestCase(
40-
model="Qwen/Qwen3-0.6B",
41-
prompts=PROMPTS_SHORT,
42-
)
35+
MODELS: list[str] = ["Qwen/Qwen3-0.6B"]
4336

4437

45-
@pytest.mark.skip(reason="TODO: Re-enable xlite_decode_only e2e test when stable.")
46-
@pytest.mark.parametrize("cur_case", [CASE_DECODE_ONLY])
47-
def test_models_with_xlite_decode_only(cur_case: LLMTestCase):
38+
@pytest.mark.e2e_model(*MODELS)
39+
@pytest.mark.e2e_coverage(
40+
arch="dense",
41+
feature="xlite",
42+
parallel="TP",
43+
deploy="pd_mix",
44+
hardware="A2",
45+
quantization="BF16",
46+
graph_mode="xlite_decode_only",
47+
)
48+
@pytest.mark.parametrize("model", MODELS)
49+
@wait_until_npu_memory_free()
50+
def test_models_with_xlite_decode_only(model: str):
4851
runner_kwargs = {
49-
"model_name": cur_case.model,
52+
"model_name": model,
5053
"max_model_len": 1024,
5154
"block_size": 128,
52-
"additional_config": {"xlite_graph_config": {"enabled": True}},
55+
"additional_config": {"xlite_graph_config": {"enabled": True, "full_mode": False}},
5356
}
54-
compare_logprobs(runner_kwargs=runner_kwargs, prompts=cur_case.prompts)
57+
compare_logprobs(runner_kwargs=runner_kwargs, prompts=PROMPTS_SHORT)
5558

5659

57-
@pytest.mark.parametrize("cur_case", [CASE_FULL])
58-
def test_models_with_xlite_full_mode(cur_case: LLMTestCase):
60+
@pytest.mark.e2e_model(*MODELS)
61+
@pytest.mark.e2e_coverage(
62+
arch="dense",
63+
feature="xlite",
64+
parallel="TP",
65+
deploy="pd_mix",
66+
hardware="A2",
67+
quantization="BF16",
68+
graph_mode="xlite_full",
69+
)
70+
@pytest.mark.parametrize("model", MODELS)
71+
@wait_until_npu_memory_free()
72+
def test_models_with_xlite_full_mode(model: str):
5973
runner_kwargs = {
60-
"model_name": cur_case.model,
74+
"model_name": model,
6175
"max_model_len": 1024,
6276
"block_size": 128,
6377
"additional_config": {"xlite_graph_config": {"enabled": True, "full_mode": True}},
6478
}
65-
compare_logprobs(runner_kwargs=runner_kwargs, prompts=cur_case.prompts)
79+
compare_logprobs(runner_kwargs=runner_kwargs, prompts=PROMPTS_SHORT)
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#
2+
# Copyright (c) 2026 Huawei Technologies Co., Ltd. All Rights Reserved.
3+
# Copyright 2023 The vLLM team.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
# This file is a part of the vllm-ascend project.
17+
#
18+
"""Verify MoE serving with xlite graph mode on two NPU cards.
19+
20+
Run `pytest tests/e2e/pull_request/two_card/test_xlite.py`.
21+
"""
22+
23+
import os
24+
25+
import pytest
26+
27+
from tests.e2e.conftest import VllmRunner, wait_until_npu_memory_free
28+
from tests.e2e.pull_request.utils import PROMPTS_SHORT
29+
30+
os.environ["VLLM_ASCEND_ENABLE_NZ"] = "2"
31+
32+
MODELS: list[str] = ["Qwen/Qwen3-30B-A3B"]
33+
34+
35+
@pytest.mark.e2e_model(*MODELS)
36+
@pytest.mark.e2e_coverage(
37+
arch="moe",
38+
feature="xlite",
39+
parallel="TP,EP",
40+
deploy="pd_mix",
41+
hardware="A3",
42+
quantization="BF16",
43+
graph_mode="xlite_decode_only",
44+
)
45+
@pytest.mark.parametrize("model", MODELS)
46+
@wait_until_npu_memory_free()
47+
def test_models_with_xlite_decode_only(model: str):
48+
with VllmRunner(
49+
model,
50+
tensor_parallel_size=2,
51+
enable_expert_parallel=True,
52+
distributed_executor_backend="mp",
53+
block_size=128,
54+
max_model_len=2048,
55+
additional_config={"xlite_graph_config": {"enabled": True, "full_mode": False}},
56+
) as vllm_model:
57+
outputs = vllm_model.generate_greedy(PROMPTS_SHORT, 3)
58+
59+
assert all(output[1] for output in outputs)
60+
61+
62+
@pytest.mark.e2e_model(*MODELS)
63+
@pytest.mark.e2e_coverage(
64+
arch="moe",
65+
feature="xlite",
66+
parallel="TP,EP",
67+
deploy="pd_mix",
68+
hardware="A3",
69+
quantization="BF16",
70+
graph_mode="xlite_full",
71+
)
72+
@pytest.mark.parametrize("model", MODELS)
73+
@wait_until_npu_memory_free()
74+
def test_models_with_xlite_full_mode(model: str):
75+
with VllmRunner(
76+
model,
77+
tensor_parallel_size=2,
78+
enable_expert_parallel=True,
79+
distributed_executor_backend="mp",
80+
block_size=128,
81+
max_model_len=2048,
82+
additional_config={"xlite_graph_config": {"enabled": True, "full_mode": True}},
83+
) as vllm_model:
84+
outputs = vllm_model.generate_greedy(PROMPTS_SHORT, 3)
85+
86+
assert all(output[1] for output in outputs)

vllm_ascend/xlite/xlite.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -436,15 +436,15 @@ def _build_model(self) -> None:
436436
layers, _ = self._get_layers_and_model_prefix()
437437

438438
xlite_model.gate = get_layer_weights(layers, "mlp.gate.weight")
439-
prefix = "mlp.experts."
439+
prefix = "mlp.experts.routed_experts."
440440
kwargs: WeightGetterConfig = {"secondary_flattening": f"{prefix}local_num_experts", "post_processor": None}
441441
xlite_model.re_up_gate = get_layer_weights(layers, f"{prefix}w13_weight", **kwargs)
442442
xlite_model.re_down = get_layer_weights(layers, f"{prefix}w2_weight", **kwargs)
443443
xlite_config.experts_weight_nz = self.is_tensor_nz(xlite_model.re_up_gate[0])
444444

445445
if self.quantization:
446446
kwargs["post_processor"] = self._transform_deq_scale
447-
xlite_model.re_up_gate_scale = get_layer_weights(layers, f"{prefix}w13_weight_scale_fp32", **kwargs)
447+
xlite_model.re_up_gate_scale = get_layer_weights(layers, f"{prefix}w13_weight_scale", **kwargs)
448448
xlite_model.re_down_scale = get_layer_weights(layers, f"{prefix}w2_weight_scale", **kwargs)
449449

450450

@@ -486,7 +486,7 @@ def _build_model(self) -> None:
486486
self.init_matmul_weights(layers, "se_up_gate", "mlp.shared_experts.gate_up_proj")
487487
self.init_matmul_weights(layers, "se_down", "mlp.shared_experts.down_proj")
488488

489-
prefix = "mlp.experts."
489+
prefix = "mlp.experts.routed_experts."
490490
kwargs: WeightGetterConfig = {"secondary_flattening": f"{prefix}local_num_experts", "post_processor": None}
491491
xlite_model.re_up_gate = get_layer_weights(layers, f"{prefix}w13_weight", **kwargs)
492492
xlite_model.re_down = get_layer_weights(layers, f"{prefix}w2_weight", **kwargs)
@@ -495,7 +495,7 @@ def _build_model(self) -> None:
495495

496496
if self.quantization:
497497
kwargs["post_processor"] = self._transform_deq_scale
498-
xlite_model.re_up_gate_scale = get_layer_weights(layers, f"{prefix}w13_weight_scale_fp32", **kwargs)
498+
xlite_model.re_up_gate_scale = get_layer_weights(layers, f"{prefix}w13_weight_scale", **kwargs)
499499
xlite_model.re_down_scale = get_layer_weights(layers, f"{prefix}w2_weight_scale", **kwargs)
500500

501501

@@ -530,7 +530,7 @@ def _build_model(self) -> None:
530530
layers, "block_sparse_moe.e_score_correction_bias", post_processor=lambda b: b.to(torch.float32)
531531
)
532532

533-
prefix = "block_sparse_moe.experts."
533+
prefix = "block_sparse_moe.experts.routed_experts."
534534
kwargs: WeightGetterConfig = {"secondary_flattening": f"{prefix}local_num_experts", "post_processor": None}
535535
xlite_model.re_up_gate = get_layer_weights(layers, f"{prefix}w13_weight", **kwargs)
536536
xlite_model.re_down = get_layer_weights(layers, f"{prefix}w2_weight", **kwargs)
@@ -539,7 +539,7 @@ def _build_model(self) -> None:
539539

540540
if self.quantization:
541541
kwargs["post_processor"] = self._transform_deq_scale
542-
xlite_model.re_up_gate_scale = get_layer_weights(layers, f"{prefix}w13_weight_scale_fp32", **kwargs)
542+
xlite_model.re_up_gate_scale = get_layer_weights(layers, f"{prefix}w13_weight_scale", **kwargs)
543543
xlite_model.re_down_scale = get_layer_weights(layers, f"{prefix}w2_weight_scale", **kwargs)
544544

545545

0 commit comments

Comments
 (0)