Skip to content

Commit 1fab0ee

Browse files
committed
fix scaled_masked_softmax of reference backend
1 parent d582b36 commit 1fab0ee

1 file changed

Lines changed: 29 additions & 14 deletions

File tree

  • transformer_engine/plugin/core/backends/reference/impl

transformer_engine/plugin/core/backends/reference/impl/softmax.py

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,35 @@ def scaled_masked_softmax_forward_torch(
4444
mask: torch.Tensor,
4545
scale: float,
4646
) -> torch.Tensor:
47-
# Handle uint8 mask (CUDA format: 1=masked, 0=unmasked)
48-
# Convert to additive mask (-10000 for masked positions, 0 for unmasked)
49-
if mask.dtype == torch.uint8:
50-
additive_mask = torch.zeros_like(input, dtype=input.dtype)
51-
# Expand mask if needed (mask shape: batch, 1, seq_q, seq_k)
52-
if mask.dim() == 4 and mask.size(1) == 1 and input.dim() == 4:
53-
mask = mask.expand_as(input)
54-
additive_mask = additive_mask.masked_fill(mask.bool(), -10000.0)
55-
else:
56-
additive_mask = mask
57-
58-
scaled_input = input * scale + additive_mask
59-
60-
return F.softmax(scaled_input, dim=-1)
47+
"""Reference forward matching TE CUDA `scaled_masked_softmax_warp_forward`.
48+
49+
Integer/bool mask (same as uint8 kernel contract):
50+
- **Exactly** ``mask == 1`` means **masked** (logit set to ``-10000``, not ``input*scale`` offset).
51+
- Any other value (typically 0) means **unmasked** (logit is ``input * scale``).
52+
53+
Floating mask: treated as **additive** bias in logit space (already scaled), added after
54+
``input * scale``.
55+
56+
Common pitfalls this avoids vs the old implementation:
57+
1) ``input * scale + (-10000)`` on masked positions ≠ CUDA's plain ``-10000``.
58+
2) Non-uint8 masks (bool, int) were used as direct addends → wrong (0/1 added to logits).
59+
3) ``mask.bool()`` masks any nonzero byte; CUDA only masks when ``mask == 1``.
60+
"""
61+
if mask.dim() == 4 and mask.size(1) == 1 and input.dim() == 4:
62+
mask = mask.expand_as(input)
63+
64+
scaled = input * scale
65+
66+
if mask.is_floating_point():
67+
scaled = scaled + mask.to(dtype=scaled.dtype)
68+
return F.softmax(scaled, dim=-1)
69+
70+
# Integer / bool: align with CUDA (masked iff value == 1)
71+
scaled = scaled.masked_fill(mask == 1, -10000.0)
72+
# CUDA zeros output row when every position in the softmax dim is masked (max == -10000)
73+
all_masked = (mask == 1).all(dim=-1, keepdim=True)
74+
out = F.softmax(scaled, dim=-1)
75+
return out.masked_fill(all_masked, 0.0)
6176

6277

6378
def scaled_masked_softmax_backward_torch(

0 commit comments

Comments
 (0)