Paper Decode

Decoding 'Attention Is All You Need': Scaled Dot-Product & Multi-Head Mechanisms

Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Łukasz Kaiser, Illia Polosukhin
NeurIPS 2017•2026-09-18•View PDF
Executive Summary
  • Core Innovation: Replaces recurrent neural networks (RNNs) and convolution entirely with self-attention mechanisms, enabling massive parallelization during training.
  • Key Equation: Attention(Q,K,V)=softmax(QKTdk)V\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V
  • Why Scaling Matters: Scaling by 1dk\frac{1}{\sqrt{d_k}} prevents dot products from growing excessively large in high dimensions, keeping gradients out of regions with extremely small softmax derivatives.

1. The Core Motivation

Prior to Transformers, dominant sequence transduction models relied on complex recurrent or convolutional neural networks (LSTMs, GRUs). While effective, sequential computation creates a fundamental bottleneck:

Sequential Bottleneck: Computing hidden state hth_t strictly requires ht−1h_{t-1}. This precludes parallelization within training examples, becoming critical at longer sequence lengths NN.

The Transformer discards recurrence entirely, drawing connections between all positions in constant O(1)O(1) sequential operations.


2. Scaled Dot-Product Attention

The model maps a query QQ and a set of key-value pairs (K,V)(K, V) to an output vector. When dimensions are large, the dot product QKTQK^T grows large in magnitude, pushing the softmax function into regions with tiny gradients.

To counteract this, the inner product is scaled by the inverse square root of key dimension dkd_k:

Attention(Q,K,V)=softmax(QKTdk)V\text{Attention}(Q,K,V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V

PyTorch Implementation

Here is how scaled dot-product attention is implemented in code:

import torch
import torch.nn as nn
import math
 
def scaled_dot_product_attention(query, key, value, mask=None):
    d_k = query.size(-1)
    
    # Compute raw attention scores: (batch, heads, seq_len, seq_len)
    scores = torch.matmul(query, key.transpose(-2, -1)) / math.sqrt(d_k)
    
    if mask is not None:
        scores = scores.masked_fill(mask == 0, -1e9)
        
    # Softmax along key dimension
    p_attn = torch.softmax(scores, dim=-1)
    
    # Weight values by attention probabilities
    return torch.matmul(p_attn, value), p_attn

3. Multi-Head Attention

Instead of performing a single attention function with dmodeld_{\text{model}}-dimensional keys, queries, and values, Multi-Head Attention projects Q,K,VQ, K, V linearly hh times with different learned linear projections to dk,dk,dvd_k, d_k, d_v dimensions:

MultiHead(Q,K,V)=Concat(head1,…,headh)WO\text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, \dots, \text{head}_h)W^O

where headi=Attention(QWiQ,KWiK,VWiV)\text{head}_i = \text{Attention}(QW_i^Q, KW_i^K, VW_i^V).

This allows the model to jointly attend to information from different representation subspaces at different positions.