Skip to content

Commit d77a8f5

Browse files
author
xfeng
committed
Fix Ascend NPU RMSNorm and fused-attention mask shapes
1 parent ed58810 commit d77a8f5

2 files changed

Lines changed: 17 additions & 7 deletions

File tree

src/diffusers/models/attention_dispatch.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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)

src/diffusers/models/normalization.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -539,13 +539,15 @@ def __init__(self, dim, eps: float, elementwise_affine: bool = True, bias: bool
539539
self.bias = nn.Parameter(torch.zeros(dim))
540540

541541
def forward(self, hidden_states):
542-
if is_torch_npu_available():
542+
# `npu_rms_norm` requires a gamma tensor. Models that disable the affine
543+
# transform (e.g. LTX-2 with `elementwise_affine=False`) keep
544+
# `self.weight is None` and must fall back to the pure PyTorch path.
545+
if is_torch_npu_available() and self.weight is not None:
543546
import torch_npu
544547

545-
if self.weight is not None:
546-
# convert into half-precision if necessary
547-
if self.weight.dtype in [torch.float16, torch.bfloat16]:
548-
hidden_states = hidden_states.to(self.weight.dtype)
548+
# convert into half-precision if necessary
549+
if self.weight.dtype in [torch.float16, torch.bfloat16]:
550+
hidden_states = hidden_states.to(self.weight.dtype)
549551
hidden_states = torch_npu.npu_rms_norm(hidden_states, self.weight, epsilon=self.eps)[0]
550552
if self.bias is not None:
551553
hidden_states = hidden_states + self.bias

0 commit comments

Comments
 (0)