★ FOUR BRAND-NEW COURSES ANNOUNCED! ★ Machine Learning End To End  •  Hands-On Deep Learning with Python  •  Generative AI & LLMs with Python  •  AI Agents and Agentic AI with Python  ★  Open the “Educational” menu above to explore them ★  ★  NEW! 5. JOB ASSISTANCE: JD Report • Resume customization • AI Mock Interviews — FREE with course bundles, or just ₹499 / US$5. Single Payment. No Subscription. ★★ FOUR BRAND-NEW COURSES ANNOUNCED! ★ Machine Learning End To End  •  Hands-On Deep Learning with Python  •  Generative AI & LLMs with Python  •  AI Agents and Agentic AI with Python  ★  Open the “Educational” menu above to explore them ★  ★  NEW! 5. JOB ASSISTANCE: JD Report • Resume customization • AI Mock Interviews — FREE with course bundles, or just ₹499 / US$5. Single Payment. No Subscription. ★★ FOUR BRAND-NEW COURSES ANNOUNCED! ★ Machine Learning End To End  •  Hands-On Deep Learning with Python  •  Generative AI & LLMs with Python  •  AI Agents and Agentic AI with Python  ★  Open the “Educational” menu above to explore them ★  ★  NEW! 5. JOB ASSISTANCE: JD Report • Resume customization • AI Mock Interviews — FREE with course bundles, or just ₹499 / US$5. Single Payment. No Subscription. ★★ FOUR BRAND-NEW COURSES ANNOUNCED! ★ Machine Learning End To End  •  Hands-On Deep Learning with Python  •  Generative AI & LLMs with Python  •  AI Agents and Agentic AI with Python  ★  Open the “Educational” menu above to explore them ★  ★  NEW! 5. JOB ASSISTANCE: JD Report • Resume customization • AI Mock Interviews — FREE with course bundles, or just ₹499 / US$5. Single Payment. No Subscription. ★

Self-attention: every word looks at every other word

Self-attention: every word looks at every other word
12-10-2026  |  By Tejas Desai, Ecube Analytics  |  Generative AI: Transformer on-ramp (Chapter 1)  |  3 min read
READ 4TH OF 8 IN THIS SERIES

Self-attention: every word looks at every other word

Transformer on-ramp · Part 4 of 8

A transformer reads a sentence by letting every word ask every other word one question: “how much should I pay attention to you?” That one idea, self-attention, is what separates it from everything before.

Three roles for every token

For each token, the model builds three vectors from its embedding, using three separate learned projections:

  • a query: what am I looking for?
  • a key: what do I offer?
  • a value: what do I actually contribute if someone attends to me?

To update one token, take its query, compare it with every token’s key, turn the comparison scores into weights that add up to 1, and use those weights to blend the values. In one line:

Attention(Q, K, V) = softmax( Q·K? / ?dk ) · V

Self-attention, step by stepToken vectors are projected into queries, keys and values. Query-key scores are scaled, turned into weights by softmax, and used to mix the values.Xtoken vectorsQ = X·W_qK = X·W_kV = X·W_vQ·K? ÷ ?d_kscoressoftmaxrows sum to 1× VnewvectorsHow much does the word “it” listen to each word? (illustrative weights)animal0.52cross0.08because0.06it0.14tired0.20
Top: the pipeline for one attention layer. Bottom: what the weights could look like for the word “it” (illustrative numbers). Most of its attention goes to “animal”.

Why divide by √dk?

A score is a dot product of two vectors of length d. If each number has spread 1, the dot product has spread about √d: the bigger the vectors, the bigger the scores. Large scores make softmax almost a hard choice and leave it with almost no gradient to learn from. Dividing by √d keeps the scores in a sensible range at every size. Measured with random vectors (64 keys per query, 2,000 queries):

Vector size dSpread of scores (theory √d)Largest weight, no scalingLargest weight, with √d
164.00 (4.00)0.5810.108
648.01 (8.00)0.7860.107
25616.00 (16.00)0.8980.106
102431.94 (32.00)0.9490.107

Without scaling, at d = 1,024 the biggest weight is already 0.95 for random inputs: the layer is making a near-hard choice before it has learned anything. With scaling the picture is the same at every size, so one learning rate works as the model grows.

Try it yourself

import torch
torch.manual_seed(0)
for d in (16, 64, 256, 1024):
    q = torch.randn(2000, d); k = torch.randn(2000, 64, d)   # 2,000 queries, 64 keys each
    s = torch.einsum('qd,qkd->qk', q, k)                    # raw scores
    raw, scaled = s.softmax(-1), (s / d**0.5).softmax(-1)
    print(d, f"spread {s.std():.2f}",
          f"top weight raw {raw.max(-1).values.mean():.3f}",
          f"scaled {scaled.max(-1).values.mean():.3f}")

Open in Colab A small notebook with the tiny worked example and this experiment. Runs free in your browser.

One idea to keep. Attention is a soft lookup: the query asks, the keys answer how relevant they are, and the values are what actually gets copied across.

Takeaways

  • Each token makes a query, a key and a value from its embedding.
  • Query–key scores become weights (softmax); the weights blend the values.
  • Dividing by √dk stops scores from growing with vector size and saturating softmax.
  • Without it, at d = 1,024 the top weight is already 0.95 on random inputs.

Next in the series (Part 5): Self-attention from scratch in PyTorch

This blog is from chapter 1, course-2-generative-ai of 4 world-class courses on aibits.ecubeanalytics.com
← Previous Article 4 of 8 in this series Next →