We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Attention Variants step 9 of 14
Cross-Attention Block
Cross-attention lets one sequence read another. Here the decoder sequence provides the queries, while the encoder sequence provides the keys and values. Every decoder position forms its own weighted mixture of encoder values. The two sequences can have different lengths.
This exercise adds an output projection, two residual connections, two layer normalizations and a small feed-forward network. The result stays aligned with decoder positions, even when the encoder sequence is longer.
Inputs and output
Implement cross_attention_block(decoder_x, encoder_out, w_q, w_k, w_v, w_o, w_mlp1, w_mlp2, num_heads).
decoder_x: floating-point array of shape(N, T_dec, d_model).encoder_out: floating-point array of shape(N, T_enc, d_model).- All six weight matrices: shape
(d_model, d_model). num_heads: a positive integer that dividesd_modelevenly.
All dimensions are positive. Return shape (N, T_dec, d_model). There is
no causal or padding mask: every decoder query reads every encoder position
in its own batch item. There are no biases, dropout or learned normalization
parameters. The feed-forward hidden width is d_model in this exercise.
Attention stage
- Compute
Q = decoder_x @ w_q,K = encoder_out @ w_kandV = encoder_out @ w_v. Use weights in the supplied orientation. - Set
d_head = d_model // num_heads. Split the projected feature axis into(num_heads, d_head)and swap the head and sequence axes. Q becomes(N, num_heads, T_dec, d_head); K and V become(N, num_heads, T_enc, d_head). - Multiply Q by K with only K's last two axes swapped, then divide by
sqrt(d_head). Scores have shape(N, num_heads, T_dec, T_enc). Apply a stable softmax over the final axis, which contains encoder keys. - Multiply the weights by V. Swap head and sequence axes back, then reshape
to
(N, T_dec, d_model), keeping heads in their original order. - Project the joined heads and add the decoder residual:
x = layer_norm(decoder_x + joined @ w_o).
K and V come from the encoder, but the residual comes from the decoder. Using the encoder as the residual would also fail when the lengths differ.
Feed-forward stage
Apply the network independently to each decoder position:
hidden = x @ w_mlp1
ffn_out = gelu(hidden) @ w_mlp2
output = layer_norm(x + ffn_out)
Use this elementwise tanh approximation of GELU, where ** denotes a power:
gelu(t) = 0.5 * t * (1 + tanh(sqrt(2 / pi) * (t + 0.044715 * t**3)))
Do not substitute the exact normal-CDF version of GELU; it gives slightly different values.
Normalization and shape checks
Both calls to layer_norm subtract the mean over the final feature axis
and divide by sqrt(population_variance + 1e-5). Population variance is
the mean squared deviation, with divisor d_model. Keep batch and sequence
positions separate, and add no learned scale or offset.
Both normalizations follow their residual additions. Even if both branches
output zeros, the specified result is layer_norm(layer_norm(decoder_x)).
Do not skip the second normalization: epsilon means it is not exactly redundant.
For T_dec = 2 and T_enc = 3, each head has a 2-by-3 score matrix and
produces two output vectors. The cross-attention panel below shows this
rectangular pattern with different example lengths. Filled cells show allowed
connections, not their attention weights.
Loading visualization…
Understand the ideas behind this exercise. The Problem tab contains the exact implementation requirements.
Combine attention with a feed-forward network
A transformer block uses attention to combine information across token positions. Its feed-forward network transforms features at each position independently, usually using shared weights across positions. Residual connections add a sublayer's output to its input, and normalization controls the values seen by that sublayer or passed to the next one.
Split attention into heads
Multi-head attention projects inputs into queries, keys, and values for several heads. Each head computes its own attention result. The block concatenates those results and applies an output projection.
For shape (batch, time, heads * head_width), first reshape to
(batch, time, heads, head_width), then move the head axis if the attention
operation expects (batch, heads, time, head_width). A reshape alone cannot
exchange time and head axes while preserving their meanings.
Match masks to the source of the keys
In self-attention, queries, keys, and values come from the same sequence. In encoder-decoder cross-attention, decoder states supply queries and encoder outputs supply keys and values. Output length follows the queries, even when the source sequence has a different length.
A causal mask blocks future keys in decoder self-attention. Cross-attention to an available encoder sequence usually needs a source-padding mask instead. Use the mask appropriate to the information the model is allowed to read.
Keep normalization in the specified place
Pre-normalization computes x + F(Norm(x)). Post-normalization computes
Norm(x + F(x)). Moving the normalization changes the function.
The same applies to replacing LayerNorm with RMSNorm or changing the feed-forward activation to SwiGLU. Follow the exercise's equations rather than filling in details from another model with a similar name. Write each intermediate shape, and check residual additions, packed weight order, epsilon, and activations.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
JAX reference solution
Sign in to track your attempts toward unlocking the reference solution.