liveBook · Manning

Multi-head attention

As explained in Natural Language Processing in Action, Second Edition

Multi-head attention computes multiple attention representations in parallel and combines them, potentially using distinct query and source sequences.

A word can matter in more than one way. Multi-head attention lets a transformer compute several attention representations in parallel, so different heads can attend to different positions and patterns. In self-attention, the queries, keys, and values all come from the input sequence’s embeddings. A decoder can also attend to an encoder’s output: its target sequence supplies the queries, while the encoder output supplies the keys and values. section 9.1.2 section 9.2.3

The computation builds on scaled dot-product attention:

  • Project embeddings into queries, keys, and values. Query–key scores, scaled by 1/√dₖ and passed through softmax, weight the values. section 9.1.2
  • Run this computation across multiple heads, concatenate their outputs, and apply an output projection. The number of heads is an architecture hyperparameter; the original transformer used eight heads with 64-dimensional keys and values. section 9.1.2
  • Place the attention layer alongside a feedforward layer and normalization in a stackable transformer block. Encoder and decoder stacks use attention in different positions. section 9.2.2
Figure 9.4 Multi-head self-attention
figure

The diagram shows the parallel heads and how their results become one projected output. section 9.1.2

Inspect attention during translation

For a translation experiment, load aligned German–English sentences, tokenize the two languages, and pass source and target sequences to a PyTorch transformer. A customized decoder layer calls self-attention with the target three times, then calls multi-head attention with the target and encoder memory. It returns the latter attention weights for inspection. In the supplied test example, a German sentence about a mother and her son produces an English translation; plotted weights put source and output tokens on the axes. The plots help inspect what the model attended to, but a translation still needs evaluation on held-out data. section 9.2.3

Listing 9.5 Inspecting attention weights with customized TransformerDecoderLayer
>>> from torch import Tensor
>>> from typing import Optional, Any

>>> class CustomDecoderLayer(nn.TransformerDecoderLayer):
...     def forward(self, tgt: Tensor, memory: Tensor,
...             tgt_mask: Optional[Tensor] = None,
...             memory_mask: Optional[Tensor] = None,
...             tgt_key_padding_mask: Optional[Tensor] = None
...             ) -> Tensor:
...         """Like decode but returns multi-head attention weights."""
...         tgt2 = self.self_attn(
...             tgt, tgt, tgt, attn_mask=tgt_mask,
...             key_padding_mask=tgt_key_padding_mask)[0]
...         tgt = tgt + self.dropout1(tgt2)
...         tgt = self.norm1(tgt)
...         tgt2, attention_weights = self.multihead_attn(
...             tgt, memory, memory,                           #1
...             attn_mask=memory_mask,
...             key_padding_mask=mem_key_padding_mask,
...             need_weights=True)
...         tgt = tgt + self.dropout2(tgt2)
...         tgt = self.norm2(tgt)
...         tgt2 = self.linear2(
...             self.dropout(self.activation(self.linear1(tgt))))
...         tgt = tgt + self.dropout3(tgt2)
...         tgt = self.norm3(tgt)
...         return tgt, attention_weights           #2

The decoder-layer code makes the distinction between target self-attention and attention over encoder memory concrete. section 9.2.3

How Natural Language Processing in Action, Second Edition covers it

How deep it goes
Works through scoring, head dimensions, concatenation, and projection, then implements weight inspection through PyTorch decoder customization rather than building attention from scratch.
Examples
Uses an eight-head transformer configuration, German–English translation samples, customized decoder code, and attention-weight plots.
What it assumes
Builds on token embeddings, query–key–value self-attention, BPE, and positional encoding before assembling transformer layers.
What you can do after
Apply it via PyTorch’s Transformer modules to train a translation model and inspect decoder attention weights.
How it connects
Links self-attention and cross-attention with embeddings, positional encoding, transformer blocks, layer normalization, and machine translation.

Also explained in

Compare how 14 books explain multi-head attention →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Natural Language Processing in Action, Second Edition. The section links point to the parts of the book it draws on.