Linear algebra for LLMsPart 4: Tensors, shapes and einsum

Batched matmul and einsum

7 min

@ on more than two axes

@ =

@ multiplies the last two axes as matrices and treats the rest as a batch. The weight has no batch axes, so it broadcasts: every sequence goes through the same WW. This is nn.Linear on a whole batch.

Write

@: matrix product over the last two axes; leading axes broadcast.

Batches of matrices on both sides

@ =

Queries times transposed keys, for every sequence and every head at once: (T×dh)(dh×T)=T×T(T \times d_h)(d_h \times T) = T \times T per (b,h)(b, h) pair. The leading axes (B,h)(B, h) must match (or broadcast).

einsum: name every axis

Cik=∑jAijBjk\displaystyle C_{ik} = \sum_j A_{ij} B_{jk}
torch.einsum("ij,jk->ik", A, B)

Give each axis a letter. A letter that appears in the inputs but not after -> is summed over; the rest are kept, in the order you write them. That one rule covers dot products, matrix products, transposes and batches.

Write

einsum: letters missing from the output are summed. "ij,jk->ik" = matmul.

The strings you'll meet

Operation einsum
dot product "i,i->"
outer product "i,j->ij"
matrix × vector "ij,j->i"
transpose "ij->ji"
linear layer "btd,de->bte"
attention scores "bhqd,bhkd->bhqk"
attention output "bhqk,bhkd->bhqd"
sum over tokens "btd->bd"

In the attention strings, q and k both index tokens: queries and keys. Writing bhkd for the keys means no explicit transpose is needed.

✏️ Your turn

Write the einsum

VVAA

AA holds the attention weights (one row per query, one column per key). Write the einsum for the output AVAV and its shape.

Work it out on paper, then go to the next card to check.

Answer

torch.einsum("bhqk,bhkd->bhqd", A, V)

k (the key position) appears in both inputs and not in the output, so it’s summed over: each query’s output is a weighted sum of value rows. Same as A @ V.

Counting FLOPs of a batched product

FLOPs=2×∏(kept)×(summed)\displaystyle \text{FLOPs} = 2 \times \textstyle\prod(\text{kept}) \times (\text{summed})
QK⊤:  2⋅B⋅h⋅T⋅T⋅dh\displaystyle QK^\top: \; 2 \cdot B \cdot h \cdot T \cdot T \cdot d_h

The 2mkn rule generalizes: every output entry costs 2 FLOPs per summed index. For one sequence of 4,096 tokens with 32 heads of 128: 2⋅32⋅40962⋅128≈1.4×10112 \cdot 32 \cdot 4096^2 \cdot 128 \approx 1.4 \times 10^{11} FLOPs for the scores of one layer. Note the T2T^2: attention cost grows with the square of the context.

Write

einsum FLOPs = 2 × (kept sizes) × (summed size). Scores: 2BhT2dh2BhT^2 d_h.

📌 Recap

Batched matmul and einsum in one card

  • @ multiplies the last two axes; leading axes broadcast.
  • einsum: letters missing from the output are summed.
  • Scores "bhqd,bhkd->bhqk", output "bhqk,bhkd->bhqd".
  • FLOPs = 2 × kept sizes × summed size; attention scores grow like T2T^2.

Write

The four lines above.