The Attention Formula: What Softmax and the Square Root of d Actually Do

Learn how scaled dot-product attention turns query-key scores into useful weights, and why transformers divide by the square root of the key size.

Sep 24, 202612 min readFollow

Topics You Will Master

What each part of the scaled dot-product attention formula does
Why dot-product scores grow when query and key vectors get wider
How softmax turns scores into attention weights
Why transformers divide scores by the square root of the key size

On Day 13, we gave every word a query, key, and value. A query asks, "Which information do I need?" A key says, "What kind of information do I offer?" A value carries the information that can be passed on. Now we need the exact rule that connects those three pieces.

That rule is scaled dot-product attention. It scores keys against a query, turns the scores into weights, then uses those weights to blend value vectors.

This first diagram shows the order of those operations before we inspect each one.

Scaled Dot-Product Attention in Five Steps for the Word "it"

Attention scores query-key matches, scales the scores, normalizes them with softmax, and uses the result to mix values.

:::note We use three words and 64-value vectors in this lesson. Real models are often wider, but 64 is large enough to make the scaling problem visible. :::

Bestseller

LLM Fine-Tuning with Hugging Face: LoRA, QLoRA, PEFT

Fine-tune BERT, T5, ViT, LLaMA-style models and Qwen3-TTS using Hugging Face Transformers, custom datasets, LoRA, QLoRA.

Enroll on Udemy 30 day refund, lifetime access

The Formula, Read One Part at a Time

The complete rule is short:

Do not try to read it all at once. Read it from the inside out.

  • is the matrix of query vectors.
  • is the matrix of key vectors.
  • is the matrix of value vectors.
  • means that the key matrix is turned sideways.
  • is the number of values in one key vector.

First, compares every query with every key. Next, division by controls the size of those comparison scores. Softmax changes each score row into weights. Finally, multiplying by takes a weighted blend of the values.

For the rest of this article, we follow the word it in a sentence with trophy, suitcase, and it. Suppose it's query gives these raw scores:

Key Raw score from it's query
trophy 16
suitcase 8
it 0

The trophy is the best match, and suitcase may still add useful context. The question is how to turn those three scores into a sensible amount of attention.

Keep Track of the Shapes

For three query positions and three key positions, and each have shape . Transposing gives . The two inner dimensions match, so has shape . Its rows belong to queries and its columns belong to keys.

Our values will have only two features each, so has shape . A weight matrix multiplied by returns a output. Query and key widths must match, but value width need not equal key width. The output width follows the values.

The scores in this lesson are invented to make the arithmetic visible. We are not claiming that a trained model actually gives the word "trophy" a score of 16. The same distinction applies to the diagrams: they explain a calculation, not a measured attention map.

Advertisement

Why Wider Vectors Produce Bigger Scores

A dot product multiplies matching vector positions and then adds all those products. With four positions, it adds four small terms. With 64 positions, it adds 64 terms. Positive and negative terms may partly cancel, but the usual size of the total still grows as we add more positions.

Under a useful starting assumption, query and key entries are independent, have mean zero, and have variance one. Variance measures the average squared spread around the mean. Each product then has variance one, and adding such products gives variance . The standard deviation, the square root of variance, grows as . Learned vectors need not keep these exact statistics. With , that number is . This growth does not mean that the model suddenly found a better match. It happens partly because the vector is wider.

Dot-Product Scores for 4-Value and 64-Value Vectors

Adding more products makes raw dot-product scores larger even when the kind of match has not changed.

Here is a small comparison. The order of the scores remains useful. The trouble is the scale of the scores before softmax sees them.

Key size Example raw scores Typical score size
4 4, 2, 0 2
64 16, 8, 0 8

If raw scores become too large, softmax reacts very strongly to even a modest difference. That can make attention pick almost one key just because vectors are wide.

Advertisement

Softmax Turns Scores into Weights

Raw scores are not weights. A raw score can be negative, and three raw scores do not have to add to one. We need a set of positive numbers that says how much each value should contribute.

Softmax does that job. For a score in a row, it uses:

The exponential makes every number positive. Dividing by the total makes all weights in that row add to one. A larger score still receives a larger weight.

The next diagram shows why our raw row [16, 8, 0] is too sharp when it reaches softmax unchanged.

Softmax on the Raw Scores 16, 8 and 0 Without Scaling

A large raw-score gap becomes an almost all-or-nothing attention distribution after softmax.

If we use softmax directly, the result is close to this:

Key Raw score Weight after raw softmax
trophy 16 0.9997
suitcase 8 0.0003
it 0 0.0000

Trophy clearly wins, but suitcase has almost no way to pass information forward. A near-one weight can be correct when the learned match is truly overwhelming. This invented score row shows what a large score gap does; the numbers alone do not prove that vector width caused the gap.

To see what softmax is doing, take a small score row, exponentiate every entry, and divide each result by their sum. The calculation gives a probability-like row of weights, not a new set of meanings.

Advertisement

Why We Divide by the Square Root of d

The scaling step repairs the size problem before softmax. Our key size is 64, and . So we divide every score in the row by 8:

We have not changed the winner. Trophy is still ahead of suitcase, and suitcase is still ahead of it. We have only returned the scores to a range where softmax can express a useful preference.

