Guides / Matrix calculus

Attention backward: AᵀG for V, a row-wise softmax for the scores, and the 1/√d on Q and K

Scaled dot-product attention is two matrix products with a row-wise softmax between them: scores S = QKT/√d, weights A = softmax(S) row by row, and output O = AV. The backward pass runs the same pieces in reverse. Each matrix product's gradient is another matrix product with one factor transposed, as in the batched backprop guide. The softmax step is the softmax Jacobian guide's row formula, applied to every row at once. The conventions are those of the matrix calculus conventions guide, with rows as positions and each gradient shaped like its variable, the same rules the one-hidden-layer backprop guide uses for a whole network. The mistakes come from a missing transpose, from a softmax Jacobian that mixes rows, and from dropping the 1/√d on the way back.

Short answer

With G = ∇OL (n × dv):

∇VL = ATG and G̃ = ∇AL = GVT.

∇SL = A ⊙ (G̃ − r1T), where r = rowsum(A ⊙ G̃) holds one number per query row.

∇QL = (∇SL)K/√d and ∇KL = (∇SL)TQ/√d.

Every row of ∇SL sums to 0, a masked score gets exactly 0, and the 1/√d appears only in the gradients of Q and K.

Why it works

For a product C = PR with upstream gradient ∇CL, the right factor gets PT∇CL and the left factor gets (∇CL)RT. In each case the transposed matrix is the one whose index the sum runs over. O = AV gives the gradients of V and A directly. S = QKT/√d gives the gradients of Q and K, with the constant 1/√d carried along, because it scales every score.

In between, row i of A depends only on row i of S, so the softmax's backward pass is the vector formula a ⊙ (g̃ − (aTg̃)1) for each row, with its own aTg̃. Stacking the rows gives one matrix expression, and no m × m Jacobian is ever built. A softmax row sums to 1 whatever its scores, so adding a constant to a row of S changes nothing, and each row of ∇SL sums to 0. That is a check worth running on every answer.

Example 1: the forward pass

Take two queries and two keys of width d = 4, so √d = 2: query rows q1 = (1, 1, 1, 1) and q2 = (1, −1, 0, 0), key rows k1 = (1, 1, 0, 0) and k2 = (0, 0, 1, −1), and V = 1002. Find S, A and O.

  1. QKT = 2000Entry (i, j) is qi · kj: only q1 · k1 is nonzero.
  2. S = 1000Divide by √d = 2.
  3. row 1 of A ≈ (0.7311, 0.2689)The softmax of (1, 0) is (e, 1)/(e + 1).
  4. row 2 of A = (0.5, 0.5)Equal scores give equal weights.
  5. O = AV ≈ 0.73110.53790.51Row i of O mixes the rows of V with the weights in row i of A: 0.2689 × 2 = 0.5379.

Example 2: the gradients of V and A

The layer above sends back G = 1−101. Find ∇VL and G̃ = ∇AL.

  1. ∇VL = ATGV is the right factor of AV. (m × n)(n × dv), the shape of V.
  2. row 1: 0.7311(1, −1) + 0.5(0, 1)Key j collects G's rows, weighted by how much each query attended to it: column j of A.
  3. ∇VL ≈ 0.7311−0.23110.26890.2311Row 2 is 0.2689(1, −1) + 0.5(0, 1).
  4. G̃ = GVTA is the left factor. (n × dv)(dv × m), the shape of A.
  5. G̃ = 1−202Entry (i, j) is row i of G dotted with value row j: (1, −1) · (0, 2) = −2.

Example 3: through the softmax, row by row

Find ∇SL = A ⊙ (G̃ − r1T).

  1. r1 = 0.7311(1) + 0.2689(−2)Row 1 of A ⊙ G̃, summed: the weighted average of row 1 of G̃ …
  2. r1 ≈ 0.1932… which every entry of that row is measured against.
  3. 0.7311 × (1 − 0.1932)Entry (1, 1): the weight times its entry of G̃ minus r1 …
  4. 0.2689 × (−2 − 0.1932)… and entry (1, 2) the same way.
  5. row 1 ≈ (0.5898, −0.5898)It sums to 0. For two keys it is always ±a1a2(g̃1 − g̃2).
  6. r2 = 0.5(0) + 0.5(2) = 1Row 2 uses its own weights and its own row of G̃.
  7. ∇SL ≈ 0.5898−0.5898−0.50.5Row 2 is 0.5 × (0 − 1) and 0.5 × (2 − 1). Central finite differences of L in S agree.

