Day 94 ยท Everyone looks at everyone

Attention

You will be able to
  • Explain the bottleneck attention solves: fixed vectors cannot carry context-dependent meaning
  • Describe queries, keys, and values as a soft, differentiable lookup
  • Hand-compute scaled dot-product attention on a 4-token example, exactly
  • Implement attention in NumPy and verify it against your hand computation
  • Explain why scores are scaled by โˆšd_k and what multiple heads add
Today's ~120 minutes
Spaced-rep warm-up: Days 92โ€“93 cards10 min
ELI5 + tech read; 3B1B attention chapter; attention-heat visualizer30 min
Guided: hand computation, NumPy verification + heatmaps45 min
Practice: the jam disambiguation20 min
Quiz + flashcards + commit attention_lab.py15 min

Builds on: Day 92 โ€” Embeddings & dot-product similarity ยท Day 93 โ€” word2vec's polysemy ceiling ยท Day 62 โ€” Softmax & distributions

The analogy

Watch a good meeting. Before speaking, each person glances around the table and weighs everyone's input: for THIS question, the finance person's comment matters 45%, the two engineers 22% each, the intern's 11%. Their eventual statement is a blend of what they heard, weighted by relevance โ€” and for the NEXT question, the weights change completely. Nobody has a fixed importance; importance is negotiated per question.

