Highlights of key papers and progression of Neural Networks over the last decade (ish). This isn't learning material -- its a reference!
Last Updated: 2026-8-15
We'll Start with the Recurrent Neural Net
Because we have to start somewhere.
A Neural Probabilistic Language Model ("Curse of Dimensionality") establishes why predicting next token can be effective but difficult to scale due to the sheer number of dimensions needed when one-hot encoding tokens in a vocabulary. The authors propose adding an Embedding layer as the first action in a network, which is learned during the training process. The length (size) of an Embedding vector remains a hyper-parameter. Through this process tokens naturally organize themselves in space, so similar tokens cluster together based on the training data. Embeddings being smaller than the entire vocabulary helps solve dimensionality while encoding more information.
The Unreasonable Effectiveness of Recurrent Neural Networks + Attention & RNNs establish the importance of prior tokens needing to inform latter tokens through building up an internal context matrix. This proves to be very effective but also limiting -- an internal context only holds so much information and becomes "lossy". When we combine this concept with Attention we find even greater success, leading to Attention is all You Need (and the transformer)
The Transformer
The Illustrated Transformer demonstrates the structure of a Transformer. This is not the same as 'modern' GPTs. A transformer has two halves: an Encoder and a Decoder. Each side is made of a stacks of transformer layers, where each item has:
- A self-attention layer
- (for Decorders when there are Encoders) a Cross-attention layer
- A feed-forward neural network (FFN) The Encoder side attends to the entire input sequence at once -- it can see tokens in the "past" and "future" of the current token you're trying to predict. During training Encoders build up an internal representation which Decoders then reference via cross-attention during inference. This proves effective in certain tasks like natural language translation. Modern models such as GPTs (as described by The Illustrated GPT-2) don't use an encoder stack, however, and just leverage Decoders. In practice, predicting next tokens aren't as effective in Encoders because they want to see the entire sequence during training/inference (spoiling the prediction). Casual attention solves this by forcibly zero'ing the softmax scores for tokens in later positions than the current one being predicted. This also means the cross-attention layer is ditched.
Self Attention & The Decoder Calculation
How is self-attention implemented?
Inputs Our token embeddings for all tokens in the input thus-far and their positional encodings (relative to each other/the start of input - one-hot vectors). The input+position are combined to yield a single vector of dimensionality width. Inputs go through "layer normalization" before entering each transformer block, where each token row gets rescaled to handle high skew.
Attention Input is fed through a self-attention layer. This layer has 3 parameter matricies learned during training: Query (Wq), Key (Wk), and Value (Wv). At inference time this means:
- Each token's Embedding is mat-muled against each
Wq,Wk,Wvto produce a Query/Key/Value vector per token. These get cached across iterations, so only the latest token really computes something new here. This calculation can be batched: if we concatenate theWq,Wk,Wvtogether horizontally, then mat-mul against a vertical embedding vector yields a concatenated vectorVq,Vk,Vv - The current token's query vector is multiplied by all the key vectors (dot product) of all the prior tokens. This tells us how well each token matches against the current one, generating a "score".
- This score is divided by the sqrt of the dimensionality of the
Vk. If we're training, then any token after this token's position is also zero'd (-inf) to prevent revealing the true next tokens. Softmax is then applied. - Each value vector is then multiplied against this score and the entire list summed, yielding a new result vector
Z
Multi-head attention (MHA) has proven valuable, which trades computational cost for even better performance in finding what to attend to. There's different ways to implement this.
- In Split Attention Heads ("SAH") Each "head" is just an additional self-attention evaluation (the above steps), using sub-slices of the QKV matricies. For example if our dimensionality is
768(soVq,Vk,Vv& our token embeddings are that long) and we had12"attention heads" then each head would operate on64indicies at once. - In the original Transformer paper each head was a fully separate
Wk,Wq,Wvmetric per head. This is aimed to provide the model more computational / learning space to find more associations and meaning from the training data.
After obtaining each head's Z vector, heads are merged by:
- In "SAH" case: concatenating them back into a single vector (thus yielding our dimensionality again -- that
768value from earlier). A square attention matrix of dimensionality width and height (A) is then mat-mul-d which will now yield out output vector for the Feed Forward Network. - In original case: concatenate each head's resulting matrix and then matmul'ing by an additional weight matrix
Wof shape#Heads*Dimensionality x Dimensionality(so not square) to reduce it back down to dimensionality size. In both cases a matrix is used to make the manual concatenation of heads "normalized".
Performing self-attention as Matrix Operations -- the above demonstrated vector-wize operations but much of this can be made matrix ops. This will be more relevant for training side of the equation.
- Concatenate the embedding tokens & rebuild
K/Q/VusingWk,Wq,Wv. More specifically the KV cache will be used to restore some of the prior token's K/Q/V when rebuilding these matricies. - The rest of the steps are consolidated:
Softmax(Q*K^T / dk) * V = Z. (wheredkis that dimensionality ofKmentioned earlier --768). - In the case of multiple attention heads, the same applies: The
Zmatricies are concatenated from the result of each head and then multiplied by a matrix to get the result back down to the size our FFN expects.
Residuals -- before feeding this result into the FFN, the orignial input embedding is element-wise added back to the self-attention result above forming a residual connection. This is also done after each FFN result before passing to the next decoder in the stack.
The Feed Forward Network
This part gives the transformer it's space to learn/encode information after the attention context has been baked into the input. The sizing of this is entirely a hyper-parameter. In GPT2 this was a 2 layer network where:
- The first layer is 4x the size of the model (768 -> 3072). The 4x choice comes from the original transformer paper, which used 512 -> 2048.
- The second (and always last layer) is just the inverse to project back down to model dimensionality (eg 3072x768)
(Bigger Picture)
Stepping back, the transformer takes the effectiveness of an RNNs internal representation but solve the lossy problem by just looking up the prior context "on the fly" through the Key & Query vectors, and extract the learned information about each token through the V vector. Phrased another way:
- Q asks "what should I attend to" (comparing to all Ks)
- K determines whether something should attend to a token
- V determines what might be useful to pass along when something does attend While you could remove the concept of V in favor of just the input token itself, V holds much more information about each token in practice. During training it can learn more about the tokens that can inform later inference. For example a 'dog' has many properties about this term: it's singular, a noun, and a subject (etc). The Value vector allows this information to be learned and stored.
These modern models (to put this in perspective) don't make bigger and bigger individual layers but instead stack them deeper and deeper. GPT-3 had 175B parameters: 96 Decoder layer, 96 attention heads, 12,288 dimensions in each layer.
Faster Attention & Caching
Attention heads directly make the entire computation slower. One Write-Head is All You need & GQA: Grouped Query Attention discuss the implications of this. While training these models can parallelize / batch feed forward, inference has to do one token at a time making the inference side carry a different cost profile than the training side (a token is predicted and then the entire phrase is re-fed through).
This is where the KV cache concept comes in -- there's no need to recompute the KV vectors of each prior token on each future token. But it does mean the context size ("Sequence Length") worth of tokens (and specifically their KV vectors) must be held onto. Key Value matricies (& the KV cache) scale with 2 * L * SequenceLength * model dimensionality:
- 2: 1 K and 1 V matrix per layer
- L: Number of layers / repeatedly stacked decoders
- SequenceLength: Number of tokens currently predicted
- Dimensionaliy: How wide these vectors are (12,288 in the GPT-3 example) Queries don't need caching because they are only needed in the context of the currently predicting token.
These articles find that having many heads sharing fewer KV matricies is effective -- we can still gain the performance of additional Heads without the overhead of storing (and thus loading) multiple different KV matricies. In practice, having some number of KV matricies 1 < Num(KV) < Heads is best: "Grouped Query Attention" proposes having groups of heads share the same KV balancing the performance of 1 KV per head and the performance of 1 KV for all heads.
Bigger Data & Training
Training becomes its entirely own data engineering problem space. Rather than speaking in terms of epochs (eg running the same training dataset through the network multiple times) we're now looking at how many tokens we can run through the model. The laws of large data apply: a sufficiently large dataset will observe all possible trends and distributions. Chinchilla ('Training Compute Optimal Large Language Models') affirms this: a bigger model (more parameters) actually performs worse than a smaller model with a much higher ratio of tokens fed through during training. The rule of thumb has become 20 tokens / parameter is needed in training.
A series of other papers teach us about harvesting data for the initial "pre-" training:
- The quality and scope of data plays a much larger role than the volume of data. FineWeb finds chosing a mix of data sampling skews model behavior as desired. Using a network to label data on a small subset to then apply more broadly is effective.
- You don't need labelled data, you do need contextual data. StarCoder & 'The Stack' leverage the surrounding information like READMEs, Commits+OldCode+NewCode, Issues+Debug+Discussion (etc) to teach the model how to code. It's effectively labelled data, but richer.
- Training data doesn't need to be 'next' token structured. You can provide the prefix, suffix, and ask it to fill in the middle.
- Dolma discusses various data structuring as part of a massive open dataset. Duplication is actually a common discussion point, as it's common for "boilerplate" to appear very often, skewing the model's training just by sample size. It's not enough for strict deduplication, there has to be techniques to find the same thing spelt out different ways. Removing all duplication isn't desired either, as repetition has value to define well-established facts and patterns -- it's when there's orders of magnitude more that it's problematic.
When it comes to post-training (or tuning the model's outputs to match human expectations) the majority of discussion is around "Alignment". Most of this wasn't very interesting to me. Two concepts stood out:
- RLHF: Reinforcement Learning from Human Feedback requires a lot of human labelling and data generation around preferred outputs, and then complications with building up a reward model to then help train models on what makes a "good" response vs a "bad" one.
- DPO: Direct Preference Optimization (associated paper) skips most of that by just taking human preferences in the post-training lifecycle, skipping the complexities of RLHF.
Reasoning
Back to model design, we arrive at Reasoning. Chain-of-Thought was a large breakthrough in improving logical thought processing, like math word problems -- it didn't require any changes to the model itself but instead how you prompt the model. Providing the model with examples of "thinking through the problem aloud" and then asking it to then solve a similar problem would have it mimic your example approaches and arrive at correct answers far more often. This concept could actually be trained into the network, to such a degree that this prompting technique isn't needed in the latest GPTs.
Self Consistency provides another framework for improving model results at the harness level by having it process the same question multiple times, using different avenues for getting to the final answer. The harness would then sample the provided responses to find which was the most frequent and treat that as the final, correct result. This, combined with Chain-of-Thought pushes performance even higher.
(TODO): Continue! ReAct DeepSeek-R1