Example 4: the gradients of Q and K

Finish with ∇QL and ∇KL, both 2 × 4.

  1. ∇QL = (∇SL)K/2Q is the left factor of QKT, and the 1/√d comes along.
  2. row 1 = (0.5898k1 − 0.5898k2)/2Query 1 is pushed toward key 1, the key whose value it should use more.
  3. ≈ 0.2949 (1, 1, −1, 1)k1 − k2 = (1, 1, −1, 1).
  4. row 2 = 0.25(−k1 + k2)(−0.5k1 + 0.5k2)/2 …
  5. = −0.25 (1, 1, −1, 1)… so query 2 is pushed the other way.
  6. ∇KL = (∇SL)TQ/2K is transposed in the forward pass, so the sum runs over the query index.
  7. row 1 = (0.5898q1 − 0.5q2)/2Column 1 of ∇SL weights the query rows …
  8. ≈ 0.2949q1 − 0.25q2… which is (0.0449, 0.5449, 0.2949, 0.2949). Row 2 is its negative, since each row of ∇SL sums to 0. Finite differences of L in Q and K agree with every entry.

Common mistakes, and the exact line they happen on

1. The gradient to V without the transpose

The first step of Example 2.

  1. O = AV, G givenRight so far.
  2. ∇VL = AGThis is the mistake. "V is multiplied by A, so its gradient is A times the gradient." In self-attention n = m, so the product runs. Here it gives rows (0.7311, −0.4621) and (0.5, 0). The sum runs over A's row index, the queries, so it is ATG.

2. One softmax over the whole matrix

The softmax step of Example 3.

  1. a ⊙ (g̃ − (aTg̃)1) for one rowRight so far.
  2. flatten A and G̃, use one aTg̃This is the mistake. That subtracts the whole matrix's total, r1 + r2 ≈ 1.1932, from every row. Row 1 becomes (−0.1412, −0.8588), which sums to −1, not 0. Rows don't interact in a row-wise softmax, so each row uses its own ri.

3. Dropping the 1/√d

The first step of Example 4.

  1. ∇SL from Example 3Right so far.
  2. ∇QL = (∇SL)KThis is the mistake. The scale is a constant, so it needs no gradient of its own, but it still multiplies every score, and so every gradient through S. Here row 1 comes out as 0.5898 (1, 1, −1, 1), twice the answer; at d = 64 it is 8 times. The direction is right, so a check that compares only directions passes.

Practice

  1. Self-attention runs on n = m = 1024 positions with d = 64. How many entries does S have, and how many multiply-adds does it take to form?

    Show answer

    10242 = 1,048,576 entries, and 10242 × 64 = 67,108,864 multiply-adds.

  2. Find ∇VL for A = 0.50.50.250.75 and G = 2004.

    Show answer

    ATG has rows (1, 1) and (1, 3).

  3. One row has weights a = (0.5, 0.25, 0.25) and g̃ = (2, 0, 4). Find that row of ∇SL.

    Show answer

    aTg̃ = 2, so a ⊙ (g̃ − 2) = (0, −0.5, 0.5).

  4. With a causal mask, the first query can see only the first key. What is its row of A, and its row of ∇SL?

    Show answer

    A's row is (1, 0, …, 0), and the gradient row is all zeros. The masked entries have weight 0, and the one unmasked weight is 1 whatever its score, so g̃1 − r1 = 0.

  5. If the entries of a query and a key are independent with mean 0 and variance 1, and d = 64, what is the standard deviation of qTk, and of the scaled score?

    Show answer

    The variance is d = 64, so the standard deviation is 8. Divided by √d = 8, the score has standard deviation 1.