@@ -1893,13 +1893,21 @@ def _maybe_modify_attn_mask_npu(query: torch.Tensor, key: torch.Tensor, attn_mas
18931893 if attn_mask is not None and torch .all (attn_mask != 0 ):
18941894 attn_mask = None
18951895
1896- # Reshape Attention Mask: [batch_size, seq_len_k] or [batch_size, 1, 1, seq_len_k] -> [batch_size, 1, sqe_len_q, seq_len_k]
1896+ # Reshape Attention Mask for Ascend fused attention, which does not broadcast a
1897+ # singleton query-length dim the way SDPA does.
1898+ # Supported expansions:
1899+ # [B, Skv] / [B, 1, 1, Skv] / [B, N, 1, Skv] -> [B, 1|N, Sq, Skv]
18971900 # https://www.hiascend.com/document/detail/zh/Pytorch/730/apiref/torchnpuCustomsapi/docs/context/torch_npu-npu_fusion_attention.md
18981901 if attn_mask is not None :
18991902 if attn_mask .ndim == 2 and attn_mask .shape [0 ] == query .shape [0 ] and attn_mask .shape [1 ] == key .shape [1 ]:
19001903 batch_size , seq_len_q , seq_len_kv = attn_mask .shape [0 ], query .shape [1 ], key .shape [1 ]
19011904 attn_mask = attn_mask .unsqueeze (1 ).expand (batch_size , seq_len_q , seq_len_kv ).unsqueeze (1 ).contiguous ()
1902- elif attn_mask .ndim == 4 and attn_mask .shape [1 :3 ] == (1 , 1 ):
1905+ elif (
1906+ attn_mask .ndim == 4
1907+ and attn_mask .shape [2 ] == 1
1908+ and attn_mask .shape [- 1 ] == key .shape [1 ]
1909+ ):
1910+ # Expand Sq for masks such as [B, 1, 1, Skv] or LTX cross-attn [B, N, 1, Skv].
19031911 attn_mask = attn_mask .expand (- 1 , - 1 , query .shape [1 ], - 1 ).contiguous ()
19041912
19051913 attn_mask = ~ attn_mask .to (torch .bool )
0 commit comments