[HotFix][Ling 2.6] Fix HybridLinearAttn dispatcher for Ling-2.6 (#26474)

Co-authored-by: luoyuan.luo <luoyuan.luo@antgroup.com>
This commit is contained in:
Yuan Luo
2026-05-29 14:50:15 +08:00
committed by GitHub
co-authored by luoyuan.luo
parent 0fb0ea7aac
commit 08ec19872c
3 changed files with 70 additions and 1 deletions
@@ -811,9 +811,18 @@ class HybridLinearAttnBackend(AttentionBackend):
def _is_full_attn(
self, layer: Optional[RadixAttention], layer_id: Optional[int] = None
) -> bool:
# Dispatch by the layer's runtime type
# Explicit linear-attention subclass → strong linear signal (KDA, GDN,
# Qwen3-Next, Qwen3.5 main linear layers).
if isinstance(layer, RadixLinearAttention):
return False
# Some hybrid models (Ling-2.5/2.6) wrap their linear layers in plain
# `RadixAttention` rather than `RadixLinearAttention`. Those wrappers
# set `_is_linear_attention=True` on the attn module so we can
# distinguish them from full-attention RadixAttention instances —
# including MTP/NEXTN draft layers, which are full and must default to
# the full-attn path.
if layer is not None and getattr(layer, "_is_linear_attention", False):
return False
if isinstance(layer, RadixAttention):
return True
@@ -508,6 +508,12 @@ class BailingMoELinearAttention(nn.Module):
quant_config=quant_config,
prefix=f"{prefix}.attn",
)
# Marker for HybridLinearAttnBackend._is_full_attn: Bailing wraps
# linear-attention layers in a plain RadixAttention, so the
# dispatcher can't tell from the type alone that this is a linear
# layer (would otherwise default to the full-attn backend, e.g. the
# same way MTP/NEXTN draft layers are routed).
self.attn._is_linear_attention = True
self.group_norm_size = getattr(config, "group_norm_size", 1)
self.rms_norm_eps = float(getattr(config, "rms_norm_eps", 1e-5))