Skip to content

Commit 2b0f65e

Browse files
committed
refactor(qwen3.5): rely on the vLLM 0.24 branch contract
1 parent de5c55b commit 2b0f65e

8 files changed

Lines changed: 51 additions & 74 deletions

File tree

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,13 @@ In theory, vllm-plugin-FL can support all models available in vLLM, as long as n
9292
pip install --no-build-isolation -e .
9393
```
9494
95-
### vLLM 0.24 runtime compatibility
95+
### Qwen3.5 text-only causal model support
9696
97-
For vLLM 0.24.x, the plugin registers Qwen3.5 text-only causal model
98-
support at process startup without modifying the vLLM installation.
99-
It also routes `vllm._custom_ops.moe_sum` to the FlagGems implementation when
97+
The plugin supports Qwen3.5 text-only causal models. It installs the required
98+
config, model, and checkpoint compatibility at process startup without
99+
modifying the vLLM installation.
100+
101+
For MoE variants, it also routes `vllm._custom_ops.moe_sum` to FlagGems when
100102
`USE_FLAGGEMS=1` and `moe_sum` is not excluded by the FlagOS
101103
whitelist/blacklist. This supports arbitrary MoE top-k with FP32 accumulation
102104
and handles empty-token batches without rebuilding or replacing vLLM's

tests/unit_tests/patches/test_moe_sum_v024.py renamed to tests/unit_tests/patches/test_moe_sum.py

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from types import ModuleType
22

3-
from vllm_fl.patches import moe_sum_v024
3+
from vllm_fl.patches import moe_sum
44

55

66
class _FakeTensor:
@@ -21,18 +21,17 @@ def test_moe_sum_patch_routes_nonempty_and_guards_empty(monkeypatch):
2121
ops = ModuleType("fake_vllm_custom_ops")
2222
ops.moe_sum = lambda input, output: calls.append(("original", input, output))
2323

24-
monkeypatch.setattr(moe_sum_v024, "is_vllm_024", lambda: True)
2524
monkeypatch.setattr(
26-
moe_sum_v024, "use_flaggems_op", lambda op_name: op_name == "moe_sum"
25+
moe_sum, "use_flaggems_op", lambda op_name: op_name == "moe_sum"
2726
)
2827
monkeypatch.setattr(
29-
moe_sum_v024,
28+
moe_sum,
3029
"_flag_gems_moe_sum",
3130
lambda input, output: calls.append(("flag_gems", input, output)),
3231
)
3332

34-
assert moe_sum_v024.patch_vllm_moe_sum(ops) is True
35-
assert moe_sum_v024.patch_vllm_moe_sum(ops) is False
33+
assert moe_sum.patch_vllm_moe_sum(ops) is True
34+
assert moe_sum.patch_vllm_moe_sum(ops) is False
3635

3736
nonempty_input = _FakeTensor(24)
3837
nonempty_output = _FakeTensor(8)
@@ -48,15 +47,14 @@ def test_moe_sum_patch_uses_stride_safe_fallback(monkeypatch):
4847
ops = ModuleType("fake_vllm_custom_ops")
4948
ops.moe_sum = lambda input, output: None
5049

51-
monkeypatch.setattr(moe_sum_v024, "is_vllm_024", lambda: True)
52-
monkeypatch.setattr(moe_sum_v024, "use_flaggems_op", lambda op_name: True)
50+
monkeypatch.setattr(moe_sum, "use_flaggems_op", lambda op_name: True)
5351
monkeypatch.setattr(
54-
moe_sum_v024,
52+
moe_sum,
5553
"_torch_moe_sum",
5654
lambda input, output: calls.append((input, output)),
5755
)
5856

59-
assert moe_sum_v024.patch_vllm_moe_sum(ops) is True
57+
assert moe_sum.patch_vllm_moe_sum(ops) is True
6058
noncontiguous_input = _FakeTensor(24, hidden_stride=2)
6159
output = _FakeTensor(8)
6260
ops.moe_sum(noncontiguous_input, output)
@@ -69,8 +67,7 @@ def test_moe_sum_patch_respects_flaggems_disable(monkeypatch):
6967
original = lambda input, output: None
7068
ops.moe_sum = original
7169

72-
monkeypatch.setattr(moe_sum_v024, "is_vllm_024", lambda: True)
73-
monkeypatch.setattr(moe_sum_v024, "use_flaggems_op", lambda op_name: False)
70+
monkeypatch.setattr(moe_sum, "use_flaggems_op", lambda op_name: False)
7471

75-
assert moe_sum_v024.patch_vllm_moe_sum(ops) is False
72+
assert moe_sum.patch_vllm_moe_sum(ops) is False
7673
assert ops.moe_sum is original

tests/unit_tests/patches/test_qwen3_5_v024.py renamed to tests/unit_tests/patches/test_qwen3_5_text.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from types import SimpleNamespace
22

3-
from vllm_fl.patches import qwen3_5_v024 as compat
3+
from vllm_fl.patches import qwen3_5_text as compat
44

55

66
def test_text_config_convertor_remaps_conditional_architecture():
@@ -65,15 +65,14 @@ def test_apply_registers_only_plugin_owned_lazy_models(monkeypatch):
6565
architecture, model
6666
)
6767
)
68-
monkeypatch.setattr(compat, "is_vllm_024", lambda: True)
6968
monkeypatch.setattr(transformers_config, "_CONFIG_REGISTRY", {})
7069
monkeypatch.setattr(model_config, "MODELS_CONFIG_MAP", {})
7170
monkeypatch.setattr(model_arch_config_convertor, "MODEL_ARCH_CONFIG_CONVERTORS", {})
7271
monkeypatch.setattr(model_registry, "_TEXT_GENERATION_MODELS", {})
7372
monkeypatch.setattr(model_registry, "_VLLM_MODELS", {})
7473
monkeypatch.setattr(model_registry, "ModelRegistry", fake_registry)
7574

76-
assert compat.apply_qwen3_5_v024_patches() is True
75+
assert compat.apply_qwen3_5_text_patches() is True
7776

7877
assert registered == {
7978
"Qwen3_5ForCausalLM": ("vllm_fl.models.qwen3_5:Qwen3_5ForCausalLM"),

vllm_fl/__init__.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -138,17 +138,13 @@ def register_router():
138138

139139
def register_model():
140140
"""Register FL-specific models not yet upstream."""
141-
# Keep all vLLM 0.24 compatibility changes plugin-owned. These hooks are
142-
# idempotent because general plugins are loaded independently in spawned
143-
# model-inspection and worker processes.
144-
from vllm_fl.patches._version import is_vllm_024
141+
# General plugins are loaded independently in spawned model-inspection and
142+
# worker processes, so all runtime compatibility hooks must be idempotent.
143+
from vllm_fl.patches.moe_sum import patch_vllm_moe_sum
144+
from vllm_fl.patches.qwen3_5_text import apply_qwen3_5_text_patches
145145

146-
if is_vllm_024():
147-
from vllm_fl.patches.qwen3_5_v024 import apply_qwen3_5_v024_patches
148-
from vllm_fl.patches.moe_sum_v024 import patch_vllm_moe_sum
149-
150-
apply_qwen3_5_v024_patches()
151-
patch_vllm_moe_sum()
146+
apply_qwen3_5_text_patches()
147+
patch_vllm_moe_sum()
152148

153149
_register_flagcx_connector()
154150

vllm_fl/models/qwen3_5.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# Copyright (c) 2026 BAAI. All rights reserved.
2-
"""Runtime compatibility shim for Qwen3.5 text-only models on vLLM 0.24.
2+
"""Runtime compatibility shim for Qwen3.5 text-only causal models.
33
44
The model implementation remains the one shipped by vLLM. Importing this
55
module adds the hybrid-model metadata, cache helpers, and VL checkpoint prefix
6-
mapping that the v0.24 text-only classes are missing, then re-exports those
7-
upstream classes for lazy registration by the FL plugin.
6+
mapping that the upstream text-only classes are missing, then re-exports those
7+
classes for lazy registration by the FL plugin.
88
"""
99

1010
from vllm.model_executor.layers.mamba.mamba_utils import (

vllm_fl/patches/_version.py

Lines changed: 0 additions & 13 deletions
This file was deleted.
Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
# Copyright (c) 2026 BAAI. All rights reserved.
2-
"""Route vLLM 0.24 MoE reduction through FlagGems at runtime."""
2+
"""Route vLLM MoE reduction through FlagGems at runtime."""
33

4-
from functools import wraps
54
import logging
5+
from functools import wraps
66
from types import ModuleType
77

8-
from vllm_fl.patches._version import is_vllm_024
98
from vllm_fl.utils import use_flaggems_op
109

1110
logger = logging.getLogger(__name__)
@@ -30,7 +29,7 @@ def patch_vllm_moe_sum(ops_module: ModuleType | None = None) -> bool:
3029
every call. The replacement therefore covers Triton/FP8 experts while
3130
leaving the vLLM wheel and its compiled extensions untouched.
3231
"""
33-
if not is_vllm_024() or not use_flaggems_op("moe_sum"):
32+
if not use_flaggems_op("moe_sum"):
3433
return False
3534

3635
if ops_module is None:
@@ -56,7 +55,7 @@ def moe_sum_flagos(input, output):
5655
moe_sum_flagos._vllm_fl_moe_sum_patch = True
5756
moe_sum_flagos._vllm_fl_original = original
5857
ops_module.moe_sum = moe_sum_flagos
59-
logger.info("Monkey-patched vLLM 0.24 moe_sum -> FlagGems runtime operator")
58+
logger.info("Monkey-patched vLLM moe_sum -> FlagGems runtime operator")
6059
return True
6160

6261

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Copyright (c) 2026 BAAI. All rights reserved.
2-
"""Install Qwen3.5 text-only compatibility at vLLM runtime.
2+
"""Install Qwen3.5 text-only causal model support at vLLM runtime.
33
44
The compatibility layer mirrors the text-only config, model, and checkpoint
5-
handling added after vLLM 0.24 without modifying the vLLM installation.
5+
handling missing from upstream vLLM without modifying the vLLM installation.
66
"""
77

88
import logging
@@ -13,7 +13,6 @@
1313
from vllm.transformers_utils.model_arch_config_convertor import (
1414
ModelArchConfigConvertorBase,
1515
)
16-
from vllm_fl.patches._version import is_vllm_024
1716

1817
logger = logging.getLogger(__name__)
1918

@@ -44,9 +43,9 @@ def get_architectures(self) -> list[str]:
4443
_CONDITIONAL_TO_CAUSAL.get(arch, arch) for arch in architectures
4544
]
4645

47-
# vLLM 0.24 consults hf_config.architectures again in the runtime model
48-
# loader, after ModelArchitectureConfig has been built. Keep both
49-
# views synchronized so it cannot fall back to a stale VL architecture.
46+
# The runtime model loader consults hf_config.architectures again after
47+
# ModelArchitectureConfig has been built. Keep both views synchronized
48+
# so it cannot fall back to a stale VL architecture.
5049
if normalized != architectures:
5150
self.hf_config.architectures = normalized.copy()
5251
return normalized
@@ -66,19 +65,20 @@ def verify_and_update_config(vllm_config) -> None:
6665
rope_parameters.pop("mrope_interleaved", None)
6766

6867

69-
def apply_qwen3_5_v024_patches() -> bool:
70-
"""Register the runtime shims required by pristine vLLM 0.24.x.
68+
def apply_qwen3_5_text_patches() -> bool:
69+
"""Register Qwen3.5 text-only causal model support.
7170
72-
Returns ``True`` when the compatibility path applies to this vLLM release.
73-
Repeated calls are safe.
71+
Repeated calls are safe. Returns ``True`` after installing the runtime
72+
registrations.
7473
"""
75-
if not is_vllm_024():
76-
return False
77-
78-
from vllm.model_executor.models import config as model_config
79-
from vllm.model_executor.models import registry as model_registry
80-
from vllm.transformers_utils import config as transformers_config
81-
from vllm.transformers_utils import model_arch_config_convertor
74+
from vllm.model_executor.models import (
75+
config as model_config,
76+
registry as model_registry,
77+
)
78+
from vllm.transformers_utils import (
79+
config as transformers_config,
80+
model_arch_config_convertor,
81+
)
8282

8383
config_registry = transformers_config._CONFIG_REGISTRY
8484
config_registry.setdefault("qwen3_5_text", "Qwen3_5TextConfig")
@@ -98,20 +98,17 @@ def apply_qwen3_5_v024_patches() -> bool:
9898
model_registry._TEXT_GENERATION_MODELS.setdefault(
9999
architecture, ("qwen3_5", class_name)
100100
)
101-
model_registry._VLLM_MODELS.setdefault(
102-
architecture, ("qwen3_5", class_name)
103-
)
101+
model_registry._VLLM_MODELS.setdefault(architecture, ("qwen3_5", class_name))
104102
model_registry.ModelRegistry.register_model(
105103
architecture, f"vllm_fl.models.qwen3_5:{class_name}"
106104
)
107105

108-
logger.info("Installed vLLM 0.24 Qwen3.5 text-only runtime compatibility")
106+
logger.info("Installed Qwen3.5 text-only causal model runtime compatibility")
109107
return True
110108

111109

112110
__all__ = [
113111
"Qwen3_5ForCausalLMConfig",
114112
"Qwen3_5TextModelArchConfigConvertor",
115-
"apply_qwen3_5_v024_patches",
116-
"is_vllm_024",
113+
"apply_qwen3_5_text_patches",
117114
]

0 commit comments

Comments
 (0)