Dividing the Scores by √64 Before Softmax

Dividing by controls the usual score growth before softmax makes weights.

Now softmax gives a more informative distribution:

Key Scaled score Weight after softmax
trophy 2 0.665
suitcase 1 0.245
it 0 0.090

Trophy still supplies most of the information. Suitcase can now supply some context, and the word itself retains a small amount. This is a preference, not an accidental forced winner.

Why divide by the square root rather than by 64? Dividing by 64 would turn [16, 8, 0] into [0.25, 0.125, 0]. Softmax would then produce weights that are nearly even. That throws away a real preference.

Softmax Weights With No Scaling, Division by 8 and Division by 64

No scaling is too sharp here, while dividing by the whole key size makes the distribution too flat.

The square root matches the usual growth of a dot product. It reduces the unwanted growth without erasing the model's learned score differences.

A score difference matters through a ratio. For scores 2 and 1, the ratio of their unnormalized weights is , about 2.72. For scores 16 and 8, that ratio is , about 2,981. This is why keeping the ranking unchanged does not keep the distribution unchanged.

Very sharp attention is not always wrong. The training concern is that an almost-one weight leaves little room for the distribution to respond to small score changes. For softmax, a weight's derivative with respect to its own score is . That quantity is small near both zero and one. Scaling helps avoid this saturation at the start of training; it does not guarantee good learning by itself.

An attention weight is a mixing coefficient, not a probability that a word is true, relevant in a human sense, or the cause of the answer. We should read 0.665 as "use this fraction of the value in this head's mixture," not "the model is 66.5% certain about trophy."

Advertisement

Values Carry the Information

The weights do not mix the keys. Keys were only used to decide where to look. The final weights mix values, because values hold the information to send to the next layer.

Let trophy's value be [1, 0], suitcase's value be [0, 1], and it's value be [1, 1]. Using the scaled weights from above gives:

The output is mostly trophy information, with smaller contributions from suitcase and it. That blended vector is the new context-aware representation for it.

Weighted Sum of the Value Vectors Gives the New Vector for "it"

Queries and keys decide the weights; the weighted values form the attention output.

Every Word Gets Its Own Score Row

We followed only it's query, but every word has a query. For three words, creates a three-by-three score grid. Each row belongs to one query, and softmax works across one row at a time.

Query word trophy key suitcase key it key
trophy 8 4 0
suitcase 4 8 0
it 16 8 0

The third row is our example. The first two rows are the questions asked by trophy and suitcase. Matrix multiplication calculates all these comparisons efficiently in one operation.

Score Grid QKᵀ for Three Words, Scaled and Softmaxed Row by Row

Each row asks one word's question about all keys in the sequence.

Advertisement

A Small Step That Keeps Softmax Safe

Real implementations often subtract the largest score in each row before applying softmax. For [16, 8, 0], subtracting 16 produces [0, -8, -16].

This does not change the final weights. Every exponential is divided by the same shared total, so moving every score by the same amount cancels out. It does prevent very large exponentials from causing number problems in code.

Subtracting the Largest Score Leaves the Softmax Weights Unchanged

Subtracting the row maximum keeps the computation safe while leaving the softmax weights unchanged.

Check the Same Row in NumPy

NumPy lets us calculate the row without building a Transformer. We first import it, then define the already-computed dot products and key width.

PYTHON
import numpy as np

The width is 64 because that is the number of products in each query-key score. It is not the number of tokens or the width of our teaching values.

PYTHON
raw_scores = np.array([16.0, 8.0, 0.0])
key_width = 64
scaled_scores = raw_scores / np.sqrt(key_width)

Subtract the maximum after scaling. Subtracting a shared constant leaves softmax unchanged, while dividing changes its sharpness. These two operations solve different problems.

PYTHON
exponentials = np.exp(scaled_scores - scaled_scores.max())
weights = exponentials / exponentials.sum()
values = np.array([[1.0, 0.0], [0.0, 1.0], [1.0, 1.0]])
context = weights @ values

The weights are approximately [0.665241, 0.244728, 0.090031]. The context is approximately [0.755272, 0.334759]. The first coordinate receives contributions from trophy and it; the second receives contributions from suitcase and it.

Check two properties before changing the example: the weights sum to one, and there is one weight per value row. Replacing a value changes the mixed output but does not change the weights. Replacing a key can change the weights because keys participate in the scores.

The Full Attention Step

For one query position, the complete attention process is now easy to state:

  1. Compare its query with all keys to get raw scores.
  2. Divide by to control score size.
  3. Apply softmax across that score row.
  4. Use the resulting weights to add value vectors.

Recap

Scaled dot-product attention starts with query-key scores. Softmax turns those scores into weights, but wide vectors make raw dot products grow and can make softmax sharp for the wrong reason. Dividing by keeps the scale useful.

The weights choose how much each value contributes. On Day 15, we will run several attention calculations in parallel so different heads can learn different relationships in the same sentence.

Found this useful? Keep building with me.

New tutorials every week on YouTube: or go deeper with a full structured course.

Find this tutorial useful?

Subscribe to our YouTube channels for more practical production walk-throughs.

Discussion & Comments