Transformers & attention interview questions

17 questions across 4 sections, in the order you would learn them. Every answer here is one that works — but an answer you have read is not an answer you can give, so use Test yourself and say it out loud first.

Attention, conceptually

Read the section that teaches this

If this comes up in an interview

Explain how attention works.

Each position produces a query, a key and a value. The query is compared against every key to produce weights, and the output is a weighted mixture of the values. It lets any position draw directly on any other regardless of distance, and unlike recurrence it parallelises across the sequence.

Then they push further

Why divide by the square root of the key dimension?

Dot products grow with dimension, so without scaling the scores get large, softmax becomes extremely peaked and gradients vanish. Dividing by the square root of the dimension keeps the scores in a workable range.

What changes in a decoder-only model?

A causal mask stops each position attending to later ones. The model can then learn to predict the next token at every position at once during training, and generate one token at a time afterwards.

What does the KV cache store, and why?

The key and value vectors of tokens already processed. For each new token only its own query, key and value are computed and the past ones are reused. Generation gets much faster, at the cost of memory that grows with sequence length and batch size.

What gets marked up. Strong answers explain queries, keys and values in plain terms, the scaling, and the mask, and connect them to the cost of long context. Reciting the formula without explaining it is marked down.

Why did transformers replace recurrent networks?

Recurrence processes sequentially, so distant information degrades through a carried summary and nothing parallelises across the sequence. Attention connects any two positions directly and computes all positions at once, which is what made training at scale practical.

Why is long context expensive?

Attention compares every position with every other, so cost grows with the square of sequence length. Doubling the input quadruples the work, which is why context limits exist and why efficient attention is an active research area.

What do multiple attention heads do?

Each head learns a different kind of relationship, such as grammatical agreement in one and topical relevance in another, and their outputs are combined. One set of weights can only represent one notion of relevance.

From attention to a full language model

Read the section that teaches this

If this comes up in an interview

What does causal masking do?

It prevents each position attending to later positions, so the model learns left-to-right prediction. It also lets the full sequence be trained in parallel, since every position predicts its next token at once.

What is the difference between attention and the feed-forward layer?

Attention moves information between positions. The feed-forward layer transforms each position independently. A block alternates the two, with residual connections around each.

Then they push further

Which holds more parameters?

The feed-forward layers, by a long way. On a typical 8B configuration they are about 70 per cent of the model against 17 per cent for all of attention, or 176 million per layer against 42 million. Attention gets discussed more because its cost grows with the square of sequence length, not because it is where the weights are.

Why does a transformer need position information at all?

Attention compares every position with every other and blends the results, and none of those operations knows where anything is. With no position signal the model is exactly permutation-equivariant: shuffle the input tokens and the outputs come back in the same shuffled order, unchanged. Position has to be injected from outside, either as a vector added per slot or, in current models, by rotating queries and keys by an angle proportional to position so the comparison depends on the gap between two tokens.

What are residual connections and layer norm for?

Two different jobs. The residual makes each block add to a running vector rather than replace it, so information survives dozens of layers and gradients have a short path back; without it the output of a deep stack is uncorrelated with its own input. Normalisation keeps the scale of that running vector predictable, since every block adds to it and the norm grows with depth. Current models use RMSNorm, which divides by the root mean square and applies a learned scale, and it is a rounding error in the parameter count.

What is the KV cache?

Stored keys and values for tokens already processed, so each generation step computes only the new position rather than recomputing the whole prefix. It makes generation practical and consumes significant memory on long contexts.

What modern models actually do differently

Read the section that teaches this

If this comes up in an interview

What is grouped-query attention and why does it matter?

Several query heads share one key and value head instead of each having its own. The KV cache shrinks by exactly that ratio, so a model with 32 query heads and 8 key and value heads has a quarter of the cache. Since the cache rather than the weights usually caps concurrency, that is four times the requests or four times the context for the same memory. Quality drops slightly, and more so for multi-query attention with a single shared pair, which is why eight is the usual compromise.

Then they push further

You need more concurrency still. What next?

Quantize the cache, cap context length, use an engine that allocates cache in pages so nothing is reserved and wasted, and consider a model with windowed attention layers, where the cache stops growing past the window.

Does it make the weights smaller too?

Only slightly. The key and value projection matrices shrink by the same ratio, but they are a small share of a layer's parameters. The cache is where the saving is.

What gets marked up. Strong answers give the ratio and connect it to concurrency rather than to speed. Saying it makes the model faster without mentioning the cache misses the point.

Why did rotary position embeddings replace learned absolute positions?

A learned table has a fixed number of rows, so there is nothing for a position beyond the training length, and it encodes absolute position when what attention needs is relative distance. RoPE rotates queries and keys by an angle proportional to position, so their dot product depends only on the gap between them. Extending context means rescaling those frequencies, which works to a point and costs some retrieval quality.

A model card says 120 billion total parameters and 5 billion active. What does that tell you about serving it?

It is a mixture of experts: a router picks a couple of experts per token, so compute per token is that of a 5 billion parameter model while all 120 billion must sit in memory. It will be cheap per token and expensive to host. Sizing the GPU from the active figure is the standard mistake.

Then they push further

What is harder about training it?

Keeping the router balanced, which needs an auxiliary loss term or the router collapses onto a few experts, and the all-to-all communication when experts live on different devices.

Is FlashAttention an approximation?

No. It computes exactly the same attention, tiling the work so blocks fit in on-chip memory and using a running softmax so the full scores matrix is never written to GPU memory. It does slightly more arithmetic and far less memory traffic, which is the whole speedup, and it makes attention memory linear in sequence length.

Causal multi-head attention in NumPy

Read the section that teaches this

If this comes up in an interview

Implement causal self-attention in NumPy.

Project the input three times to get q, k and v of shape (T, d_k). Compute scores as q @ k.T divided by the square root of d_k, giving (T, T). Set the strictly upper triangle to negative infinity, softmax each row, then multiply by v to get (T, d_k). For multiple heads, reshape the feature axis into (n_heads, d_head), transpose heads in front of positions, do the same computation batched, transpose back and reshape, then apply the output projection.

Then they push further

Why negative infinity rather than zeroing the weights afterwards?

Because the softmax has to normalise over the visible positions only. Zeroing after the softmax leaves each row summing to less than one, and the deficit is worst at early positions, which quietly shrinks their outputs. Negative infinity makes the exponential exactly zero before normalisation, so the surviving weights still sum to one.

Do you scale by the square root of d_model or of d_head?

d_head. The dot product happens inside a head, between vectors of length d_head, so that is the dimension whose variance needs correcting. Scaling by d_model would under-scale by the number of heads.

How would you convince me it is correct without a reference implementation?

Two assertions. Each row of the attention weights sums to one, which catches a softmax on the wrong axis or a mask applied too late. The strict upper triangle of the weights is exactly zero, which catches a mask built with the wrong offset or transposed. A third is that truncating the sequence leaves the earlier outputs unchanged, which is causality stated as a property rather than as a shape.

What gets marked up. Strong candidates state the shape of each intermediate as they write it and test their own code unprompted. Getting the mask right before the softmax, and scaling by d_head, separate people who have written this from people who have read it.

Walk through the shapes of multi-head attention for a batch of 2, length 6, d_model 16 and 4 heads.

Input (2, 6, 16). Each projection keeps (2, 6, 16). Reshape to (2, 6, 4, 4) and transpose to (2, 4, 6, 4), so heads sit in front of positions. Scores are (2, 4, 6, 6), one square matrix per batch item per head, and the mask (6, 6) broadcasts over the first two axes. Weights times values gives (2, 4, 6, 4); transpose back to (2, 6, 4, 4), reshape to (2, 6, 16), then the output projection leaves it there.

Why does the softmax need the maximum subtracted?

Purely for numerical stability. Exponentiating a large score overflows to infinity in floating point and the division then gives NaN. Subtracting the row maximum is algebraically a no-op because the constant factors out of numerator and denominator, and it guarantees the largest exponent is exp(0), so nothing overflows and the smallest underflows harmlessly to zero.

Your attention weights sum to 0.6 on the first row and 1.0 on the last. What is wrong?

The mask is being applied after the softmax rather than before. The first position can see one entry out of many, so once the remaining entries are zeroed most of its normalised weight has been thrown away; the last position can see everything, so nothing is lost. Move the mask to the scores and use negative infinity.

These are the questions for one topic. The whole question bank covers every topic on the site.