Type at least 2 letters. Enter opens the first result, Esc closes.

    learn.mohebi.ai

    Attention playground

    Build scaled dot-product attention by hand on a short sentence. Drag the word vectors, edit the query, key and value matrices, and watch the scores, the softmax weights and the outputs change at every step.

    Attention is the operation at the centre of every transformer. Each token asks a question (its query), compares it with what every token offers (its key), and returns a weighted average of what the tokens carry (their values). On this page you build it yourself, one step at a time, with numbers small enough to check by hand.

    You will see three figures:

    1. The attention lab. One head on a sentence of up to 8 words. Every vector has 2 numbers, so every vector is a point in a plane.
    2. Two heads side by side. Two heads read the same sentence in different ways, and their outputs are combined.
    3. Sinusoidal positional encodings. How a transformer gets the order of the tokens.

    1. The attention lab #

    Interactive figure: loading…

    Pick a sentence, then click a token to make it the query. Follow the five steps in the box under the planes: the query qq is compared with every key; the scores (orange for positive, aqua for negative) go through a softmax; the output oo is the weighted average of the grey values. Drag a word in the embedding plane (the first plane): every number on the page updates. Notice that the blue output never leaves the grey region around the values (their convex hull).

    The lab computes, for every token at the same time:

    Step What happens Formula
    1. Embed look up the vector of each word, and add a position code xt=e(wordt)+s ptx_t = e(\text{word}_t) + s\,p_t
    2. Project three matrices give a query, a key and a value qt=xtWQ, kt=xtWK, vt=xtWVq_t = x_tW_Q,\ k_t = x_tW_K,\ v_t = x_tW_V
    3. Score compare the query of token ii with the key of token jj sij=qi⊤kj/dks_{ij} = q_i^\top k_j / \sqrt{d_k}
    4. Softmax turn each row of scores into weights that sum to 1 aij=esij/τ∑lesil/τa_{ij} = \dfrac{e^{s_{ij}/\tau}}{\sum_l e^{s_{il}/\tau}}
    5. Mix average the values with these weights oi=∑jaij vjo_i = \sum_j a_{ij}\,v_j

    Try this #

    1. Does the same word always get the same output? Choose "the cat sat on the mat". Click the first "the" (position 0), then the second "the" (position 4), and compare the two rows of the weight matrix. Then turn on the causal mask. Then turn it off again and move the slider ss of the position code to 1.
      What you should seeWithout positions and without a mask, the two rows are equal and the two outputs are equal: o=(0.44,−0.28)o = (0.44, -0.28) for both. The two tokens have the same embedding, so they have the same query, and they see the same set of keys. Attention alone treats the input as a set of tokens. The causal mask breaks the tie (the first "the" sees only itself, the second sees five tokens), and so does the position code: with s=1s = 1 the two tokens get different vectors x0≠x4x_0 \ne x_4.
    2. What does the temperature do? Choose "it → cat" and click "it". Move τ\tau down to 0.1, then up to 3. Then set τ=0.5\tau = 0.5 and compare with τ=1\tau = 1 and the preset WQ=2IW_Q = 2I.
      What you should seeWith τ=0.1\tau = 0.1 the row of "it" is almost one-hot: weight 1.00 on "cat", and the output jumps onto the value of "cat". With τ=3\tau = 3 the weights are flat (largest 0.28) and the output moves towards the mean of all values. Doubling WQW_Q doubles every score, which gives exactly the same weights as halving τ\tau. This is why the scores are divided by dk\sqrt{d_k}: the scale of the scores controls how sharp the softmax is.
    3. What if the query carries no information? Choose the preset WQ=0W_Q = 0. Look at the weight matrix. Then turn on the causal mask.
      What you should seeAll queries are zero, so all scores are 0 and every row of AA is uniform: aij=1/Ta_{ij} = 1/T. Every token gets the same output, the mean of all values. With the causal mask, row ii is uniform over the first i+1i + 1 tokens, so oio_i is the running mean 1i+1∑j≤ivj\frac{1}{i+1}\sum_{j \le i} v_j (for example 1/31/3 on each of the first three tokens in row 2).
    4. Can context change the meaning of a word? Choose "river bank" and click "bank". Note its output oo. Then choose "money bank" and click "bank" again.
      What you should see"bank" has the same embedding in both sentences. In the first sentence its largest weight (0.47) is on "river" and o=(−1.37,0.27)o = (-1.37, 0.27). In the second its largest weight (0.39) is on "money" and o=(−0.90,−1.09)o = (-0.90, -1.09). The output of attention is a contextual vector: it depends on the other words in the sentence.
    Quick check

    In the lab, you set WQ=2IW_Q = 2I and keep τ=1\tau = 1. A friend keeps WQ=IW_Q = I and sets τ=0.5\tau = 0.5. Everything else is the same. How do the two weight matrices compare?

    Quick check

    The lab uses WQ=0W_Q = 0 and the causal mask. The values of the first three tokens are v0=(3,0)v_0 = (3, 0), v1=(0,3)v_1 = (0, 3) and v2=(0,0)v_2 = (0, 0). What is the output o2o_2?

    2. Two heads side by side #

    Interactive figure: loading…

    Click a token and compare the two weight matrices. Head 1 compares tokens only along the first axis, head 2 only along the second axis (see their matrices WQhW_Q^h and WKhW_K^h). The plane below shows the two head outputs and their combination, the multi-head output. Try other presets, or type your own numbers in the matrices.

    Multi-head attention runs HH heads in parallel. Each head hh has its own matrices WQh,WKh,WVhW_Q^h, W_K^h, W_V^h, so it computes its own weights AhA^h and its own outputs oiho^h_i. The outputs are put side by side (concatenated) and multiplied by an output matrix WOW_O. Write WOW_O as a stack of blocks WO1,…,WOHW_O^1, \dots, W_O^H, one block for each head. Then the result is a sum over heads:

    MultiHead⁡(X)i=[ oi1,…,oiH ] WO=∑h=1Hoih WOh.\begin{aligned} \operatorname{MultiHead}(X)_i &= [\,o^1_i, \dots, o^H_i\,]\,W_O \\ &= \sum_{h=1}^{H} o^h_i\,W_O^h . \end{aligned}

    In the figure, WVh=IW_V^h = I and WO1=WO2=12IW_O^1 = W_O^2 = \tfrac12 I, so the result is the midpoint of the two head outputs.

    Try this #

    1. Why use more than one head? In "it → cat", click "hungry". Which token does each head attend to most? Then give head 2 the same preset as head 1.
      What you should seeHead 1 (axis 1) puts 0.65 on "cat"; head 2 (axis 2) puts 0.49 on "ate". One head can find the subject while the other finds the verb, and the combined output mixes both. When both heads have the same matrices, they compute the same weights and the same outputs, and the second head adds nothing. Different heads are useful only because they learn different projections.
    Quick check

    Both heads use the same WQW_Q, WKW_K and WVW_V, and WO1=WO2=12IW_O^1 = W_O^2 = \tfrac12 I as in the figure. How does the multi-head output compare with the output oio_i of one head with these matrices?

    3. Sinusoidal positional encodings #

    Interactive figure: loading…

    Move the position tt, or press Play. Each pair of dimensions (2i,2i+1)(2i, 2i+1) is a clock hand that turns by the angle θi\theta_i per position. The first pairs turn fast, the last ones hardly move. The chart shows how similar PE(t)PE(t) is to the encoding of every other position ss. Notice that the curve moves with tt but keeps its shape. Change the base bb and the dimension DD.

    Attention alone does not know the order of the tokens (experiment 1). The original transformer adds a fixed vector PE(t)PE(t) to the embedding of the token at position tt. For i=0,…,D/2−1i = 0, \dots, D/2 - 1:

    PE(t)2i=sin⁡(θit),PE(t)2i+1=cos⁡(θit),θi=b−2i/D,\begin{aligned} PE(t)_{2i} &= \sin(\theta_i t), \\ PE(t)_{2i+1} &= \cos(\theta_i t), \\ \theta_i &= b^{-2i/D}, \end{aligned}

    with base b=10000b = 10000. Each pair (PE(t)2i,PE(t)2i+1)(PE(t)_{2i}, PE(t)_{2i+1}) is a point on the unit circle at the angle θit\theta_i t. A step of kk positions turns every pair by the angle θik\theta_i k. This turn does not depend on tt, so PE(t+k)=Mk PE(t)PE(t + k) = M_k\,PE(t) with a fixed block rotation MkM_k, and

    PE(t)⊤PE(t+k)=∑i=0D/2−1cos⁡(θik),PE(t)^\top PE(t + k) = \sum_{i=0}^{D/2 - 1} \cos(\theta_i k),

    a function of the offset kk only. The lab above uses one such pair, pt=(sin⁡0.6t,cos⁡0.6t)p_t = (\sin 0.6t, \cos 0.6t), multiplied by the slider value ss.

    Try this #

    1. What does the base bb change? Keep D=32D = 32. Read the similarity at offset k=8k = 8 under the chart, first with b=10000b = 10000, then with b=100b = 100. Press Play with each base.
      What you should seeWith b=10000b = 10000 the similarity at k=8k = 8 is 0.66; with b=100b = 100 it is 0.40. A smaller base makes the slow clocks turn faster, so nearby positions become less similar and the encoding separates positions better inside a short window. A larger base keeps slow pairs that are still different after thousands of positions, which matters for long sequences.

    4. The math in one place #

    For a sequence of TT tokens with vectors xt∈RDx_t \in \mathbb{R}^{D} stacked as the rows of X∈RT×DX \in \mathbb{R}^{T \times D}:

    Q=XWQ,K=XWK,V=XWV,A=softmax⁡ ⁣(QK⊤dk+M),O=AV.\begin{aligned} &Q = XW_Q, \quad K = XW_K, \quad V = XW_V, \\ &A = \operatorname{softmax}\!\Big(\frac{QK^\top}{\sqrt{d_k}} + M\Big), \\ &O = AV . \end{aligned}

    The softmax acts on each row of the T×TT \times T score matrix separately, and row ii of OO is the output oio_i of token ii.

    5. Learn more in the tracks #