Transformer Block Assembly › Causal Masking for Decoder Blocks
Language AI HandbookAll chapters Transformer Block Assembly › Causal Masking for Decoder BlocksOne section · Sections in this chapter7 / 16 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
Language models like GPT are autoregressive: they generate tokens one at a time, with each token depending only on previous tokens. This requires causal masking in attention, preventing tokens from attending to future positions.
The causal mask modifies the attention score computation. Recall that attention scores between queries and keys are computed as:
where:
- : the query vector for token at position
- : the key vector for token at position
- : the dimension of the key vectors (used for scaling)
To prevent token from attending to any future token , we add a mask to the scores before applying softmax:
where:
- if (past or current positions, allowed)
- if (future positions, blocked)
After softmax, positions with scores become exactly zero, effectively removing them from the weighted average. The result is a triangular attention pattern where each token can only "see" itself and previous tokens:
def create_causal_mask(seq_len):
"""
Create causal attention mask.
Returns a matrix where position (i, j) is -inf if j > i (future position),
and 0 otherwise. Adding this to attention scores before softmax
ensures tokens cannot attend to future positions.
"""
mask = np.triu(np.ones((seq_len, seq_len)) * float("-inf"), k=1)
return mask
# Example mask for 4 tokens
mask_example = create_causal_mask(4)Causal Mask (4 tokens): (0 = can attend, -inf = cannot attend) 0 -∞ -∞ -∞ 0 0 -∞ -∞ 0 0 0 -∞ 0 0 0 0

Decoder Block Implementation
A decoder block is identical to the standard block, but with causal masking applied during attention:
class DecoderBlock(TransformerBlock):
"""
Transformer decoder block with causal masking.
Identical to TransformerBlock but automatically applies
causal masking to prevent attending to future positions.
"""
def __call__(self, x):
"""
Process input through decoder block.
Args:
x: Input tensor of shape (seq_len, d_model)
Returns:
Output tensor of shape (seq_len, d_model)
"""
seq_len = x.shape[0]
# Create causal mask
mask = create_causal_mask(seq_len)
# Use parent class forward with mask
return super().__call__(x, mask=mask)
# Test decoder block
decoder_block = DecoderBlock(d_model=256, n_heads=4, d_ff=688, use_swiglu=True)
x_test = np.random.randn(8, 256) * 0.02
y_test = decoder_block(x_test)Decoder Block Test ======================================== Input shape: (8, 256) Output shape: (8, 256) Causal masking: enabled Parameters: 791,040