Feed-Forward Networks › Interpreting the FFN as Key-Value Memory
Language AI HandbookAll chapters Feed-Forward Networks › Interpreting the FFN as Key-Value MemoryOne section · Sections in this chapter5 / 13 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
One of the most illuminating ways to understand the FFN is to see it as a neural network layer and as an associative memory: a structure that stores key-value pairs in its weights and retrieves the appropriate values when presented with matching inputs. This interpretation, developed by researchers at Tel Aviv University and other institutions, helps explain how transformers store and retrieve factual knowledge, and why simply scaling up the FFN increases a model's capacity to "know" things.
The idea is elegant. Consider the first layer's weight matrix . Each column of can be thought of as a "key" that matches certain input patterns. When we compute , we are essentially computing the dot product between the input and each of the keys. Each element of the resulting vector measures how well the input matches the corresponding key.
To make this precise: the pre-activation value for hidden dimension measures the alignment between the current input and the -th key pattern. Given an input and the -th column of (call it ), this alignment is:
where:
- : the pre-activation value for hidden dimension , measuring how well the input matches key
- : the input vector (-dimensional), representing the current token's contextual state
- : the -th column of , encoding the pattern that key is tuned to detect
- : the -th element of the bias vector , which acts as a threshold, biasing the key toward activation or suppression
When the input aligns well with key (high dot product), the corresponding hidden dimension activates strongly. After ReLU, only positive activations survive, so keys that match the current input "fire" while keys that don't match are silenced. This is exactly how an associative memory works: present a query, retrieve only the memories that match.
The second layer's weight matrix contains the "values" associated with each key. Each row of (call it for the -th row) is the value vector that gets added to the output when hidden dimension is active. The final FFN output is a weighted sum of these values, where the weights are the hidden activations:
where:
- : the post-activation strength of the -th key match
- : the -th row of , encoding the value retrieved when key fires
- The sum runs over all key-value pairs, but in practice only the active (nonzero) values contribute
The feed-forward layer can be interpreted as an associative memory where columns are keys, hidden activations are match scores, and rows are values. Input patterns that match certain keys retrieve their associated values. With key-value pairs per layer and dozens of layers per model, the total storage capacity of the FFN weights is enormous.
This memory interpretation explains several important empirical observations about transformers. Researchers have found that specific neurons in FFN layers activate for particular concepts: individual neurons that fire consistently for "the Eiffel Tower," for "programming languages," or for "past tense verbs." These neurons are not hand-designed. They emerge from training, as the model discovers that certain hidden dimensions reliably encode certain patterns. The FFN learns to store factual associations in its weights, and the attention mechanism retrieves them by routing relevant input patterns through the FFN.
This interpretation also explains a peculiar phenomenon called "knowledge editing" in language models. When researchers want to update a model's stored facts (for instance, changing "The president of France is X" to a newer value), they can sometimes accomplish this by modifying specific rows of FFN weight matrices. The change propagates naturally because those rows encode the associated value that gets retrieved when the "president of France" key fires.
The memory interpretation also clarifies why larger FFN dimensions store more knowledge. More hidden dimensions means more key-value pairs, which means more distinct patterns the model can recognize and more distinct responses it can retrieve. This is why scaling the FFN dimension is one of the primary ways to increase a model's factual capacity.
Let's visualize this interpretation with a concrete example:
# Interpret FFN as key-value memory
d_model_small = 8
d_ff_small = 16
W1_small = np.random.randn(d_model_small, d_ff_small) * 0.5
b1_small = np.zeros(d_ff_small)
W2_small = np.random.randn(d_ff_small, d_model_small) * 0.5
b2_small = np.zeros(d_model_small)
# Create an input that strongly activates certain hidden dimensions
x_test = np.random.randn(d_model_small)
# Compute hidden activations (before and after ReLU)
pre_activation = x_test @ W1_small + b1_small
hidden_activations = relu(pre_activation)
# See which "keys" were matched (high activation)
active_dims = hidden_activations > 0.5FFN as Key-Value Memory: Input dimension: 8 Number of 'keys' (hidden dim): 16 Pre-activation (dot product with keys): [ 2.89 -0.3 -1.39 1.7 0.28 0.9 1.25 -0.09 -0.54 1.3 -2.01 -0.44 -0.15 3.36 0.76 -1.39] After ReLU (matched keys): [2.89 0. 0. 1.7 0.28 0.9 1.25 0. 0. 1.3 0. 0. 0. 3.36 0.76 0. ] Strongly activated dimensions: [ 0 3 5 6 9 13 14]
Let's visualize this sparsity pattern across multiple inputs to see how different inputs activate different subsets of hidden dimensions:

The heatmap reveals the key-value memory character directly. Each column represents one hidden dimension (one key-value pair). The white cells are zero, meaning that key did not fire for that input. The blue cells indicate firing keys, with darker blue indicating stronger activation. Notice that no two input samples have exactly the same activation pattern: different inputs retrieve different combinations of stored associations. This input-dependent sparse access is what makes the FFN such a powerful memory structure.
This sparsity also has practical implications for efficiency. In a model with large , only a fraction of hidden dimensions are nonzero for any given input. Methods that exploit this sparsity can skip computation for inactive dimensions, reducing the compute needed well below the theoretical maximum. Recent work on ReLU-based sparse FFNs has shown that sparsity rates of 90% or higher can be achieved with minimal quality loss, meaning only 10% of hidden dimensions are needed for most tokens.