Visual walkthrough — Scaled dot-product attention
This page rebuilds the parent result Scaled Dot-Product Attention from absolute zero, one picture at a time. We start with nothing but arrows on a page, and end holding the full formula
Every symbol here is earned before it is used. If you have never seen a dot product, a softmax, or a matrix, start reading at line one — you lose nothing.
Step 1 — A word is an arrow
WHAT. Before any attention, we must agree what a "word" even is to the machine. Each word (or token) is turned into a list of numbers — a vector. Draw that list as an arrow from the origin: the direction the arrow points is the meaning.
WHY. We need meaning to live somewhere we can do arithmetic. Arrows can be added, stretched, and — crucially for Step 2 — compared by direction. Plain words can't.
PICTURE. Two arrows below. The amber arrow is a query — "the thing currently looking for information". The cyan arrows are keys — "things on the shelf that might answer". Notice leans toward and away from .

Step 2 — "How well do you match?" is a dot product
WHAT. We need a single number that says how aligned the query arrow is with a key arrow. That number is the dot product:
Read it term by term: pair up matching coordinates, multiply each pair, add all the products. One number falls out.
WHY this tool and not another? We could have measured distance between arrow tips instead. But we want alignment, not closeness, and we want it cheap and smooth (differentiable, so Gradient Descent can push on it). The dot product costs only multiplies and has a beautiful geometric meaning:
where is the angle between the arrows and means the length of . So the dot product literally reads off the angle:
- arrows point the same way (, ) → large positive number → strong match,
- arrows are perpendicular (, ) → zero → unrelated,
- arrows point opposite (, ) → large negative number → anti-match.
PICTURE. The same arrows, now with the angle marked and the three sign-cases spelled out. This is the "compatibility score" the parent note calls .

Step 3 — Doing all comparisons at once:
WHAT. Real inputs have many queries and many keys. Stack the query arrows as rows of a grid (that grid is a matrix), and the key arrows as rows of . We want every query dotted with every key. That whole table of dot products is written
Reading the symbols. has shape ( queries, each of length ). has shape . The little in means transpose — flip the key grid on its side so its columns become the arrows, making the multiplication line up. The result has shape : one score per (query, key) pair.
WHY. Two reasons. (1) A single formula covers the whole sentence. (2) GPUs are built to multiply matrices blindingly fast, so computing thousands of dot products at once costs almost the same as one.
PICTURE. A grid: rows are queries, columns are keys, each cell is a match-score. Bright amber cells = strong match, dark = weak/negative. This grid is the raw attention before any softening.

Step 4 — The size problem, and why we divide by
WHAT. Here is a fact that surprises everyone. If the query and key numbers are ordinary random values (average , spread ), then a dot product over dimensions has:
The average stays , but the spread grows with . Since spread (standard deviation) is the square root of variance, the typical size of a score is about . For that is — scores routinely swing between and .
WHY this is dangerous. Step 5 feeds these scores into softmax, which involves . A gap of versus becomes versus — one term utterly dominates, softmax collapses to "100% on one key, 0% on the rest". Once it's that lopsided, the gradient (the slope Gradient Descent climbs) is almost flat, so learning stalls. We are stuck.
THE FIX. Shrink the scores back to spread by dividing by :
Why and not ? Because we are fixing the spread, and spread scales as , not . Dividing by would over-correct and squash everything to zero.
PICTURE. Two bell curves: the wide one is the unscaled score distribution (std ), the narrow one is after dividing (std ). Shaded band shows softmax's healthy "sensitive zone" roughly — only the scaled curve sits inside it.

Step 5 — Turning scores into percentages: softmax
WHAT. Take one row of scaled scores, say , and convert it into positive numbers that add up to — a set of percentages. The Softmax Function does exactly this:
Term by term: makes every score positive (even negatives become small positives), and dividing by the sum of all exponentials makes the whole row add to .
WHY this tool. We want three things at once: outputs that are positive, that sum to (so they read as "how much attention"), and that are smooth so gradients flow. The exponential also creates competition — pushing one key up automatically pushes the others down, because they share one denominator.
PICTURE. Left: a row of raw scores (some negative). Right: the same row after softmax — all bars positive, tallest bar where the score was highest, and every bar's height is now a percentage summing to 100%.

Step 6 — Blending the answers: multiply by
WHAT. Behind each key sits a value — the actual content to hand back. The output for query is the attention-weighted blend of all values:
Each value is scaled by its attention weight and the results are summed. In matrix form the whole sentence at once:
WHY. The query asked, the keys matched, and now the values answer. Because the weights are percentages summing to , the output is a genuine weighted average — it lands inside the cloud of value arrows, leaning hardest toward whichever value the query attended to most.
PICTURE. Value arrows in cyan, the output arrow in amber sitting between them but closer to (because favoured key 1). A slider-bar shows the blend from the worked example.

Step 7 — Watch it run on real numbers
Let's push the parent note's Example 1 through every step so no move stays abstract. Take , one query, two keys, two values:
Dot products (Step 2/3): , . So — the query is , hence perfect match; it's perpendicular to .
Scale (Step 4): , so scaled scores .
Softmax (Step 5): .
Blend (Step 6):
PICTURE. The full pipeline in one strip: arrows → score grid → scaled → softmax bars → output arrow, with these exact numbers annotated at each arrow.

The one-picture summary

Everything on this page compressed: arrows become a score grid (), the grid is shrunk () into softmax's sweet spot, softmax makes each row a set of percentages (), and those percentages blend the values () into the output.
Recall Feynman retelling (say it out loud, no symbols)
I turn every word into an arrow. To ask "who's relevant to me?", I measure how much my arrow points the same way as each other arrow — that alignment number is big when they agree, zero when they're unrelated, negative when they clash. When there are lots of dimensions, those alignment numbers naturally grow huge, so I shrink them by the square root of the dimension count to keep them tame. Then I squash the row of numbers into percentages that add to 100% — big alignment gets a big slice, negatives get almost nothing. Finally I mix the answer-vectors in exactly those percentages. The word I agreed with most contributes most. That mixed vector is my answer. Nothing more.
Recall
Why divide by and not ? ::: The dot product's spread (standard deviation) grows like ; to reset spread to we divide by that spread, . Dividing by would over-shrink. What single job does softmax do here? ::: Turn a row of real-valued scores into positive percentages that sum to , smoothly and competitively. Where does a masked position go? ::: Its score is set to , so and it receives exactly attention. In Example 1, what is the output vector? ::: .
See also: Self-Attention · Cross-Attention · Multi-Head Attention · Positional Encoding