Attention runs this meeting between words. Yesterday's problem: "jam" had one frozen vector, torn between traffic and strawberries. Attention thaws it. Every token broadcasts three things: a query โ€” "here's what I'm looking for" โ€” a key โ€” "here's what I offer" โ€” and a value โ€” "here's my actual content." Each token compares its query with everyone's keys (a dot product โ€” Day 92's similarity), converts the match scores into percentages with a softmax, and then takes a weighted blend of everyone's values. In "traffic jam," the token "jam" finds "traffic" highly relevant and blends it in; its output vector now MEANS traffic-jam. Same word, different sentence, different vector. That per-occurrence renegotiation โ€” everyone looks at everyone, every time โ€” is the single mechanism the last decade of AI is built on, and today you compute one by hand, to the third decimal.

Why this matters on the job

Attention is the "T" in GPT and the operation your future stack spends most of its money on: context windows are priced by it, long-document costs explode quadratically because of it (Day 101), and KV caching (Day 155) exists to avoid recomputing it. When you debug a model that ignores the middle of a long prompt or explain to a customer why doubling context more than doubles cost, you are reasoning about today's mechanism. Interviews test it constantly, and the difference between reciting "queries, keys, values" and having COMPUTED one is immediately audible.

Watch it happen

Attention weights โ€” every token looks at every earlier token

step 1 / 5
Thecatsatdown
The1.0โ€”โ€”โ€”
cat.2.8โ€”โ€”
sat.1.6.3โ€”
down.05.15.7.1

Four tokens: "The cat sat down". Each row asks: while processing ME, how much should I look at each column?the โ€” cells: causal mask. A token can't see the future.

Guided practice

guided 1

The hand computation โ€” every digit yours

25 min
  1. On paper, reproduce the worked example WITHOUT looking at the tech section: given q4 = [1,1], keys k1..k4 = [1,0],[0,1],[1,1],[0,0], values v1..v4 = [1,0],[0,2],[2,2],[0,0].
  2. Compute the four dot-product scores. Scale by โˆš2. (Keep 3 decimals.)
  3. Softmax: exponentiate (e^0.707 โ‰ˆ 2.028, e^1.414 โ‰ˆ 4.113), sum, divide. You must get [0.221, 0.221, 0.449, 0.109].
  4. Blend the values: output โ‰ˆ [1.12, 1.34]. Check against the tech section only when done.
  5. Repeat for token 2, whose query is q2 = [0, 2]: scores come out [0, 2, 2, 0], scaled to [0, 1.414, 1.414, 0]. Finish the softmax and blend yourself โ€” you should land on weights โ‰ˆ [0.098, 0.402, 0.402, 0.098]. Exercise 2's code will confirm.
  6. One sentence: why must each row of attention weights sum to 1?
guided 2

NumPy attention โ€” verify, then heatmap

20 min
  1. Implement attention(Q, K, V) in NumPy exactly as the formula reads: scores = Q @ K.T / sqrt(d_k); rowwise softmax; weights @ V.
  2. Run it on the full 4-token example (starter) and confirm row 4 of the weights is [0.221, 0.221, 0.449, 0.109] and row 4 of the output is [1.12, 1.34] โ€” your paper, vindicated. Also read off row 2 to check your step-5 answer.
  3. Print an ASCII heatmap of the weight matrix (starter helper): darker = higher weight. Identify visually which token attends most to which.
  4. Remove the โˆšd_k scaling and reprint the heatmap: rows sharpen. Now set d_k = 64 with random Q/K scaled up accordingly and compare softmax outputs with and without scaling โ€” saturation appears.
๐Ÿ python โ€” editable, runs in your browser
Ctrl/โŒ˜+Enter runs ยท Tab indents ยท numpy/pandas/sklearn auto-load on import (torch and network calls need a local run)

On your own

Make "jam" mean two things

20 min

Close the loop on Day 93's polysemy demo โ€” with hand-set vectors, no training. Design a 3-token mini-world: token "jam" plus context token "traffic" OR "strawberry". Give "jam" a neutral value vector, give the two context words value vectors pointing in opposite directions (e.g. [3, 0] vs [0, 3]), and set keys/queries so that jam's query matches whichever context token is present. Run your attention() on the sequence [traffic, jam] and on [strawberry, jam], and show jam's OUTPUT vector differs strongly between the two โ€” the same input embedding, disambiguated by context.

Constraints: use your attention() unchanged; print both output vectors and their cosine similarity (should be low).

Hints: give both context tokens the same key (say [1, 0]) and jam a query aligned with it ([2, 0]) โ€” the mechanism does the rest through the values.

Ship before you stop

attention_lab.py โ€” the artifact interviews are made of

Commit attention_lab.py: softmax (stable), attention() with a scale toggle, the verified 4-token example asserting the hand-computed row ([0.221, 0.221, 0.449, 0.109] and [1.12, 1.34] within 0.005), the ASCII heatmap, the d_k = 64 saturation demonstration (print max softmax weight with and without scaling), and the jam-disambiguation demo. Add a 10-line README section: the meeting analogy in your own words, then Q/K/V in one sentence each. Day 95 imports attention() into a transformer block and Day 97 reimplements it with trainable weights in PyTorch โ€” this file is the reference they are checked against.

Rubric โ€” check what you completed (0/6)

Common mistakes & misconceptions

  • Memorizing "Q, K, V" without roles. Query = what I seek; key = what I advertise; value = what I hand over if matched. If you can't assign these in a sentence, re-run the meeting analogy.
  • Forgetting softmax normalizes per ROW. Each token distributes exactly 100% of its attention across all tokens; columns need not (and don't) sum to anything.
  • Dropping the โˆšd_k "because it barely changes my toy numbers." At d_k = 64+ it is the difference between training and a saturated, gradient-dead softmax.
  • Thinking attention weights are THE explanation of model behavior. They show information routing in one layer of many; treat heatmaps as evidence, not verdicts.
  • Believing values are redundant with keys. Keys are for MATCHING, values are the CONTENT delivered โ€” the jam demo only works because they differ.
  • Missing the quadratic cost: n tokens โ†’ nร—n score matrix. This single fact drives context pricing, long-context research, and Day 155's KV cache.
Knowledge check

Q1. In the worked example, token 4's weights were [0.221, 0.221, 0.449, 0.109]. What produced the 0.449?

Q2. Why divide scores by โˆšd_k?

Q3. Doubling the sequence length from 1,000 to 2,000 tokens does what to the attention score computation?

Go deeper โ€” curated resources

articleJay Alammar โ€” The Illustrated Transformer (attention sections) โ†—30 minpaperAttention Is All You Need (Vaswani et al., 2017) โ€” ยง3.2 only today โ†—20 minvideo3Blue1Brown NN playlist โ€” the attention chapter, visually โ†—25 minbookDive into Deep Learning โ€” attention mechanisms chapter โ†—20 min
If you have a third hour
  • Cross-attention vs self-attention โ€” In translation-style encoder-decoders, queries come from one sequence and keys/values from another โ€” the same formula, different table. You'll recognize it instantly in the Illustrated Transformer's decoder figures tomorrow.
Done means
  • Hand computation done unaided and verified to 3 decimals (both rows)
  • attention() asserts against the worked example; heatmaps rendered and read
  • Saturation demo and jam demo both committed in attention_lab.py
  • Quiz โ‰ฅ 2/3
How this connects

โ† Back: The scores are Day 92's dot-product similarity; the weighting is Day 62's softmax; the saturation danger is Day 86's vanishing-gradient lesson; and the whole mechanism answers the polysemy ceiling Day 93 ended on.

Forward โ†’: Day 95 wraps attention with positions, residuals, and FFNs into the transformer block; Day 97 gives Q/K/V trainable weights in your GPT; Day 101 prices the nยฒ you met today; Day 155's KV cache banks the K and V you just computed.

Unlocks: D95 The Transformer ยท D97 Tiny GPT Lab I โ€” Build It ยท D98 Week 14 Checkpoint: Attention, Locked In ยท D101 Scaling Laws, Capabilities & Limits