Attention Mechanisms & The Transformer

Derive the mathematical variance proof of the 1/sqrt(d_k) scaling factor in self-attention, trigonometric linear shift properties of sinusoidal positional encodings, and zero-dependency implementations in Python and Rust.

03. Deep Learning, CNNs & Transformer Architectures9 min read

Before 2017, sequence-to-sequence modeling relied on recurrent architectures that compressed variable-length source sentences into a single fixed-size bottleneck vector hTh_T.

Vaswani et al. (2017) eliminated recurrence entirely in "Attention Is All You Need", introducing the Transformer. By replacing sequential unrolling with pairwise Scaled Dot-Product Self-Attention, Transformers enable massive GPU parallelization and direct O(1)O(1) path length between any two tokens across time.

Variance NormalizationTransformer Mathematics
Var(Q K^T / sqrt(d_k)) = 1.0

Dividing dot products by sqrt(d_k) prevents softmax saturation and vanishing gradients.

1. Scaled Dot-Product Attention Formulation#

Let sequence representations be packed into matrix X∈RT×dmodelX \in \mathbb{R}^{T \times d_{\text{model}}} of TT tokens.

We project XX using three learnable parameter matrices:

  • Queries: Q=XWQ∈RT×dkQ = X W_Q \in \mathbb{R}^{T \times d_k}
  • Keys: K=XWK∈RT×dkK = X W_K \in \mathbb{R}^{T \times d_k}
  • Values: V=XWV∈RT×dvV = X W_V \in \mathbb{R}^{T \times d_v}
Architecture Diagram
Rendering diagram...

The canonical Scaled Dot-Product Attention equation is:

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

Where softmax(A)i,j=exp⁡(Ai,j)∑m=1Texp⁡(Ai,m)\text{softmax}(A)_{i,j} = \frac{\exp(A_{i,j})}{\sum_{m=1}^T \exp(A_{i,m})}.

2. Mathematical Proof: The 1dk\frac{1}{\sqrt{d_k}} Scaling Factor#

Why is the dot-product matrix QKTQ K^T scaled specifically by the inverse square root of key dimension dkd_k?

Consider a query vector q∈Rdkq \in \mathbb{R}^{d_k} and key vector k∈Rdkk \in \mathbb{R}^{d_k}. Assume their scalar components qiq_i and kik_i are independent random variables with zero mean and unit variance:

E[qi]=0,Var(qi)=1,E[ki]=0,Var(ki)=1\mathbb{E}[q_i] = 0, \quad \text{Var}(q_i) = 1, \qquad \mathbb{E}[k_i] = 0, \quad \text{Var}(k_i) = 1

The dot product is the sum of dkd_k scalar products:

S=qTk=∑i=1dkqikiS = q^T k = \sum_{i=1}^{d_k} q_i k_i
1

Step 1: Compute the Expected Value

Because qiq_i and kik_i are independent:

E[S]=∑i=1dkE[qiki]=∑i=1dkE[qi]E[ki]=∑i=1dk(0⋅0)=0\mathbb{E}[S] = \sum_{i=1}^{d_k} \mathbb{E}[q_i k_i] = \sum_{i=1}^{d_k} \mathbb{E}[q_i] \mathbb{E}[k_i] = \sum_{i=1}^{d_k} (0 \cdot 0) = 0
2

Step 2: Compute the Variance of a Single Product $q_i k_i$

Using the variance identity for independent variables:

Var(qiki)=Var(qi)Var(ki)+Var(qi)(E[ki])2+Var(ki)(E[qi])2\text{Var}(q_i k_i) = \text{Var}(q_i) \text{Var}(k_i) + \text{Var}(q_i)(\mathbb{E}[k_i])^2 + \text{Var}(k_i)(\mathbb{E}[q_i])^2

Substituting zero means and unit variances:

Var(qiki)=(1⋅1)+(1⋅0)+(1⋅0)=1\text{Var}(q_i k_i) = (1 \cdot 1) + (1 \cdot 0) + (1 \cdot 0) = 1
3

Step 3: Compute the Variance of the Sum

Because the dkd_k terms are mutually independent:

Var(S)=Var(∑i=1dkqiki)=∑i=1dkVar(qiki)=∑i=1dk1=dk\text{Var}(S) = \text{Var}\left( \sum_{i=1}^{d_k} q_i k_i \right) = \sum_{i=1}^{d_k} \text{Var}(q_i k_i) = \sum_{i=1}^{d_k} 1 = d_k

The standard deviation of the raw dot product is:

StdDev(S)=Var(S)=dk\text{StdDev}(S) = \sqrt{\text{Var}(S)} = \sqrt{d_k}
4

Step 4: Scale to Restore Unit Variance

For large head dimensions (e.g. dk=64d_k = 64 or 128128), the standard deviation is 88 to 11.311.3. Raw dot products grow large in magnitude, driving the softmax function into regions with near-zero gradients.

Dividing by dk\sqrt{d_k}:

Var(Sdk)=Var(S)(dk)2=dkdk=1.0\text{Var}\left( \frac{S}{\sqrt{d_k}} \right) = \frac{\text{Var}(S)}{(\sqrt{d_k})^2} = \frac{d_k}{d_k} = 1.0

Scaling by 1dk\frac{1}{\sqrt{d_k}} preserves unit variance into the softmax regardless of feature dimensionality dkd_k.

