v9.1.1
Menu

Multi-Head Attention

mediumFREEAttention MechanismsLLM 1: Foundations

Implement multi-head attention by splitting Q, K, V into multiple heads.

Given Q, K, V of shape (n, d) and number of heads h:

  1. Split each into h heads: reshape (n, d) → (n, h, d/h) → (h, n, d/h)
  2. Apply scaled dot-product attention per head: softmax(QiKiTd/h)Vi\text{softmax}\left(\frac{Q_i K_i^T}{\sqrt{d/h}}\right) V_i, with the softmax taken over each row (the scale uses the per-head width d/hd/h, not dd)
  3. Concatenate heads: (h, n, d/h) → (n, d)

Assume d is divisible by h. No linear projections needed — just split and concat.

Input: multi_head_attention(Q, K, V, h) where Q, K, V are NumPy arrays of shape (n, d) and h is the number of heads.

Output: Multi-head attention output as an (n, d) array; the tests print each value to 4 decimal places.

Example

Input
2 4 2
1 0 0 1
0 1 1 0
1 0 0 1
0 1 1 0
1 2 3 4
5 6 7 8
Output
[2.3210 3.3210 4.3210 5.3210]
[3.6790 4.6790 5.6790 6.6790]
Reasoning
  • Inputs: QQ, KK, VV are 2×42 \times 4 (two tokens, d=4d = 4 features) and h =2= 2, so each head owns d/h=2d/h = 2 consecutive features: head 1 the first two columns, head 2 the last two. That gives Q1=K1=IQ_1 = K_1 = I, Q2=K2=[0110]Q_2 = K_2 = \begin{bmatrix}0&1\\1&0\end{bmatrix}, V1=[1256]V_1 = \begin{bmatrix}1&2\\5&6\end{bmatrix}, V2=[3478]V_2 = \begin{bmatrix}3&4\\7&8\end{bmatrix}.
  • Scores: each head scales by d/h=2\sqrt{d/h} = \sqrt{2}, not d\sqrt{d}. Both Q1K1TQ_1K_1^T and Q2K2TQ_2K_2^T equal II, so both heads score [0.7071000.7071]\begin{bmatrix}0.7071&0\\0&0.7071\end{bmatrix}.
  • Row softmax: e0.7071e0.7071+e0=2.02813.0281=0.6698\frac{e^{0.7071}}{e^{0.7071}+e^{0}} = \frac{2.0281}{3.0281} = 0.6698, each token puts 0.66980.6698 on itself and 0.33020.3302 on the other.
  • Weighted values: token 1 gets 0.6698⋅[1,2]+0.3302⋅[5,6]=[2.3210,3.3210]0.6698\cdot[1,2] + 0.3302\cdot[5,6] = [2.3210, 3.3210] from head 1 and 0.6698⋅[3,4]+0.3302⋅[7,8]=[4.3210,5.3210]0.6698\cdot[3,4] + 0.3302\cdot[7,8] = [4.3210, 5.3210] from head 2; token 2 gets [3.6790,4.6790][3.6790, 4.6790] and [5.6790,6.6790][5.6790, 6.6790].
  • Output: each token's two head results sit side by side, rounded to 4 decimal places: [2.3210 3.3210 4.3210 5.3210] and [3.6790 4.6790 5.6790 6.6790].
  • Notice head 2's values are exactly head 1's plus 2: V2=V1+2V_2 = V_1 + 2 and every row of weights sums to 1.

Constraints

  • d is divisible by h
  • 1 <= h <= d, 1 <= n <= 10
  • No projection matrices — just split/concat
  • Round to 4 decimal places

Learn this in

More from LLM 1: Foundations

solution.py

Test results

Sign in to run your code against the test cases.