Skip to content

Commit de5c55b

Browse files
committed
fix(moe): preserve upstream quantized methods
1 parent a363521 commit de5c55b

2 files changed

Lines changed: 71 additions & 3 deletions

File tree

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Copyright (c) 2026 BAAI. All rights reserved.
2+
3+
from unittest.mock import MagicMock, patch
4+
5+
from vllm_fl.ops.fused_moe import layer
6+
7+
8+
def _runner_with_quant_method(quant_method):
9+
runner = MagicMock()
10+
runner._quant_method = quant_method
11+
runner.moe_config = MagicMock()
12+
return runner
13+
14+
15+
def test_fused_moe_fl_replaces_unquantized_method():
16+
quant_method = MagicMock(spec=layer.UnquantizedFusedMoEMethod)
17+
runner = _runner_with_quant_method(quant_method)
18+
replacement = MagicMock()
19+
20+
with (
21+
patch.object(layer, "_OrigFusedMoE", return_value=runner),
22+
patch.object(
23+
layer,
24+
"UnquantizedFusedMoEMethodFL",
25+
return_value=replacement,
26+
) as replacement_cls,
27+
patch.object(layer, "replace_router_with_fl") as replace_router,
28+
):
29+
result = layer.FusedMoEFL(test_arg=True)
30+
31+
assert result is runner
32+
replacement_cls.assert_called_once_with(runner.moe_config)
33+
runner._replace_quant_method.assert_called_once_with(replacement)
34+
replace_router.assert_called_once_with()
35+
36+
37+
def test_fused_moe_fl_preserves_quantized_method():
38+
quant_method = object()
39+
runner = _runner_with_quant_method(quant_method)
40+
41+
with (
42+
patch.object(layer, "_OrigFusedMoE", return_value=runner),
43+
patch.object(layer, "UnquantizedFusedMoEMethodFL") as replacement_cls,
44+
patch.object(layer, "replace_router_with_fl") as replace_router,
45+
patch.object(layer.logger, "info_once") as info_once,
46+
):
47+
result = layer.FusedMoEFL()
48+
49+
assert result is runner
50+
replacement_cls.assert_not_called()
51+
runner._replace_quant_method.assert_not_called()
52+
replace_router.assert_called_once_with()
53+
info_once.assert_called_once_with(
54+
"Preserving upstream quantized MoE method %s in FusedMoEFL.",
55+
"object",
56+
)

vllm_fl/ops/fused_moe/layer.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,15 @@
1212
from vllm.model_executor.layers.fused_moe.unquantized_fused_moe_method import (
1313
UnquantizedFusedMoEMethod,
1414
)
15+
from vllm.logger import init_logger
1516

1617
from vllm_fl.ops.fused_moe.router import replace_router_with_fl
1718
from .fused_moe_utils import select_unquantized_moe_backend_oot
1819

1920

21+
logger = init_logger(__name__)
22+
23+
2024
class UnquantizedFusedMoEMethodFL(UnquantizedFusedMoEMethod):
2125
"""OOT replacement for UnquantizedFusedMoEMethod that routes computation
2226
through flaggems operators."""
@@ -54,9 +58,17 @@ def FusedMoEFL(*args, **kwargs) -> MoERunner:
5458
# _fused_moe_pkg.FusedMoE with FusedMoEFL.
5559
runner: MoERunner = _OrigFusedMoE(*args, **kwargs)
5660

57-
# 2. Replace quant_method with FL version.
58-
fl_quant_method = UnquantizedFusedMoEMethodFL(runner.moe_config)
59-
runner._replace_quant_method(fl_quant_method)
61+
# 2. Replace only an upstream unquantized method with the FL version.
62+
# Quantized methods own their weight/activation scaling metadata and must
63+
# remain attached to the runner.
64+
if isinstance(runner._quant_method, UnquantizedFusedMoEMethod):
65+
fl_quant_method = UnquantizedFusedMoEMethodFL(runner.moe_config)
66+
runner._replace_quant_method(fl_quant_method)
67+
else:
68+
logger.info_once(
69+
"Preserving upstream quantized MoE method %s in FusedMoEFL.",
70+
type(runner._quant_method).__name__,
71+
)
6072

6173
# 3. Replace router _compute_routing with FL version via monkey-patch.
6274
# replace_router_with_fl() patches the class method so the router

0 commit comments

Comments
 (0)