The problem
Multi-head attention runs attentions side by side, so that each one can learn a different pattern (one head may follow grammar, another a name ten tokens back). It does not add parameters: it cuts each query, key and value vector of numbers into slices of numbers, and runs one attention per slice. The hard part is the shape work, which you will write here.
The input x has shape : texts, tokens each, numbers per token. The four weight matrices Wq, Wk, Wv, Wo have shape .
The five steps
- Project: , , , each of shape .
- Split heads: . Head takes the numbers to of every token.
- Causal attention in every head at once, on the last two axes: .
- Merge heads: undo step 2, .
- Output projection: multiply by , which mixes the heads.
Splitting, with numbers
Example. One text, tokens, , heads of . The projected queries are
x = [[[0, 1, 2, 3], [4, 5, 6, 7]]]: token 0 is[0, 1, 2, 3], token 1 is[4, 5, 6, 7].
- Head 0 must get the first two numbers of every token:
[0, 1]for token 0 and[4, 5]for token 1.- Head 1 must get the last two:
[2, 3]and[6, 7].Right:
x.reshape(1, 2, 2, 2)as cuts each token into its two halves, then.transpose(0, 2, 1, 3)gives : head 0 is[[0, 1], [4, 5]], head 1 is[[2, 3], [6, 7]].Wrong: reading the same
reshape(1, 2, 2, 2)directly as , with no transpose, makes head 0[[0, 1], [2, 3]]: the two halves of token 0, as if they were two different tokens. It runs without any error.
reshape never moves numbers: it only reads them in memory order, last axis fastest. So split the last axis first, where the numbers of a head are already next to each other, and then move the head axis into place with transpose.
What to implement
split_heads(x, n_heads): .merge_heads(x): , the exact inverse.mha_forward(x, params, n_heads): the five steps, whereparamsis a dict with"Wq","Wk","Wv","Wo".
The attention and causal_mask functions of the previous exercise are given.
Requirements
- Raise
ValueErrorif is not divisible byn_heads. - No loops over heads or batch elements.
merge_heads(split_heads(x, H))must give backxexactly.