Predict the softmax output for a causal masked attention row.
Position 2 (0-indexed) in a length-4 sequence has raw attention scores [1.0, 2.0, 3.0, 4.0] before masking. Apply causal masking (position 2 can attend to positions 0, 1, 2 but NOT position 3), then softmax. What are the 4 output weights, in order?
Mask sets position 3's score to negative infinity before softmax, giving the four weights approximately 0.0900, 0.2447, 0.6652, 0.0000.
Imagine a teacher converting test scores into slices of a pie chart where every slice has to add up to one whole pie. To remove a student entirely, you can't just give them a score of zero, a zero score still claims a sliver of the pie, because the conversion rule turns zero into a real positive number first. You have to give them an impossibly bad score, think 'negative infinity bad', which then converts to no pie at all. The remaining students share the whole pie among themselves, like causal masking sweeps a future position out of the attention distribution.
Detailed answer & concept explanation~4 min readEverything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example.
Everything important, quickly.
5 min: masking step, exponentials, sum, divide; the negative-infinity vs zero distinction; max subtraction softmax stabilization; dtype-aware mask values; FlashAttention's block level masking; the all masked edge case.
import torch
scores = torch.tensor([1.0, 2.0, 3.0, 4.0])
mask = torch.tensor([0.0, 0.0, 0.0, float('-inf')])
masked_scores = scores + mask # [1, 2, 3, -inf]
weights = torch.softmax(masked_scores, dim=-1)
print(weights) # tensor([0.0900, 0.2447, 0.6652, 0.0000])
assert weights[3].item() == 0.0
assert abs(weights[:3].sum().item() - 1.0) < 1e-6Real products, models, and research that use this idea.
- PyTorch's torch.nn.functional.scaled_dot_product_attention with is_causal=True applies the canonical mask internally and selects an efficient backend.
- HuggingFace transformers uses torch.finfo(dtype).min as the mask value, which is roughly -3.4e38 for fp32.
- FlashAttention 2 and 3 skip fully masked blocks entirely and apply the boundary mask inside partial blocks to preserve the streaming accumulator's correctness.
- Karpathy's nanoGPT uses tril plus masked_fill with float('-inf') as the reference implementation pattern.
What an interviewer would ask next. Try answering before peeking at the approach.
QWhy use a large finite negative instead of literal negative infinity in production kernels?
QHow does the max subtraction stabilization handle a masked score?
Don't say thisRed flags and common mistakes that signal junior thinking. Click to expand.
Red flags and common mistakes that signal junior thinking. Click to expand.
Zero as the mask value leaks ~3% weight to the masked slot. e^0 is 1, not 0. Only negative infinity vanishes.
The night-before-the-interview bullets. Scan these on the way to the call.
Primary sources. Skim if you want the original framing.
Same topic, related formats. Practice these next.