3. Sinusoidal Positional Encoding & Linear Relative Shifts#

Because self-attention computes dot products symmetrically across all pairs, the permutation of input tokens XX yields identical attention scores (permutation equivariance).

To supply positional order, Vaswani et al. add fixed sinusoidal encodings PE∈RT×dmodelPE \in \mathbb{R}^{T \times d_{\text{model}}}:

PE(pos,2i)=sin⁡(pos100002i/dmodel)PE_{(pos, 2i)} = \sin\left( \frac{pos}{10000^{2i / d_{\text{model}}}} \right)
PE(pos,2i+1)=cos⁡(pos100002i/dmodel)PE_{(pos, 2i+1)} = \cos\left( \frac{pos}{10000^{2i / d_{\text{model}}}} \right)

Where pos∈{0,…,T−1}pos \in \{0, \dots, T-1\} is token position and i∈{0,…,dmodel/2−1}i \in \{0, \dots, d_{\text{model}}/2 - 1\} is feature channel.

Mathematical Proof of Relative Linear Shift#

For any fixed offset kk, can the model attend to relative position pos+kpos + k using a linear transformation?

Recall the trigonometric addition formulas:

sin⁡(α+β)=sin⁡(α)cos⁡(β)+cos⁡(α)sin⁡(β)\sin(\alpha + \beta) = \sin(\alpha)\cos(\beta) + \cos(\alpha)\sin(\beta)
cos⁡(α+β)=cos⁡(α)cos⁡(β)−sin⁡(α)sin⁡(β)\cos(\alpha + \beta) = \cos(\alpha)\cos(\beta) - \sin(\alpha)\sin(\beta)

Let ωi=1100002i/dmodel\omega_i = \frac{1}{10000^{2i / d_{\text{model}}}}. We can represent PE(pos+k,2i)PE_{(pos + k, 2i)} and PE(pos+k,2i+1)PE_{(pos + k, 2i+1)} as a rotation matrix acting on PEposPE_{pos}:

[PE(pos+k,2i)PE(pos+k,2i+1)]=[cos⁡(kωi)sin⁡(kωi)−sin⁡(kωi)cos⁡(kωi)][PE(pos,2i)PE(pos,2i+1)]\begin{bmatrix} PE_{(pos + k, 2i)} \\ PE_{(pos + k, 2i+1)} \end{bmatrix} = \begin{bmatrix} \cos(k \omega_i) & \sin(k \omega_i) \\ -\sin(k \omega_i) & \cos(k \omega_i) \end{bmatrix} \begin{bmatrix} PE_{(pos, 2i)} \\ PE_{(pos, 2i+1)} \end{bmatrix}

Because the rotation matrix depends solely on offset kk and not on absolute position pospos, the self-attention mechanism can easily learn to attend to relative distances.

4. From-Scratch Implementation: Zero Dependencies#

The following implementations construct the complete Scaled Dot-Product Attention mechanism (including numerically stable softmax and value aggregation) from scratch in pure Python and pure Rust.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import math from typing import List class AttentionFromScratch: @staticmethod def _dot(a: List[float], b: List[float]) -> float: return sum(x * y for x, y in zip(a, b)) @staticmethod def _softmax(row: List[float]) -> List[float]: # Numerical stability: subtract max(row) max_val = max(row) exp_vals = [math.exp(x - max_val) for x in row] sum_exp = sum(exp_vals) return [v / sum_exp for v in exp_vals] @classmethod def scaled_dot_product_attention( cls, Q: List[List[float]], K: List[List[float]], V: List[List[float]] ) -> List[List[float]]: # Q: [T, d_k], K: [T, d_k], V: [T, d_v] T = len(Q) d_k = len(Q[0]) d_v = len(V[0]) scale = 1.0 / math.sqrt(d_k) # 1. Compute Q * K^T / sqrt(d_k) scores = [[0.0] * T for _ in range(T)] for i in range(T): for j in range(T): scores[i][j] = cls._dot(Q[i], K[j]) * scale # 2. Row-wise Softmax to compute attention weights attention_weights = [cls._softmax(row) for row in scores] # 3. Multiply weights by V: [T, T] * [T, d_v] -> [T, d_v] output = [[0.0] * d_v for _ in range(T)] for i in range(T): for col in range(d_v): output[i][col] = sum(attention_weights[i][j] * V[j][col] for j in range(T)) return output if __name__ == "__main__": # Sequence of 3 tokens with d_k = 4, d_v = 2 Q = [ [1.0, 0.0, 1.0, 0.0], [0.0, 2.0, 0.0, 1.0], [1.0, 1.0, 1.0, 1.0] ] K = [ [1.0, 0.0, 1.0, 0.0], [0.0, 2.0, 0.0, 1.0], [1.0, 1.0, 1.0, 1.0] ] V = [ [10.0, 1.0], [20.0, 2.0], [30.0, 3.0] ] out = AttentionFromScratch.scaled_dot_product_attention(Q, K, V) print("Scaled Dot-Product Attention Output (3x2):") for row in out: print(" ", [round(v, 4) for v in row])

5. Active Knowledge Checks#

Concept check

Why does multiplying two zero-mean, unit-variance vectors q, k in R^(d_k) produce a dot product with variance d_k rather than 1.0?

Concept check

How do sinusoidal positional encodings enable the attention mechanism to attend to relative token offsets k?