Skip to content

Apply the causal mask in MLAAttentionBridge when HF passes no 4D mask - #1920

Merged
jlarson4 merged 1 commit into
TransformerLensOrg:devfrom
YHC66:fix-mla-causal-mask-without-attention-mask
Oct 21, 2026
Merged

jlarson4 merged 1 commit into
TransformerLensOrg:devfrom
YHC66:fix-mla-causal-mask-without-attention-mask

Conversation

@YHC66

@YHC66 YHC66 commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

Description

MLAAttentionBridge.forward (DeepSeek-V2/V3, GLM-4.7-Flash) recomputes attention by hand, but it only applies a mask when one is passed, and only as an additive float mask:

if attention_mask is not None:
    attention_mask = self._normalize_compatibility_mask_sentinel(attention_mask)
    attn_scores = attn_scores + attention_mask

When the wrapped HF model runs with attn_implementation="sdpa" (the transformers default), HF does not build a float 4D mask for the attention modules:

  • with no padding it passes attention_mask=None and relies on SDPA's is_causal, so the bridge attends bidirectionally;
  • with padding it passes a boolean 4D mask (True = attend), which the bridge adds to the scores as 0/1, so neither the causal mask nor the padding is applied.

boot_transformers forces eager attention, so it is not affected. build_bridge_from_module leaves the supplied model alone (as documented), so a DeepSeek model loaded with default settings and wrapped this way gets wrong logits, and earlier positions depend on later tokens. With a tiny random DeepseekV3ForCausalLM on sdpa (dev 2ad49297, transformers 5.20.1):

before after
bridge vs HF log-probs, no padding (V3 / V2) 1.0e-1 / 1.6e-1 4.8e-7 / 4.8e-7
change in positions 0–2 when only tokens 3–5 change 6.1e-2 0
bridge vs HF on the real tokens of a left-padded batch 1.0e-1 4.8e-7

Eager models were already correct and are unchanged.

The fix replaces those three lines with AttentionBridge._apply_reconstruct_attention_mask, which the other reconstructing bridges (PositionEmbeddingsAttentionBridge, JointQKVAttentionBridge, ...) already use: a 4D mask is used as given (bool or float), otherwise the causal mask is built, with the KV-cache offset handled. The compatibility-mode -inf sentinel handling is the same as before. GlmMoeDsaAttentionBridge has its own forward and forces eager, so it is not touched.

Tests (test_mla_attention_bridge.py):

  • test_output_matches_hf already compared the bridge against the sdpa HF attention module with attention_mask=None, but with max_diff < 0.15, which was loose enough to hide the missing causal mask. It is now 1e-5 (the actual difference after the fix is around 1e-7).
  • New test_boolean_padding_mask_matches_hf passes a left-padded boolean 4D mask to both and compares the non-padded positions.

Both fail on dev and pass with the fix.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Checklist:

  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have not rewritten tests relating to key interfaces which would affect backward compatibility

Local runs: tests/unit on the locked environment (transformers 5.13.0, torch 2.11.0): 7676 passed, 0 failed; the MLA/DeepSeek/GLM-4.7-Flash/GLM-MoE-DSA unit and integration tests on both 5.13.0 and 5.20.1 (126 passed each), plus black, isort, pycln and mypy ..

HF's sdpa path calls the attention module with attention_mask=None (no
padding) or a boolean 4D mask (padding). MLAAttentionBridge only added a
float mask when one was given, so a DeepSeek-V2/V3 or GLM-4.7-Flash model
running sdpa attended bidirectionally, and a boolean mask was added as
0/1. Reuse AttentionBridge._apply_reconstruct_attention_mask like the
other reconstructing bridges.
@jlarson4
jlarson4 merged commit 91f2e7d into TransformerLensOrg:dev Oct 21, 2026
55 of 56 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants