From bigrams to GPT-2, one component at a time (in Jax)
The article walks through building and training a GPT-2 Small-scale model from scratch using JAX, progressing from simple bigram models to a full transformer architecture component by component.
Background
- This is a technical walkthrough by Giles Thomas (co-founder of the AI startup Flyte) showing how to build and train GPT-2 Small (a 124-million-parameter language model) entirely in JAX (a high-performance numerical computing library from Google, similar to PyTorch but designed for speed and automatic differentiation).
- GPT-2 was OpenAI's landmark 2019 language model that showed large-scale unsupervised text generation was possible. "GPT-2 Small" is its smallest variant (124M params), making it feasible for an individual to train from scratch.
- The post follows Andrej Karpathy's famous "Let's build GPT from scratch" video but reimplements everything in JAX instead of PyTorch — significant because JAX is favored in research for its speed, functional programming style, and ability to compile code for GPUs/TPUs.
- "Bigrams" refers to the simplest possible next-token predictor (pairs of tokens), used as the starting point before layering on attention mechanisms, embeddings, feed-forward networks, and the full Transformer architecture that powers modern LLMs.
Max Weinbach says he had early access to OpenAI's new model GPT-5.6 Sol, calling it his favorite model by far. He highlights that it never gives up and will keep reasoning until it's done. OpenAI announced that GPT-5.6 Sol, along with Terra and Luna, will launch publicly on Thursday, with preview access expanding globally now.
Newer Claude models sometimes invent extra keys in tool call arguments, breaking validation in Pi's edit tool. The author suspects post-training for Claude Code's forgiving harness makes alternative schemas fail. This suggests closed RL training can degrade general tool-use reliability.
The author builds and trains a GPT-2 small model from scratch in JAX, starting from a basic bigram-style model and incrementally adding components like LayerNorm and Transformer blocks. Achieved a final loss of 3.418, beating their PyTorch version (3.538) and original GPT-2 small (3.499) on the same test dataset.
The author debugged a Flax NNX training loop where the loss was stuck at 10.82, indicating random guessing. By hashing the model parameters and comparing hashes across steps, they discovered the parameters weren't changing. The root cause was using @jax.jit instead of @nnx.jit, which is needed for proper in-place state propagation of parameter updates in NNX.
Building a JAX training loop for an LLM from scratch using Flax NNX and Optax. First validated the harness with a minimal "A-to-A" model (embedding then projection) before adding Transformer layers. Key challenges included fixing JAX's GPU memory default and slow data iteration by committing data to CPU memory.