Skip to content

moe-router-weight-on-input

Source: fixes/moe-router-weight-on-input/

Apply the router weight to the expert input, not the output, for MoE layers that ask for it (apply_router_weight_on_input), as Llama 4 does.

Affects Llama 4 Scout and Maverick (BF16 and compressed-tensors checkpoints)
Releases v0.26.0, v0.30.0
Patches vllm_gaudi/ops/hpu_fused_moe.py, vllm_gaudi/ops/hpu_compressed_tensors.py
Upstream not filed yet
Test test_moe_router_weight_on_input.py (CPU, needs torch)

Problem

Llama 4's MoE builds FusedMoE with apply_router_weight_on_input=True and a top-1 sigmoid router, so the reference computes expert(w * x). The HPU monolithic MoE paths never read the flag and pass the router weights to the Habana mixture_of_experts op, which applies them to the expert output: w * expert(x). With SwiGLU experts these differ (silu(w * a) * (w * b) against w * silu(a) * b) on every MoE layer.

Symptom

Outputs drift from the reference model. The text stays fluent, but next-token distributions differ measurably from a float32 CPU reference, and tool calling and exact tasks suffer most.

Who is affected

Anyone serving Llama 4 on HPU through the unquantized (BF16) or compressed-tensors (W8A8 FP8, WNA16) MoE path. Checkpoints with quant_method: fp8 go through hpu_fp8.py, which this fix does not change. Models that do not set the flag are unchanged.

The fix

Right before each moe_op call (unquantized apply_monolithic and forward_oot, compressed-tensors W8A8 FP8 and WNA16 apply_monolithic), a layer with apply_router_weight_on_input gets x * w and unit router weights. top_k must be 1, as upstream requires; anything else raises an error.

Apply it after laguna-moe-sigmoid-routing, which edits the routing branch of the same methods; it also applies without it.

Verify

python3 fixes/moe-router-weight-on-input/apply.py --check   # 0 = applied, 1 = not applied, 2 = source drifted
GAUDI_FIXES_ROOT=/path/to/site-packages pytest fixes/moe-router-weight-on-input

End to end: compare the served model's top-20 logprobs on a few prompts with a float32 CPU reference run of the Hugging Face model. With the fix the divergence drops by an order of magnitude.