Skip to content

fix(metax): avoid vllm._C dependency in activation ops for empty builds - #325

Closed
tengqm wants to merge 1 commit into
mainfrom
fix/metax-empty-mode-activation
Closed

fix(metax): avoid vllm._C dependency in activation ops for empty builds#325
tengqm wants to merge 1 commit into
mainfrom
fix/metax-empty-mode-activation

Conversation

@tengqm

@tengqm tengqm commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Problem

When vllm is built with VLLM_TARGET_DEVICE=empty, vllm._C is not compiled and torch.ops._C.silu_and_mul / torch.ops._C.gelu_and_mul do not exist. The MetaX activation functions instantiate SiluAndMul() / GeluAndMul(), whose init accesses torch.ops._C.* — causing AttributeError at model load time.

Root cause

silu_and_mul_maca and gelu_and_mul_maca delegate to vllm's compiled CUDA kernel classes (SiluAndMul, GeluAndMul). These depend on vllm._C.abi3.so which is absent in empty builds.

Fix

Replace with pure PyTorch: F.silu / F.gelu — functionally identical and works on both empty and full vllm builds.

Credit

Originally authored by ftgreat ldwang@baai.ac.cn in commit 1357ddf (2026-07-21) on the MetaX CI node. This PR upstreams that fix.

Testing

Verified on MetaX C550 (MACA 3.7.2.0, torch 2.8.0+metax): vllm 0.20.2 empty + vllm-plugin-FL, Qwen3-4B, eager mode, flash attention, inference succeeds without _C stubs.

When vllm is built with VLLM_TARGET_DEVICE=empty, vllm._C is not
compiled and torch.ops._C.silu_and_mul does not exist. The MetaX
activation functions instantiating SiluAndMul/GeluAndMul crash at
model load time because their __init__ accesses torch.ops._C.

Replace SiluAndMul/GeluAndMul with pure PyTorch F.silu/F.gelu. This
is functionally identical and works on both empty and full vllm
builds — the CUDA kernel path was a micro-optimization, not a
correctness requirement. The dispatch layer (call_op) already
routes these through the MetaX vendor backend.

Co-Authored-By: ftgreat <ldwang@baai.ac.cn>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions github-actions Bot added the core label Jul 29, 2026
@tengqm

tengqm commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

Error without this fix

Full stack trace from MetaX C550 (MACA 3.7.2.0, vllm 0.20.2 built with VLLM_TARGET_DEVICE=empty):

vllm_fl/ops/activation.py,: cannot open vllm_fl/ops/activation.py,' (No such file or directory) line: cannot open line' (No such file or directory)
10,: cannot open 10,' (No such file or directory) in: cannot open in' (No such file or directory)
init: cannot open `init' (No such file or directory)

Why dispatch doesn't help here

The crash happens in __init__, not in forward. vllm's SiluAndMul.__init__ unconditionally accesses torch.ops._C.silu_and_mul during model construction — before any inference, before any dispatch.

The dispatch layer (forward_oot → call_op → flagos/vendor/reference) only takes effect at inference time in SiluAndMulFL.forward_oot. But we never get there — __init__ crashes first.

__init__ is called during model loading by the vllm core model builder:

The fix replaces SiluAndMul() / GeluAndMul() with F.silu / F.gelu — no class instantiation, no __init__ dependency on vllm._C.

@tengqm

tengqm commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

Error without this fix

Full stack trace from MetaX C550 (MACA 3.7.2.0, vllm 0.20.2 built with VLLM_TARGET_DEVICE=empty):

File "vllm_fl/ops/activation.py", line 10, in __init__
  class SiluAndMulFL(SiluAndMul):
      def __init__(self):
          super().__init__()  ← line 10

File "vllm/model_executor/layers/activation.py", line 133, in __init__
  class SiluAndMul(CustomOp):
      def __init__(self, *, compile_native: bool = True):
          super().__init__(compile_native=compile_native)
          if current_platform.is_cuda_alike() or current_platform.is_xpu():
              self.op = torch.ops._C.silu_and_mul  ← line 133, CRASH

File "torch/_ops.py", line 1353, in __getattr__
  raise AttributeError(
      f"'_OpNamespace' '_C' object has no attribute 'silu_and_mul'")

Why dispatch doesn't help here

The crash happens in __init__, not in forward. vllm's SiluAndMul.__init__ unconditionally accesses torch.ops._C.silu_and_mul during model construction — before any inference, before any dispatch.

The dispatch layer (forward_oot -> call_op -> flagos/vendor/reference) only takes effect at inference time in SiluAndMulFL.forward_oot. But we never get there — __init__ crashes first.

__init__ is called during model loading by the vllm core model builder:

qwen3.py:204 Qwen3DecoderLayer.__init__()
  -> qwen2.py:111 init via lambda
    -> vllm_fl/ops/activation.py:10 SiluAndMulFL.__init__()
      -> super().__init__()
        -> activation.py:133 self.op = torch.ops._C.silu_and_mul

The fix replaces SiluAndMul() / GeluAndMul() with F.silu / F.gelu — no class instantiation, no __init__ dependency on vllm._C.

@tengqm
tengqm marked this pull request as draft July 30, 2026 04:59
@tengqm

tengqm commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

This PR is not ready. Need further investigation.

@tengqm

tengqm commented Jul 31, 2026

Copy link
Copy Markdown
Contributor Author

This PR was generated based on an experiment using cpu version of vllm. So the conclusion and the proposed fixes are both wrong.

@tengqm tengqm closed this Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant