Linear attention is attention rewritten so that its cost grows in proportion to the length of the sequence, not with its square. Ordinary attention compares every query with every key, so T tokens need T2 comparisons. Linear attention first adds up all the keys and values into one small table, and then each query reads its answer from that table. When the model generates text, the table is a running total that each new token updates. So the model carries a memory of fixed size instead of a cache that grows with every token.
That fixed-size memory makes linear attention a recurrent network, the first full model this chapter builds. A recurrent network reads one token at a time and keeps a fixed-size summary of everything it has read, called its state (§3.3). §21.1 set up the problem this solves. A softmax Transformer stores the key and value vectors of every past token, a store called the KV cache, and the cache grows by a fixed number of bytes with every token. A recurrent network keeps only its state. That section also showed that if the state is updated linearly, the network can still be trained in parallel over the whole sequence.
Here is the trick in numbers. Take scaled dot-product attention (§4.3), with the queries, keys, and values of T tokens stacked as the rows of matrices Q, K, and V. Delete the softmax and what is left is (QK⊤)V. Now move one pair of parentheses, Q(K⊤V). Matrix multiplication is associative, so the answer is the same, but the cost is not. Take T=65,536 tokens and a head width of d=128. The first order builds a T×T matrix and costs about 2.2×1012 floating-point operations (FLOPs). The second builds a d×d matrix and costs about 4.3×109, which is 512 times less. And K⊤V is a sum over tokens, so a model generating text can keep it as a running total.
§4.7 and §12.6 previewed this idea without proof. This section proves it and then asks what it costs. We will see why the softmax blocks the reordering, and how a product of feature vectors in its place unblocks it. We will prove that causal attention then becomes exactly a recurrent network whose state is a matrix. Linear attention trains in parallel and decodes in constant time and memory, yet for years it was worse than softmax attention. By the end you will be able to say precisely why, with a derivation for each reason, which is what interviewers ask for.
Attention is a weighted average with a similarity score
Fix one attention head, the unit of a layer that has its own queries, keys, and values (§4.2). Each token t has a query qt∈Rdk, a key kt∈Rdk, and a value vt∈Rdv, where dk and dv are the widths of the keys and the values. Stacked as rows, they form Q,K∈RT×dk and V∈RT×dv. Here is the output of softmax attention at token t, without the causal mask for now,
In plain words, score the query against every key, turn the scores into weights that are positive and add up to one, and return the weighted average of the values. This is the soft lookup of §4.1.
Nothing in that recipe needs the exponential in particular. It needs a way to score how similar a query is to a key, and a rule that turns the scores into weights that are nonnegative and sum to one. Any nonnegative similarity function, divided by its sum over the keys, does that job. Such a function is called a kernel here. Kernel methods in machine learning use the word in a stricter sense, and the kernels built from feature maps below meet that stricter sense too.
In plain words, attention is a weighted average of values, and the kernel decides the weights. Statisticians have used this form since 1964, when Nadaraya and, independently, Watson proposed it as a kernel smoother. A kernel smoother predicts the value at a point by averaging nearby observations, each weighted by a kernel. Tsai et al. (2019) read attention this way, with queries and keys as the points and values as the observations.
Why must κ be nonnegative? If some weights could be negative, the denominator could be zero or negative. The output would no longer be an average of the values, and a tiny denominator would blow it up. Keep this in mind, because it decides which feature maps are allowed.
Moving the parentheses
Suppose the similarity of a query and a key can be computed in two steps. First turn each vector into a list of dϕ numbers, its features, with a fixed function ϕ called the feature map. Then take the dot product of the two feature lists,
κ(q,k)=ϕ(q)⊤ϕ(k),ϕ:Rdk→Rdϕ.
A tiny example shows the idea. In two dimensions, take ϕ(x)=(x12,2x1x2,x22). For q=(1,2) and k=(3,1) the features are (1,22,4) and (9,32,1), and their dot product is 9+12+4=25. That is (q⊤k)2=52, and the identity holds for every pair, so this ϕ computes the kernel κ(q,k)=(q⊤k)2. The kernel is never negative, even though one feature can be. It can be zero, though, which is why the maps used in practice keep every feature strictly positive. Any kernel of this two-step form can be reordered, as follows.
Apply ϕ to each row, so ϕ(Q)∈RT×dϕ and ϕ(K)∈RT×dϕ. In the numerator of kernel attention, the query's features do not depend on s, so they come out of the sum,
We wrote the output as a row vector to keep the shapes lined up. The first equality writes each term as ϕ(qt)⊤(ϕ(ks)vs⊤), since matrix products can be regrouped, and then takes the common factor ϕ(qt)⊤ out of the sum. The second uses one more definition. The outer productϕ(ks)vs⊤ is the dϕ×dv matrix whose entry (i,j) is ϕ(ks)ivs,j. A sum of outer products over the rows of two matrices is their product, here ϕ(K)⊤V. The denominator works the same way with vs replaced by the number 1.
In plain words, summarize all keys and values once, into a dϕ×dv table and a dϕ vector. Then let every query read from the summary instead of from every key.
Why can softmax attention not do this? Its kernel does not factor with finitely many features. The Taylor series exp(q⊤k)=∑n≥0(q⊤k)n/n! has a term for every power n. The power (q⊤k)n is itself a dot product of features, but it needs dkn of them, one for every product of n entries. So the series is a feature map with infinitely many features. No finite map can do the same job, because a finite map caps the rank. With dϕ features, the matrix of kernel values between n queries and n keys is ϕ(Q)ϕ(K)⊤, whose rank is at most dϕ. The softmax kernel produces matrices of every rank, as the box below shows. That is the precise sense in which the softmax blocks the reordering. Everything else in this section is a choice of a finite ϕ, and the price of that choice.
Now count the cost. §4.7 counts a product of an m×k matrix and a k×n matrix as 2mkn FLOPs, one multiply and one add per term. The left order, (ϕ(Q)ϕ(K)⊤)V, forms a T×T matrix in 2T2dϕ FLOPs and multiplies it by V in 2T2dv. The right order, ϕ(Q)(ϕ(K)⊤V), forms the dϕ×dv summary in 2Tdϕdv, and the T queries read it in another 2Tdϕdv. The normalizer adds only lower-order terms, the T2 additions of the row sums in the left order and O(Tdϕ) in the right order, so we leave it out of the count.
The cell below times both orders in NumPy for a head of width 32, so the predicted crossover is at T=32. A single wall-clock time on a CPU is noisy, so the cell keeps the best of five runs.
Python · cell 1
The left order's time grows about fourfold or more with each doubling of T, as T2 predicts. At the largest sizes the T×T matrix no longer fits in the CPU's cache, which adds to it. The right order grows about twofold per doubling, linearly in T, and stays far below a millisecond. The exact times depend on your machine, but the gap between the two orders widens with every doubling, at least as fast as the FLOP ratio T/d. In an interview, write the crossover formula first. It shows that linear attention only pays once the sequence is longer than the head is wide.
Warm-up
Which order to multiply
Write two cost functions for non-causal linear attention. Both return Python ints.
attention_flops(T, d_phi, d_v, order) returns the FLOPs of the two matrix products, ignoring the normalizer and the feature map. With order='left' it counts (ϕ(Q)ϕ(K)⊤)V, and with order='right' it counts ϕ(Q)(ϕ(K)⊤V). Count an (m×k) by (k×n) product as 2mkn FLOPs.
crossover_T(d_phi, d_v) returns the smallest positive integer T at which the right order costs strictly fewer FLOPs than the left.
Tests, verified solutions, and AI help, open once you add your API key.
Causal linear attention is a recurrent network
A language model needs the causal version, in which token t may only use the keys of tokens s≤t (§4.4). Repeat the factoring with the sums cut off at t,
The numerator used (ϕ(qt)⊤ϕ(ks))vs=vs(ϕ(ks)⊤ϕ(qt)), which moves a scalar to the other side of a vector. Each query now reads a prefix sum, a sum over the tokens up to its own. A prefix sum is a recurrence, because the sum up to t is the sum up to t−1 plus one term. Give the two running sums names.
In plain words, each new token writes the outer product of its key features and its value into a fixed-size matrix, and adds its key features to a fixed-size vector. Then it reads its output in two steps. It multiplies the matrix by its own query features, and it divides by the vector's dot product with the same query features.
§21.1 studied the scalar recurrence ht=atht−1+utxt. There a decayat scales the old state, and the new input xt is added with weight ut. Linear attention has the same shape with three differences. The state is a dϕ×dv matrix, there is no decay (at=1), and each write is the rank-one matrix ϕ(kt)vt⊤. The update is linear in the state, with no nonlinearity on the path from St−1 to St. That is exactly the property that let the recurrences of §21.1 be computed in parallel.
Before the general proof, run the recurrence by hand once.
The same numbers, computed in parallel
The example computed the outputs two ways, a loop over tokens and a masked matrix, and got the same numbers. The theorem says the two always agree.
In plain words, causal linear attention is two things at once. It is ordinary masked attention with the softmax replaced by a kernel and a division by row sums, and it is a recurrence. The mask that makes attention causal and the running sum that makes the recurrence causal are the same object.
§21.1 described every causal layer of this chapter by a sequence-mixing matrix. That is a lower-triangular T×T matrix M, computed from the layer's input, that mixes each channel x∈RT as y=Mx. Linear attention is the first instance with a matrix state. For each value channel, M=diag(W1)−1W. The parallel and recurrent forms are that section's matrix mode and recurrent mode. The cell implements both, checks the hand example exactly, and checks agreement on random data.
Python · cell 2
Decoding, training, and what each costs
The two forms have opposite strengths, and real systems use each where it is strong.
Decoding. Generating token t needs only St−1 and zt−1. The update costs dϕdv multiply-adds for the outer product, and the read costs another dϕdv. That is about 4dϕdv FLOPs per head per token. The memory is dϕdv+dϕ numbers, whatever t is. Softmax attention instead reads a KV cache that grows by one key and one value per token (§6.5). For dϕ=dv=128 the state holds 16,512 numbers. At 2⋅128 numbers per token, that is about what this head's KV cache holds after 64 tokens, and the state never grows.
Training. The recurrent form has T steps that must run one after another, which is slow on a GPU. If autograd keeps every intermediate state for the backward pass, it also stores Tdϕdv numbers. At T=8192 and dϕ=dv=128 in float32, the 4-byte format, that is 512 MiB for one head of one layer. Katharopoulos et al. (2020) avoided the storage by writing the gradients as cumulative sums too. The sums run forward in time for the queries and backward in time for the keys and values, so no intermediate state is stored. The parallel form costs O(T2) like ordinary attention, but it is all matrix multiplication, which GPUs do best.
The practical answer is the chunkwise algorithm of §21.5. It splits the sequence into chunks of Tc tokens, typically 64 to 256. It uses the parallel form inside each chunk and the recurrence across chunks, and gets most of the benefit of both. It is used for training and for prefill, the one parallel pass over the prompt before decoding starts.
Why can the causal form not use the non-causal shortcut directly? The non-causal right order computes one summary ϕ(K)⊤V, shared by all queries. Causally, every query needs its own prefix of that summary. That is why the causal form is a recurrence rather than one matrix product, and why training it fast needs the chunkwise algorithm.
Interview
Causal linear attention, recurrent and parallel, plus the decode step
This is the standard interview coding question on linear attention. Implement three functions for one head. Q and K have shape (T, d_k), V has shape (T, d_v), and phi maps an array of shape (..., d_k) to (..., d_phi).
causal_linear_attention_recurrent(Q, K, V, phi, eps=1e-6) loops over time. It must never build a (T, T) array, and the tests disable np.tril, np.triu, and np.tri while it runs.
causal_linear_attention_parallel(Q, K, V, phi, eps=1e-6) builds the masked kernel matrix.
linear_attention_step(S, z, q, k, v, phi, eps=1e-6) is one decode step. It takes the state S of shape (d_phi, d_v) and the normalizer z of shape (d_phi,) after t−1 tokens. It also takes one token's q and k of shape (d_k,) and v of shape (d_v,). It returns (o, S_new, z_new) with ot=St⊤ϕ(qt)/(zt⊤ϕ(qt)+ϵ), and it must not modify its inputs.
All three add eps to the denominator as written, and each token is included in its own sum.
Tests, verified solutions, and AI help, open once you add your API key.
Choosing the feature map
Everything so far holds for any ϕ. The choice of ϕ decides three things. It decides how close linear attention comes to softmax attention, how large the state is, and whether training is stable. There are four families, from the simplest to the most faithful to softmax.
Simple positive maps
Katharopoulos et al. (2020) used ϕ(x)=elu(x)+1 with dϕ=dk. They preferred it to relu(x)=max(x,0), because ReLU has zero gradient for negative inputs. Both maps are cheap and keep the state as small as it can be. The elu+1 map is positive, and ReLU only nonnegative. Neither approximates the softmax kernel.
One property of these maps matters a lot. A map is positively homogeneous if ϕ(cx)=cϕ(x) for every c>0, and ReLU and the identity both are. For such a map, scaling a query by c multiplies every kernel value by c, and the normalized weights do not change. So a query cannot make its attention sharper by growing longer. A softmax query can, since exp(cq⊤k) widens the gaps between weights exponentially in c. The elu+1 map is not homogeneous, since it equals x+1 for positive inputs. It still cannot sharpen without limit. For a long query cq, the positive entries of ϕ(cq) grow like cqi and the negative ones shrink to zero, so ϕ(cq) points along relu(q). The weights then settle at a fixed limit, proportional to relu(q)⊤ϕ(ks), which the +1 inside ϕ(ks) keeps close to uniform.
Random features that estimate the softmax kernel
Can a finite ϕ approximate exp(q⊤k) instead of replacing it? Choromanski et al. (2020) found a positive feature map that is random, and whose dot product equals the softmax kernel on average over the randomness. Their model is called the Performer. The idea rests on one fact about a standard Gaussian vector ω, its moment generating function, the average of eω⊤x as a function of x.
Start with one dimension. If ω is a standard normal number, then E[eωx]=ex2/2. So at x=1 the average of eω is e0.5≈1.65. In dk dimensions, take ω∼N(0,Idk) and a fixed x∈Rdk. Completing the square in the exponent gives
The middle step uses −21∥ω∥2+ω⊤x=−21∥ω−x∥2+21∥x∥2. The last integrand is the density of N(x,I), which integrates to 1 (§0.4 defines the multivariate Gaussian).
So eω⊤x−∥x∥2/2 averages to 1 for every x. Multiply two such factors, one for q and one for k, and the average becomes eq⊤k, as the derivation below shows. Each random direction ωi then gives one feature.
∂ Unbiasedness and variance of positive random features
The estimator is an average of dϕ independent copies of one random number,
So Var[Y]=E[Y2]−E[Y]2=e2q⊤k(e∥q+k∥2−1). Averaging dϕ independent copies divides the variance by dϕ. Dividing by the squared mean e2q⊤k gives the relative variance in the theorem. This is the mean squared error that Lemma 2 of Choromanski et al. (2020) states for these features. ∎
In plain words, each random direction ωi gives one positive feature. The product of two such features equals the softmax kernel on average. The noise of the estimate shrinks like 1/dϕ, with a constant that grows exponentially in ∥q+k∥2.
Now read the variance formula as an engineer would. Take queries and keys with independent unit-variance entries, as at initialization. Then ∥q+k∥2≈2dk, and after the dk−1/4 scaling of each vector it is about 2dk. At dk=16 that is 8, and the relative variance of one kernel value is (e8−1)/dϕ≈2980/dϕ. At dk=128 it is about 22.6, and e22.6≈7×109. No affordable dϕ estimates such kernel values well. The cell measures the error for 16 queries against 32 keys at dk=16, first with the vectors shrunk to half length and then at full length.
Python · cell 3
Why does the error fall more slowly at full length? Each feature is a log-normal random number, mostly small with rare huge values, and the rare values carry most of the variance. An average of dϕ of them settles into the 1/dϕ rate only once dϕ is well above that pair's relative variance per feature, e∥q+k∥2−1. Below that, a typical draw misses the rare values and underestimates the kernel. At the measured average of 7.4 that variance is about 1,600, far more for the longest pairs, and those pairs dominate the mean. So random features are a genuinely unbiased estimator, yet in practice they do not keep softmax quality in a language model, and the variance formula says why. An interviewer who asks about Performers wants exactly this answer.
Core
Positive random features for the softmax kernel
Implement the positive random features of the theorem. There is no temperature here, so use the inputs as given.
positive_random_features(X, Omega) takes X of shape (n, d_k) and Omega of shape (d_phi, d_k), whose rows are the random directions. It returns the features, of shape (n, d_phi).
softmax_kernel_estimate(q, k, Omega) takes vectors q and k of shape (d_k,) and returns the scalar estimate ϕ(q)⊤ϕ(k) of eq⊤k.
Tests, verified solutions, and AI help, open once you add your API key.
A Taylor feature map
The softmax kernel's trouble is its infinite series, so cut the series off. Keep terms up to second order, es≈1+s+s2/2 with s=q⊤k. Each term factors exactly into features. The constant is 1⋅1, and the linear term is q⊤k. The square is the dot product of the two outer products,
(q⊤k)2=i,j∑qiqjkikj=vec(qq⊤)⊤vec(kk⊤),
where vec lists a matrix's entries as one long vector. Take the pair from the start of the section, q=(1,2) and k=(3,1), so s=5 and s2=25. The outer products list as (1,2,2,4) and (9,3,3,1), whose dot product is 9+6+6+4=25. This is the three-feature map from that example with its two equal middle entries kept apart.
In plain words, a second-order Taylor expansion of the exponential is itself an exact kernel with 1+d+d2 features. It is always positive, so it can sit in the denominator safely.
The positivity comes with two caveats. First, the kernel is smallest at s=−1 and grows again below it. So a key with score −3 gets kernel value 2.5, while an orthogonal key, with score 0, gets 1. Softmax always gives more weight to a higher score, and this kernel does not. Second, the kernel grows only quadratically. So the ratio of two weights is at most polynomial in the scores, while softmax ratios are exponential.
Even so, Zhang et al. (2024) found that this map keeps two properties that make softmax work. Its weights have low entropy, meaning they concentrate on a few keys. And they rise with the score over the range of scores that trained models produce. Arora et al. (2024) made it the core of a model called Based.
The cost is the feature count. At d=128 it would be 1+128+16,384=16,513 features and a state of over two million numbers per head. Based therefore projects queries and keys down to d=16 first, giving dϕ=1+16+256=273. It pairs this with a small sliding-window softmax attention, in which each token attends with exact softmax to only the previous 64 or 128 tokens (§12.6). The window handles precise comparisons with nearby tokens.
Core
Taylor features and their cost
Implement taylor_features(X) for X of shape (n, d). It returns shape (n, 1 + d + d*d) in the order of the theorem, so that ϕ(q)⊤ϕ(k)=1+s+s2/2 exactly. The order is the constant, then the d linear features, then the d2 entries of vec(xx⊤)/2 in row-major order.
Then implement two memory counts, both returning Python ints.
taylor_state_bytes(d_head, d_v, n_heads, bytes_per=4) is the bytes of one layer's decode state. Here d_head is the width d of the queries and keys that enter the feature map (16 in Based, after the projection), and d_v is the width of the values. Count both St∈Rdϕ×dv and zt∈Rdϕ for every head, with dϕ=1+d+d2.
kv_cache_tokens(state_bytes, n_kv, d_k, bytes_per=2) is the smallest number of tokens T at which one layer's softmax KV cache takes at least state_bytes. The cache holds 2nkvdk numbers per token, a key and a value for each of its nkv key-value heads.
import numpy as np
def taylor_features(X):
return np.concatenate([np.ones((len(X), 1)), X], axis=1) # first order only
def taylor_state_bytes(d_head, d_v, n_heads, bytes_per=4):
raise NotImplementedError
Tests, verified solutions, and AI help, open once you add your API key.
Learned feature maps
If no fixed map matches the softmax, learn one that does. Hedgehog (Zhang et al. 2024) makes ϕ a single trainable layer with an exponential activation,
ϕ(x)=exp(W⊤x+b)=(ew1⊤x+b1,…,ewd′⊤x+bd′).
Here W∈Rdk×d′ is a weight matrix whose columns are the wi, and b∈Rd′ holds one bias per feature. In practice d′=dk, with W starting as the identity and b as zero. The map also appends the mirrored features e−(wi⊤x+bi), so dϕ=2dk and the cost stays O(Tdk2). Each head of each layer gets its own map, shared by its queries and keys.
How the map is trained depends on the starting point. In a model trained from scratch, it is learned with everything else from the next-token loss. To convert a trained Transformer, Hedgehog first freezes the model and trains only the maps, so that their attention weights match the softmax weights the same queries and keys produce. The loss is the cross-entropy between the two sets of weights. Then it fine-tunes the model with its usual loss. The paper reports that Hedgehog recovers over 99% of Transformer quality, both from scratch and when converting a fine-tuned model. Converting a pretrained 125-million-parameter GPT-2 gave a perplexity of 16.7 on WikiText-103 (perplexity is the exponential of the average next-token loss, §3.1).
LoLCATs (Zhang et al. 2024) scaled this conversion to Llama 3.1 70B and 405B in two steps. First it trains each linear attention to reproduce the output of the softmax layer it replaces, under a mean squared error, a step it calls attention transfer. Then it repairs the remaining error with LoRA, the low-rank fine-tuning of §14.5. The two steps together use as few as 40 million tokens. It also keeps a short sliding window of exact attention in every layer. Converting a pretrained model this way costs a tiny fraction of pretraining a new one, which is why it comes up in design interviews.
The widget compares softmax with the fixed maps above (elu+1, ReLU, random features, and Taylor) on one query that has one clearly relevant key among 32. Choose a feature map with the buttons. The head width is dk=16. The sharpness slider multiplies the query, which is what lowering a softmax temperature does. For random features a second slider sets dϕ.
Can a feature map focus attention on one key the way softmax does?
One query against 32 keys at head width 16. Key 12 points along the query.
Loading interactive figure…
ReLU does not move at all, because it is homogeneous and sharpness only rescales the query. The elu+1 weight creeps up and stops near uniform, at the limit derived above. Taylor rises with sharpness but levels off far below softmax. In the limit its weights become proportional to sj2, the squared scores, which do not concentrate on one key. Random features come closest at mild sharpness and the largest dϕ. A larger dk makes them worse, because the scaled query and key grow longer. They fall apart as sharpness grows, which is exactly where softmax concentrates its weight. We drew ten sets of features at dk=16, sharpness 1, and dϕ=512. They misplaced between 16 and 45 percent of the total weight, about 22 percent in a typical draw (the weight misplaced, under the chart). Their kernel values were off by 37 to 87 percent on average. Here is the comparison in one table.
feature map
dϕ
positive
approximates softmax
used in
identity
dk
no
no
layers with no denominator and an output norm (RetNet)
So far St has been bookkeeping. It is more useful to see it as a memory that stores key-value pairs and looks them up by content, which is called an associative memory. To see it, drop the denominator and use the identity feature map with unit-length keys. Writing a pair adds the outer product kv⊤ to the matrix. Reading with a key kj returns S⊤kj.
In general, after n writes the state is S=∑s=1nksvs⊤∈Rdk×dv, and reading with stored key j gives
In plain words, what comes back is the stored value plus crosstalk. Crosstalk is interference from every other pair, each weighted by how similar its key is to the query.
In plain words, a dk×dv memory holds dk pairs perfectly if their keys are orthogonal, and no linear read can do better. With random keys the noise grows steadily. Its energy is (n−1)/dk times the signal's, so the signal-to-noise ratio is about dk/(n−1). In high dimension the crosstalk is nearly orthogonal to vj. So the retrieved vector has cosine about 1/1+(n−1)/dk with the right value, about 0.71 at n=dk.
Causal linear attention writes one pair per token and never erases anything. A layer with dϕ=128 that has read 100,000 tokens is a memory loaded nearly eight hundred times past its exact capacity. With a feature map the same argument holds with dϕ in place of dk. That is one honest reason to want a large dϕ, as with Taylor features. Schlag et al. (2021) took another route. Their feature map, called DPFP, raises dϕ to a multiple of dk without random sampling, and its features are sparse, so different keys tend to be orthogonal after the map. The cell measures retrieval for orthonormal and for random keys.
Python · cell 4
Orthonormal keys retrieve perfectly up to n=d and cannot exist beyond it, so that column shows nan. Random keys lose fidelity smoothly. The measured cosine tracks 1/1+(n−1)/d, and the measured crosstalk energy tracks (n−1)/d. An interviewer who asks how much a linear-attention layer can remember wants these two facts, exact recall up to dϕ pairs and crosstalk that grows as (n−1)/dϕ beyond it.
The widget lets you watch a memory of width d=32 fill one write at a time. Choose the kind of keys, orthonormal, random, or correlated (all sharing one direction). Then press Write one by one, or drag the number of pairs n.
How many key-value pairs can a d by d state hold?
Each bar is one stored pair, as tall as the cosine between its value and what its key reads back.
Loading interactive figure…
Interview
A matrix state as an associative memory
Implement an outer-product memory with three functions.
write(K, V) takes keys of shape (n, d_k) and values of shape (n, d_v). It normalizes each key to unit length and returns S=∑sk^svs⊤ of shape (d_k, d_v).
read(S, q) normalizes the query of shape (d_k,) and returns S⊤q^ of shape (d_v,).
crosstalk_energy(K) normalizes the keys and returns the mean over j of ∑s=j(k^s⊤k^j)2. The theorem predicts about (n−1)/dk for random keys.
import numpy as np
def write(K, V):
return K.T @ V
def read(S, q):
return S @ q
Tests, verified solutions, and AI help, open once you add your API key.
A fixed state against a growing cache, at real scale
How big is the state of a real linear-attention layer, and when does it beat a KV cache? The answer decides how many sequences fit on one GPU, so it is a standard question in a systems interview.
The cell checks these numbers.
Python · cell 5
Speed follows memory. Katharopoulos et al. (2020) generated CIFAR-10 images, sequences of 3,072 values, 4,462 times faster than a softmax Transformer that recomputed attention over the whole prefix at every step. The honest comparison is a softmax Transformer that caches its keys and values, and against that it was still more than 50 times faster (their appendix). Based (Arora et al. 2024) reached 24 times the generation throughput of FlashAttention-2 when generating 1,024 tokens with 1.3-billion-parameter models. On recall-intensive tasks, where fixed states struggle most, it beat Mamba and other sub-quadratic models of its size by 10.36 accuracy points on average in the revised paper. The first version, whose abstract arXiv still lists, reported 6.22.
The MiniMax paper also gives the clearest statement of the cost. In its scaling experiments, a pure linear-attention model matched softmax attention on most downstream tasks. It fell short on needle-in-a-haystack retrieval, finding one planted fact in a long context. The hybrid with one softmax layer in eight matched or beat softmax attention on retrieval. The next part of this section explains that result.
Why linear attention lags softmax attention
For years after 2020, linear attention trained from scratch was consistently worse than softmax attention at the same size. Four mechanisms account for the gap, and each one points to a fix that the rest of this chapter develops.
It is low rank. The kernel matrix ϕ(Q)ϕ(K)⊤ is a T×dϕ matrix times a dϕ×T matrix, so its rank is at most dϕ, however long the sequence. Masking with L raises the rank of the whole matrix. But every block that lies entirely below the diagonal is still a block of ϕ(Q)ϕ(K)⊤, of rank at most dϕ. The softmax matrix exp(QK⊤/dk) applies the exponential entry by entry, which destroys low rank, and is typically full rank. A layer whose blocks below the diagonal have low rank is a recurrence with a small state, because the rank is the amount of information the past passes to the future. §21.6 makes that equivalence exact, through what are called semiseparable matrices.
Python · cell 6
The softmax kernel matrix has full rank 256, and its lower-left block full rank 128. The elu+1 matrix and its lower-left block both have rank 16, which is dϕ=dk, whatever T is.
It cannot be sharp. Softmax turns a score gap Δ into a weight ratio eΔ, so a query can put nearly all its weight on one key. Homogeneous maps cannot sharpen at all, elu+1 adds a floor that flattens everything, and Taylor features give only polynomial ratios. Zhang et al. (2024) measured two differences. Linear attentions trained from scratch had higher-entropy weights than softmax, and their weights did not rise steadily with the query-key dot product. Restoring these two properties closed most of the quality gap. The widget above shows the flatness directly.
Its memory is finite and it never forgets. By the memory theorem, a dϕ×dv state retrieves at most dϕ pairs exactly. With random keys its retrieval cosine falls as 1/1+(n−1)/dϕ. Causal linear attention adds one pair per token with equal weight forever, so old and irrelevant pairs crowd out new ones. Qin et al. (2022) named a related symptom attention dilution, weights spread evenly over long sequences instead of concentrating on nearby tokens.
Its normalizer is unstable. The denominator zt⊤ϕ(qt) grows roughly linearly in t, so each new token's share of the weight shrinks like 1/t. The gradients are the deeper problem. Write the weight of key s as pts=κts/∑rκtr, with κts=ϕ(qt)⊤ϕ(ks). Its derivative with respect to the kernel value κtr is (δsr−pts)/∑r′κtr′, where δsr is 1 if s=r and 0 otherwise. So the derivative can be as large as one over the denominator. Nothing keeps the denominator away from zero, so the gradient has no upper bound. Softmax weights, as functions of the scores, have derivatives of at most 1/4.
Qin et al. (2022) proved this unboundedness and measured its effect. Over training, the relative standard deviation of the gradients was 0.58 for elu+1 and 0.47 for Performer, against 0.25 for softmax. Their model, TransNormer, deletes the denominator and normalizes the output instead, O=RMSNorm(ϕ(Q)(ϕ(K)⊤V)). RMSNorm divides each output vector by its root mean square and multiplies it by learned gains (§5.2). That brought the number down to 0.20.
Taming the denominator is now standard. MiniMax-01's linear-attention layer, which it calls lightning attention, builds on TransNormer. RetNet, GLA, Mamba-2, and Gated DeltaNet also normalize the output, and none of them depends on the division by zt⊤ϕ(qt). (RetNet does divide each row of its scores by the absolute value of their sum, clamped below at 1, but only for numerical precision. The normalization after it cancels any such scale.) So these layers no longer need ϕ to be positive. MiniMax-01's released code, for example, applies SiLU, xσ(x) with σ the logistic sigmoid (§5.3), to queries, keys, and values. It keeps the state in float32 and multiplies it by a fixed decay per head at every step. It puts an RMSNorm and a sigmoid output gate after the read. A few designs keep a denominator but bound it below, dividing by max(∣zt⊤qt∣,1), as the deeper box below shows.
The decay is the other half of the modern recipe. The rest of the chapter adds the two missing abilities in turn. First the state learns to forget, through principled continuous-time decays (§21.3), then through decays chosen by the input (§21.4) and gates (§21.6). Then it learns to correct itself, through the delta rule of §21.6, which overwrites the value at a key instead of adding crosstalk.
layer
training cost
decode cost per token
decode memory
exact softmax
recall
softmax attention
O(T2d)
O(Td)
KV cache, O(Td)
yes
exact, the reference
linear attention, elu+1
O(Td2)
O(d2)
state, O(d2)
no
weak, about d pairs
Performer
O(Tdϕd)
O(dϕd)
O(dϕd)
unbiased estimate
weak in practice
Based (Taylor plus a 64 to 128 token window)
O(Tdϕdv) plus window
constant
constant
to second order
strong for its state size
normalized linear attention with decay (lightning, RetNet)
O(Td2), chunked
O(d2)
O(d2)
no
forgets gracefully, still finite
hybrid, one softmax layer in four to eight (§21.6)
mixed
grows only in softmax layers
small cache
in some layers
close to softmax
In the Based row, dϕ is the projected Taylor dimension, 273 in the paper.
In PyTorch
There is no linear attention in core PyTorch. Production kernels live in libraries such as flash-linear-attention, which use the chunkwise algorithm of §21.5. The block below writes causal linear attention three ways with plain tensor operations. The first is the masked quadratic form. The second is the cumulative-sum form, which stores every St, so the training-memory problem above shows up as the size of one tensor. The third is the recurrent decode loop. Then the block checks that autograd gives the same gradients through the quadratic form and the loop.
Choromanski et al. (2020). Rethinking Attention with Performers. Positive orthogonal random features (FAVOR+). Lemma 1 is the unbiasedness result, Lemma 2 the variance comparison with trigonometric features, and Theorem 2 the gain from orthogonality.
Qin et al. (2022). The Devil in Linear Transformer. Why the normalizer gives unbounded gradients, attention dilution, and the normalized replacement that most modern layers use.
🎬 Transformers are RNNs: Fast Autoregressive Transformers with Linear Attention (Paper Explained) · Yannic KilcherA walk through Katharopoulos et al., from the kernel view to the recurrent form with a matrix state and its constant-time decoding.🎬 Rethinking Attention with Performers (Paper Explained) · Yannic KilcherPositive orthogonal random features, why they are unbiased for the softmax kernel, and why trigonometric features fail there.🎬 Linear Transformers Are Secretly Fast Weight Memory Systems (Machine Learning Paper Explained) · Yannic KilcherThe fast-weight reading of the state, its capacity limit, and the delta-rule fix that Section 21.6 develops.🎬 Linear Attention and Beyond (Interactive Tutorial with Songlin Yang) · Sasha RushOne of the field's main researchers goes from linear attention to gated and delta-rule layers and how they are trained fast on GPUs.