Let's reproduce GPT-2 (124M)
Karpathy builds GPT-2 124M from scratch in PyTorch, optimizes it for speed, trains on FineWeb-Edu, and matches OpenAI performance overnight.
Key takeaways
10 points- 1Build the model from scratch before loading weights to guarantee correctness.
- 2Stack TF32, bfloat16, compile and Flash Attention for >10× wall-clock gains.
- 3Pad vocab size and other dimensions to CUDA-friendly multiples.
- 4Follow GPT-3 hyperparameters: AdamW (0.9,0.95), 6e-4 LR, cosine decay, 0.5 M tokens per batch.
- 5Use gradient accumulation and DDP to reach large batch sizes on limited hardware.
- 6Evaluate validation loss and HellaSwag every 100 steps for early signal.
- 7Weight tying between embeddings and LM head saves 30 % of parameters.
- 8Residual initialization scaled by 1/√N prevents activation variance explosion.
- 9FineWeb-Edu provides high-quality educational tokens that train faster than raw web text.
- 10Modern single-GPU throughput of ~200 k tokens/s makes GPT-2 124M training an overnight job.
Summary
Karpathy reproduces the full GPT-2 124M training run in PyTorch, from model construction to overnight results on 8 GPUs.
Core Architecture
- Decoder-only Transformer with 12 layers, 768 dim, 12 heads and learned positional embeddings (0:00-12:02).
- Pre-norm residual blocks, GELU MLP and weight tying between token embeddings and LM head (24:05-36:09).
Speed Stack
- TF32, bfloat16 autocast, torch.compile and Flash Attention cut iteration time from 1000 ms to 96 ms (1:24:26-2:12:39).
- Vocabulary padded to 50304 and fused AdamW add further gains (2:12:39-2:24:41).
Training Setup
- GPT-3 hyperparameters: AdamW betas (0.9,0.95), 6e-4 max LR with 715-step warmup + cosine decay, 0.5 M token batches via gradient accumulation and DDP (2:24:45-3:00:52).
Data & Eval
- FineWeb-Edu 10 B token shards; validation loss and HellaSwag every 100 steps (3:12:58-3:37:02).
Results
- 40 B tokens yield 33.2 % HellaSwag, nearly matching original GPT-2 124M while using 10× fewer tokens (3:49:08-4:01:25).
Deep read
Executive Summary
This analysis dissects Karpathy’s in-depth exploration titled 'Let’s reproduce GPT-2 (124M)' where the GPT-2 124M model is reconstructed from scratch in PyTorch, then accelerated via a suite of hardware- and software-level optimizations. The walkthrough covers architectural recreation (decoder-only Transformer with weight tying between input embeddings and the language modeling head, trainable positional embeddings, and an LM head projecting to 50257 vocab tokens), loading OpenAI’s released weights for verification, building a clean forward pass to produce logits, and implementing a training loop with a simple data loader. The video then layers in speed optimizations: mixed precision (bf16/TF32), Torch.compile, Tensor Cores, and Flash Attention, plus memory-conscious strategies like vocabulary padding to a nice number and kernel-fusion-aware code paths. It moves into more advanced training regime details: AdamW with gradient clipping, warmup + cosine learning rate scheduling, gradient accumulation to simulate large batch sizes, and Distributed Data Parallel (DDP) to utilize multiple GPUs.
Data strategy is a major pillar: from small Tiny Shakespeare debugging data to FineWeb EDU (educational subset) for scalable training. The evaluation suite includes HellaSwag, and an auxiliary sampling exercise to observe generation quality. The video culminates with overnight runs (even a 40B-token-scale pretraining scenario) and a discussion of results, including the surprising observation that 10B tokens could surpass GPT-2’s baseline under certain data distributions, plus a note about hardware- and data-driven optimization limits. A comparative note highlights llm.c as a highly optimized C/CUDA reference implementation and underscores that PyTorch-based pipelines at this scale can rival native implementations in speed with careful engineering.
This piece provides a practical blueprint for students and professionals to reproduce a GPT-2-like model from scratch: re-implement the architecture, load and map existing weights for verification, train with disciplined data and hyperparameters, and push performance with state-of-the-art optimizations, all while maintaining a rigorous eye on evaluation metrics and reproducibility. The content also serves as a foundation for exploring larger models (GPT-2 variants, GPT-3 scale) and modern data strategies (FineWeb EDU and beyond).
Major Topic: Reproducing GPT-2 (124M) from scratch
00:00: Intro & Goal
- Detailed notes: Karpathy announces the Zero to Hero project goal: reproduce GPT-2 at the 124M parameter size from scratch, then optimize training speed, align hyperparameters with GPT-2 and GPT-3 papers, run training, and examine model generations the next day. He emphasizes that GPT-2 has a mini-series of models (124M up to 1.5B) and that the 124M model is used to plot scaling laws in downstream tasks.
- Key points:
- GPT-2 124M: 12 Transformer layers, 768 hidden dimension, 50257-token vocabulary. - The “miniseries” concept explains why multiple model sizes exist and are plotted on the x-axis for scaling laws. - He plans to compare with published results (GPT-2, GPT-3) and to reuse the OpenAI weights where possible, while re-implementing training from scratch.
- Notable lines (verbatim):
> "we are going to reproduce the gpt2 model the 124 million version of it" (00:00) > "as the model size increases you're getting better at Downstream metrics" (00:00)
> Important context: The video frames the task as a practical synthesis of architecture, initialization, data handling, and training optimizations that historically made GPT-2 tractable on modest hardware. The approach blends re-implementing from scratch with leveraging openly released weights, to validate the same family of models and their training regimes.
00:03:39 Exploring the GPT-2 (124M) OpenAI Checkpoint
- Detailed notes: Karpathy loads the GPT-2 124M checkpoint from OpenAI, noting OpenAI released weights and a GPT-2 paper but not always training hyperparameters in full. He demonstrates loading via Hugging Face Transformers, inspecting state dict shapes, and recognizing the 50257-token vocabulary and 768-dim embeddings. The 1024 max sequence length provides 1024 position embeddings (for token positions).
- Key points:
- The 124M model has 12 Transformer layers with 768 hidden units; it uses a decoder-only Transformer (no encoder). - The Hugging Face GPT-2 implementation handles converting weights from TensorFlow to PyTorch and exposing a PyTorch-friendly interface. - The state dict keys show the embedding matrices (token embeddings, positional embeddings) and all the Transformer blocks.
- Notable lines (verbatim):
> "the 124 million parameter had 12 layers in the Transformer and it had 768 channels in the Transformer" (00:03:39) > "we can load it using hugging face Transformers" (00:03:39)
## 00:13:47 SECTION 1: Implementing the GPT-2 nn.Module - Detailed notes: Karpathy sketches a plan to implement GPT-2 in PyTorch from scratch, mirroring Hugging Face’s naming and structure so that weight mapping from the HF state dict remains straightforward. The skeleton mirrors the GPT-2 architecture: token embeddings (wte), positional embeddings, a stack of decoder blocks (H=12), a final layer norm, and the LM head that maps hidden states back to vocabulary logits (768 -> 50257) without a bias. - Notable points: - GPT-2 uses a decoder-only Transformer; GPT-2 differs from the encoder-decoder Transformer in the attention and normalization placement (LayerNorm position changes; an extra pre-final normalization exists in GPT-2). - The block uses a residual stream with pre/post normalization variants, and a nonlinearity G (Gated Linear Units variant) rather than ReLU in the MLP. The exact GPT-2 nonlinearity historically used is the exact (or a close) G nonlinearity; the video discusses the rationale for using the G(z) variant (to avoid dead ReLU issues). - Notable lines (verbatim): > "we want to write the GPT model from scratch... in parallel" (00:20:00) > "the Block Normalization inside the residual stream is a design choice in GPT-2" (00:21:00)
## 00:28:08 Loading the HuggingFace GPT-2 Parameters - Detailed notes: He loads the 124M model from HF, inspects keys, prints shapes (e.g., WTE: 50257 x 768), and demonstrates token embeddings, position embeddings, and the rest of the weights. This step confirms that the 124M checkpoint can be fed into a PyTorch module that mirrors the HF naming scheme to enable easy weight transfer. - Key points: - Vocabulary size is 50257; embedding dimension is 768; positional embeddings have 1024 max positions; there are 12 transformer blocks (H). - The process of converting TensorFlow weights to PyTorch-friendly weights is handled by HF, simplifying subsequent integration. - Notable lines (verbatim): > "the W weight for token embedding is of size 50257 by 768" (00:28:08) > "in particular we can load it using hugging face Transformers" (00:28:08)
## 00:31:00 Implementing the forward pass to get logits - Detailed notes: The forward pass takes an input tensor of token IDs (B x T) and outputs logits for the next-token predictions (B x T x C). The code uses the token embeddings + positional embeddings as the inputs to the Transformer blocks, followed by a final LayerNorm and the LM head (a linear projection to the vocabulary size). The sequence length T must be ≤ block_size (1024 for GPT-2 in the original setting; for the 124M target he uses 1024 positions). - Important terms: - Logits: unnormalized log probabilities for each vocabulary token at each position in the sequence. - LM head: final linear layer projecting hidden states to vocabulary logits. - Notable lines (verbatim): > "the input to the forward is the indices of tokens... shape B x T" (00:31:00) > "the logits are for next token in the sequence" (00:31:00)
## 00:33:31 Sampling Init, Prefix Tokens, Tokenization - Detailed notes: He demonstrates sampling from the pre-trained GPT-2 pipeline via Hugging Face, showing a prefix such as "Hello I'm a language model..." and generating a few sequences. This validates the model can generate coherent text from a prompt. - Key points: - Prefix tokens, tokenization, and sampling settings (temperature, top-k/top-p) affect the variety and coherence of generations. - The 124M model produces multiple coherent continuations from a given prefix. - Notable lines (verbatim): > "we can look at the GPT-2 124M model... and sample from it" (00:33:31) > "five sequences and we get five completions" (00:33:31)
## 00:37:02 Sampling Loop - Detailed notes: A sampling loop is shown, where the model iteratively appends one token at a time to the sequence, feeding the updated sequence back into the model to predict the next token. The process auto-detects the device (CPU/GPU) and runs on the available hardware. - Notable lines (verbatim): > "sampling loop" (00:37:02) > "auto-detect the device" (00:37:02)
## 00:41:47 Sample, Auto-detect the Device - Detailed notes: The code includes device autodetection logic to run on the best available hardware (GPU if available; otherwise CPU). This is essential for reproducibility across environments. - Notable lines (verbatim): > "auto-detect the device" (00:41:47)
## 00:45:50 Let’s Train: Data Batches (B, T) → Logits (B, T, C) - Detailed notes: The training setup transitions to the core data path: batching (B, T), embedding, Transformer blocks, and producing logits that map to vocabulary size C. - Notable lines (verbatim): > "data batches (B,T) → logits (B,T,C)" (00:45:50)
## 00:52:53 Cross Entropy Loss - Detailed notes: Cross-entropy loss is used for the next-token prediction objective. Loss is computed by reshaping logits to (BT, C) and targets to (BT) for PyTorch's cross-entropy routine. - Notable lines (verbatim): > "cross entropy loss" (00:52:53)
## 00:56:42 Optimization Loop: Overfit a Single Batch - Detailed notes: The trainer verifies the optimization loop by attempting to overfit a single batch, a standard debugging technique to ensure gradients flow and the loss decreases with backpropagation. This gate checks the end-to-end path from input to loss to gradient updates. - Notable lines (verbatim): > "optimization loop: overfit a single batch" (00:56:42)
## 01:02:00 Data Loader Lite - Detailed notes: A lightweight data loader is introduced to convert a 1-D token sequence into 2-D mini-batches (B x T) suitable for the Transformer. The loader reshapes, slices, and shifts sequences to align with the training target (the next token). - Notable lines (verbatim): > "data loader lite" (01:02:00)
## 01:06:14 Parameter Sharing: WTE and LM Head - Detailed notes: The talk introduces weight tying between input token embeddings (WTE) and the language modeling head (LM head). This is a common GPT/GPT-2 trick and reduces parameter count while improving consistency between input and output representations. - Notable lines (verbatim): > "parameter sharing wte and lm_head" (01:06:14)
## 01:13:47 Model Initialization: Std 0.02, Residual Init - Detailed notes: The initialization strategy uses a standard deviation around 0.02 for weights and 0 for biases; LayerNorm gamma/beta are initialized to 1 and 0, respectively. The residual connections are scaled to stabilize deeper networks. - Notable lines (verbatim): > "model initialization: std 0.02, residual init" (01:13:47)
## 01:22:18 SECTION 2: Let’s Make It Fast. GPUs, Mixed Precision, 1000ms - Detailed notes: This section introduces speedups: hardware (GPUs), mixed precision, and kernel-level optimizations to dramatically improve wall-clock performance. - Subtopics and key ideas: - Tensor Cores, TF32, and 333ms timings. - Float16, gradient scalers, bf16 for speed and numeric stability. - torch.compile: Python overhead reduction and kernel fusion. - Notable lines (verbatim): > "Tensor Cores, timing the code, TF32 precision, 333ms" (01:22:18) > "float16, gradient scalers, bf16, 300ms" (01:39:38) > "torch.compile, Python overhead, kernel fusion, 130ms" (01:48:15)
## 01:28:14 Tensor Cores, timing the code, TF32 precision, 333ms - Detailed notes: TF32 is a precision mode on Ampere GPUs that uses the same exponent range as FP32 but trims mantissas, enabling faster matrix multiplies with minimal accuracy loss. The pipeline benefits from faster kernels and better memory throughput. - Notable lines (verbatim): > "TF32 precision, 333ms" (01:28:14)
## 01:39:38 Float16, Gradient Scalers, BF16, 300ms - Detailed notes: bf16 (bfloat16) provides a larger dynamic range with reduced precision, often enabling stable mixed-precision training without gradient scaling. PyTorch AutoCast is introduced to manage mixed precision across modules; some layers stay in FP32 (e.g., layer norms). The result is meaningful speedups with acceptable numerical fidelity. - Notable lines (verbatim): > "float16, gradient scalers, bfloat16, 300ms" (01:39:38)
## 01:48:15 Torch.compile, Python Overhead, Kernel Fusion, 130ms - Detailed notes: Torch.compile compiles the entire forward path to reduce Python-level overhead and enable kernel fusion, producing substantial speedups for large models. The idea is that a full, static graph of the model allows the compiler to fuse operations and minimize data transfers. - Notable lines (verbatim): > "Torch.compile, Python overhead, kernel fusion, 130ms" (01:48:15)
## 02:00:18 Flash Attention, 96ms - Detailed notes: Flash Attention is a fast attention kernel that aggressively reduces memory reads/writes by not materializing the full attention matrix and by using an online softmax approach. This yields dramatic speedups on attention-heavy layers. - Notable lines (verbatim): > "Flash attention, 96ms" (02:00:18)
## 02:06:54 Nice/Ugly Numbers: vocab 50257 → 50304, 93ms - Detailed notes: They discuss padding the vocabulary size to a power-of-two-like number (50304) to improve hardware tiling and kernel efficiency. The idea is that a few extra tokens provide a cleaner dimension that helps memory alignment and kernel execution. - Notable lines (verbatim): > "vocab size 50257 → 50304, 93ms" (02:06:54)
## 02:14:55 SECTION 3: Hyperparameters, AdamW, Gradient Clipping - Detailed notes: Moving toward the training regime, Karpathy maps to the OpenAI practices: AdamW optimizer, gradient clipping, warmup, cosine decay, and data handling conventions. He emphasizes the responsibilities of initialization, weight decay blocks, and the interplay of hyperparameters in training stability and speed. - Key ideas: - AdamW and gradient clipping to stabilize optimization. - Warmup + cosine decay learning rate schedule. - Weight decay schedules and the use of FusedAdamW for speed. - Notable lines (verbatim): > "AdamW, gradient clipping" (02:14:55)
## 02:21:06 Learning Rate Scheduler: Warmup + Cosine Decay - Detailed notes: A cosine decay LR schedule with a warmup phase is implemented to gradually raise the learning rate from near-zero to a peak and then decay it following a cosine curve, for a smooth optimization trajectory. - Notable lines (verbatim): > "learning rate scheduler: warmup + cosine decay" (02:21:06)
## 02:26:21 Batch Size Schedule, Weight Decay, FusedAdamW, 90ms - Detailed notes: In addition to the learning rate, batch size and weight decay interplay is discussed. The FusedAdamW optimizer is used where available to speed updates. They separate parameters into those that should and should not decay (e.g., biases, LayerNorm parameters). - Notable lines (verbatim): > "batch size schedule, weight decay, FusedAdamW, 90ms" (02:26:21)
## 02:34:09 Gradient Accumulation - Detailed notes: To simulate larger batch sizes that do not fit into memory, gradient accumulation is introduced: accumulate gradients over multiple micro-batches before performing an optimizer step. The implementation requires careful scaling to preserve the effective loss normalization. - Notable lines (verbatim): > "gradient accumulation" (02:34:09)
## 02:46:52 Distributed Data Parallel (DDP) - Detailed notes: The talk covers training with multiple GPUs using PyTorch's DDP. The approach splits work across processes, with gradient averaging (all-reduce) across ranks. The master process coordinates logging and checkpointing. - Notable lines (verbatim): > "distributed data parallel (DDP)" (02:46:52)
## 03:10:21 Datasets Used in GPT-2, GPT-3, FineWeb (EDU) - Detailed notes: He contrasts the data sources used by GPT-2 (Web Text) and GPT-3 (larger, more curated corpora). He highlights FineWeb EDU as a newer, education-focused corpus that helps steer the dataset toward high-quality text. - Notable lines (verbatim): > "datasets used in GPT-2, GPT-3, FineWeb (EDU)" (03:10:21)
## 03:23:10 Validation Data Split, Validation Loss, Sampling Revival - Detailed notes: The validation split is introduced to monitor overfitting. He shows sampling reviving as an optional step to generate samples to inspect model quality during training. - Notable lines (verbatim): > "validation data split, validation loss, sampling revive" (03:23:10)
## 03:28:23 Evaluation: HellaSwag, Starting the Run - Detailed notes: The HellaSwag evaluation is introduced as a sanity-checking benchmark that roughly measures world knowledge and common sense in language models. It uses multiple-choice contexts and assesses model-generated continuations. - Notable lines (verbatim): > "evaluation: HellaSwag, starting the run" (03:28:23)
## 03:43:05 SECTION 4: Results in the Morning! GPT-2, GPT-3 Repro - Detailed notes: In the morning, the GPT-2 repro run is evaluated. The OpenAI GPT-2 124M baseline and GPT-3 numbers are used as references; the goal is to reproduce and potentially surpass the baseline in a constrained compute environment. - Notable lines (verbatim): > "results in the morning! GPT-2, GPT-3 repro" (03:43:05)
## 03:56:21 Shoutout to llm.c, Equivalent but Faster Code in Raw C/CUDA - Detailed notes: He highlights llm.c (a raw C/CUDA implementation) as a faster alternative to PyTorch-based GPT-2, serving as an implementation-level reference with similar results but more performance. - Notable lines (verbatim): > "shoutout to llm.c, equivalent but faster code in raw C/CUDA" (03:56:21)
## 03:59:39 Summary, Phew, Build-nanogpt GitHub Repo - Detailed notes: A recap of outcomes, including a repository (build-nanogpt) with commits detailing changes. The repository is designed to reproduce GPT-2 124M, with reported parity and performance improvements. - Notable lines (verbatim): > "summary, phew, build-nanogpt github repo" (03:59:39)
## Resources Mentioned
- Attention Is All You Need (Vaswani et al.)
- OpenAI GPT-2 paper
- OpenAI GPT-3 paper
- Hugging Face Transformers
- Lambda GPU Cloud (cloud GPUs)
- nanoGPT repository (Karpathy)
- llm.c (C/CUDA GPT implementation)
- OpenAI GPT-2 source code (TensorFlow): original GPT-2 code
- OpenAI GPT-3 paper (supplementary details for hyperparameters)
- FineWeb EDU dataset (educational content extraction)
- HellaSwag evaluation suite
- TOO MANY: The video mentions building a nanoGPT repo, a build-nanogpt repo, and llm.c, plus a Discord and their GitHub pages.
## Notable Diagrams, Visuals, and How to Recreate Them
- Positional embeddings: visualized as a matrix with one row per position, showing structure (sinusoidal-like patterns emerge as training progresses).
- Transformer block layout: showing token embeddings, positional embeddings, block stack (H = 12), final layer norm (LNF), and LM head.
- Attention mechanism: description of q, k, v, and the attention score computation, including masking for autoregressive behavior.
- Memory hierarchy diagram (in-depth explanation of GPU memory vs. on-chip memory, L2/L1 caches, and HBM bandwidth) and how tensor cores speed up matmul by batching into small 4x4 blocks.
- Hardware speedups: TF32, BF16, FP16, and how mixed precision with AutoCast affects performance and numeric stability.
- Data loading: how to reshape 1-D token streams into B x T batches, and how targets are offset by one token to create the next-token prediction labels.
- Training throughput: tokens per second as a performance metric across different optimization techniques.
## Books, Papers, Tools, Websites, Companies, Frameworks (Resources Mentioned)
- Attention Is All You Need (Vaswani et al.)
- OpenAI GPT-2 paper (Language Models Are Unsupervised Multitask Learners)
- OpenAI GPT-3 paper (Language Models are Few-Shot Learners)
- Hugging Face Transformers (library and GPT-2 model)
- Lambda Labs (cloud GPU provider)
- llm.c (C/CUDA implementation of LLMs)
- GPT-2 source code (OpenAI) and GPT-2 weights released by OpenAI
- build-nanogpt GitHub repo (Karpathy)
- nanoGPT repo
- FineWeb EDU dataset (educational data subset for training)
- HellaSwag (evaluation dataset)
- OpenWebText / Common Crawl (data sources discussed in GPT-2 / GPT-3 literature)
- PyTorch (framework used for GPT-2 reproduction)
- Torch.compile (PyTorch compilation tool)
- Flash Attention (Stanford, memory-efficient attention kernel)
- bf16/tf32 (mixed-precision approaches on Ampere GPUs)
- AdamW, FusedAdamW (optimizers)
- DataLoader, DDP (Distributed Data Parallel) concepts
## 4–5 Important Concepts, Jargon, and Definitions (Glossary terms first use)
- GPT-2 124M: A 124-million-parameter GPT-2 model (12 Transformer layers; 768 hidden size; 50257-token vocabulary).
- Transformer: A neural network architecture built on self-attention and feed-forward blocks; GPT-2 uses a decoder-only variant.
- Decoder-only Transformer: A Transformer stack used for autoregressive text generation; lacks encoder-decoder cross-attention, uses masked self-attention.
- WTE (Word Token Embeddings): The embedding matrix that maps tokens to vector representations (vocab_size x embedding_dim).
- LM head: The final linear projection from hidden states to vocabulary logits; often tied to WTE in GPT-2 via weight sharing.
- Weight tying: Sharing weights between input embeddings and the output projection (WTE and LM head share the same matrix).
- Positional embeddings: Embeddings that encode the position of tokens in a sequence; in GPT-2 they are trainable parameters (not fixed sinusoids).
- Masked self-attention: In autoregressive generation, tokens are prevented from attending to future tokens.
- BF16 vs FP32 vs TF32 vs FP16: Floating-point formats with different precision and range; BF16 (bfloat16) keeps range similar to FP32 but with fewer mantissa bits; TF32 (TensorFloat-32) uses a 19-bit mantissa in hardware to accelerate matmuls on Ampere GPUs.
- Gradient clipping: A technique to constrain the norm of gradients to stabilize training.
- AdamW: A variant of Adam with decoupled weight decay.
- Gradient accumulation: Technique to simulate larger batch sizes when memory is limited by accumulating gradients over micro-batches before an optimizer step.
- DDP (Distributed Data Parallel): PyTorch mechanism to parallelize training across multiple GPUs with gradient synchronization.
- Flash Attention: An optimized attention kernel that reduces memory reads/writes by avoiding the explicit materialization of the full attention matrix.
- Mixed precision AutoCast: PyTorch context manager to automatically cast certain operations to lower precision to speed up training while maintaining stability.
- FineWeb EDU: A high-quality educational data subset used for training large language models, emphasizing careful curation of content.
- HellaSwag: A benchmark for common-sense inference (multiple-choice completion) in language models.
- Overfitting a single batch: A debugging check to ensure gradients and updates flow correctly on a tiny dataset before scaling up.
- Over-smoothing vs. structure in positional embeddings: The observation that trained positional embeddings develop sinusoidal-like structure even though they are learned.
- Logits: The raw outputs of the model before applying the softmax to produce probabilities over vocabulary tokens.
- State dict: A Python dictionary containing parameter tensors and persistent buffers (weights) of a PyTorch model.
- Tokenization: The process of converting text into a sequence of token IDs in the model's vocabulary.
- Namespace: WTE vs LM head naming consistent with HF Transformers for easier weight transfer.
## 2–3 Notable Quotes (verbatim blocks) > "we're going to reproduce the gpt2 model the 124 million version of it" (00:00) > "the biggest model is called the gpt2" (00:00) > "we can look at the gpt2 124M model... and sample from it" (00:03:39) > "we want to write the gpt2 model from scratch" (00:18:00) > "the 12 layers in the Transformer and 768 channels" (00:03:39) > "logits for next token in the sequence" (00:31:00)
## 3–6 Notable Tools & External Resources Mentioned
- Hugging Face Transformers (Python library for loading GPT-2 and other LMs)
- PyTorch (Deep learning framework used for the implementation)
- OpenAI GPT-2 paper and GPT-3 paper (for hyperparameters and architecture context)
- Attention Is All You Need (Transformer foundational paper)
- llm.c (C/CUDA implementation of a GPT-like model for speed comparisons)
- Lambda GPU Cloud (on-demand GPUs used in the video)
- OpenAI GPT-2 weights released by OpenAI
- FineWeb EDU (educational data subset for training)
- HellaSwag (evaluation benchmark)
- Flash Attention (fast attention kernel)
- Torch.compile (PyTorch optimization tool)
- AdamW (optimizer with decoupled weight decay)
- FusedAdamW (CUDA-optimized version of AdamW)
- Data parallel vs. distributed data parallel (DDP) in PyTorch
## 4 Internal Diagrams You Could Re-create
- Architecture sketch: Input WTE + Position Embeddings → Transformer blocks (12 layers) → Final LayerNorm → LM head, with WTE tied to LM head.
- Data path: Text input -> tokenization -> (B x T) indices -> embedding + positional encoding -> Transformer blocks -> LayerNorm -> logits -> softmax to token probabilities.
- Memory hierarchy: CPU RAM <-> GPU memory (HBM) <-> on-chip cache (L1/L2) and tensor cores; the role of memory bandwidth vs. compute in training speedups.
- Attention: Q (query), K (key), V (value) flow; attention weights via softmax; masked autoregressive attention.
- Training speedups graph: TF32, BF16, FP16, AutoCast, Torch.compile, Flash Attention—each contributing to wall-clock speedups.
## 5 Resources for Quick Reference
- GPT-2 and GPT-3 papers, Attention Is All You Need
- Hugging Face Transformers docs and GPT-2 implementation
- OpenAI GPT-2 weights release
- e.g., FineWeb EDU dataset introduction and usage notes
- llm.c (C/CUDA reference implementation)
- Flash Attention papers (Stanford; Flash Attention v1 & v2)
- PyTorch docs on AutoCast, DDP, and fused optimizers
- Lambda Labs for hardware access
## 6 Key Takeaways & High-Impact Lessons
- Reproducing GPT-2 124M demonstrates that with careful implementation, alignment with GPT-2’s architecture, and disciplined data handling, you can reach strong model quality on modest hardware within hours to days.
- A handful of optimization levers dramatically change wall-clock performance: mixed precision (BF16/TF32/FP16), tensor cores, kernel fusion via Torch.compile, and Flash Attention for memory-bound attention.
- Weight tying (WTE with LM head) reduces parameters and improves consistency between input and output mappings, and is a standard GPT-2 design choice.
- Proper initialization, including scaling residual connections, can stabilize training as depth grows; the open literature suggests scaling residual contributions by sqrt(n) to prevent gradient explosion and activation variance growth.
- Gradient accumulation and distributed data parallel are essential when you want large effective batch sizes beyond single-GPU memory, and you must adjust loss averaging to account for accumulation.
- Data choices (e.g., FineWeb EDU) significantly influence model efficiency and the value of match vs. baseline GPT-2 trained on WebText-like corpora. The right dataset matters just as much as architecture.
- Evaluation is nontrivial: HellaSwag and other benchmarks are useful but have caveats about data leakage and comparison baselines; you should interpret improvements in light of data distributions.
- The end-to-end workflow shown (from checkpoint loading to re-implementing, to training, to evaluating, to generating) is a strong blueprint for building your own nano-LLMs and iterating quickly.
## 7 Actionable Takeaways (What to do next)
- Build from scratch: Re-implement the GPT-2 124M architecture (12 layers, 768 hidden, 50257 vocab) with token embeddings, positional embeddings, a 12-layer transformer stack, pre-Norm inside residual streams, and a final LM head with weight tying.
- Load weights for verification: Validate that the Hugging Face HF state_dict matches the intended architecture; confirm shapes and parameter names align to map pre-trained weights into your custom module.
- Implement training pipeline: Create a simple, clean data loader that builds B x T batches, constructs targets (next-token labels offset by one), and overfits a single batch to verify the pipeline.
- Optimize performance: Experiment with TF32/bf16/FP16, AutoCast, Torch.compile, and Flash Attention to maximize throughput on your hardware. If some optimizations break other parts (like eval), separate their usage or disable for debugging runs.
- Enable weight tying: Tie input embedding matrix with output LM head to save parameters and improve alignment of token-level representations.
- Use DDP for multi-GPU: If you have multiple GPUs, use PyTorch’s Distributed Data Parallel with careful gradient synchronization (accumulate gradients, then all-reduce) and proper master process logging.
- Explore dataset strategy: If you aim for GPT-2-like performance, select a dataset with diverse, high-quality content; consider FineWeb EDU or a gated mix of Common Crawl-derived data and curated sources, ensuring non-overlap with evaluation sets when possible.
- Benchmark evaluation: Use HellaSwag and other standard metrics, but keep in mind that model sizes, data distributions, and evaluation setups affect comparability. Track train/val losses, as well as sample generations to assess quality.
- Iterate with hardware-aware tuning: Try larger vocabulary padding (to powers of two like 50304), adjust batch sizes per GPU, and explore gradient accumulation steps to simulate larger effective batch sizes without blowing memory.
- Compare with fast C/CUDA implementations: If you need speed, consider comparing PyTorch-based approaches againstllm.c or other optimized kernels to see where PyTorch gains or loses efficiency.
## 8 Executive Summary
- Karpathy’s deep dive demonstrates an end-to-end approach to reproducing GPT-2 124M from scratch, combining architecture re-implementation, weight transfer, and a suite of performance optimizations. The journey covers architecture details (decoder-only Transformer, weight tying, and positional embeddings), data handling (tokenization, batching, and targets), optimization strategies (AdamW, gradient clipping, warmup + cosine LR, gradient accumulation, DDP), and speedups (BF16/TF32, Torch.compile, Flash Attention). He also cross-references GPT-2 and GPT-3 papers to align hyperparameters, and showcases how to accelerate training and evaluation while producing coherent sample generations.
- The work is a practical blueprint for anyone who wants to replicate large language models from first principles, while also highlighting the reality of engineering tradeoffs (data quality, memory limits, and the importance of hardware-aware optimizations). The overall takeaway is that with careful implementation and a mixture of modern optimization strategies, you can reproduce a GPT-2 124M-scale model and iteratively push its performance toward published baselines, all while learning a great deal about the inner workings of modern LMs.
## 9 Topics
- GPT-2 Reproduction
- PyTorch Implementation
- Weight Tying & Token Embeddings
- Data Loading & Tokenization
- Training Speedups & Mixed Precision
- Gradient Accumulation & DDP
- Attention Algorithms (Flash Attention)
- Data Sets & Evaluation (HellaSwag, FineWeb EDU)
- Hyperparameters (AdamW, LR warmup/cosine, batch size)
- Benchmarks, Repos & Related Projects (nanoGPT, llm.c, build-nanogpt)
## 10 Key Takeaways (Condensed)
- GPT-2 124M can be reproduced and trained to competitive quality with careful implementation and hardware-aware optimizations.
- Weight tying (WTE ↔ LM Head) reduces parameters and enhances model consistency.
- Mixed-precision training (bf16/TF32) and kernel fusion dramatically reduce training time with minimal accuracy loss.
- Flash Attention can drastically improve speed for attention-heavy transformers by reducing memory traffic.
- Gradient accumulation and DDP are essential to scale batch sizes beyond a single GPU’s memory.
- The dataset choice (like FineWeb EDU) matters as much as architecture for final model quality.
- Regular evaluation (val loss, HellaSwag) helps monitor learning progress and avoid purely memorizing training data.
- The project demonstrates an end-to-end workflow, from architecture to training to evaluation to sample generation, including a GitHub repo with iterative commits documenting every change.
## 11 Final Notes
- The video emphasizes not just architecture, but also practical considerations such as initialization (0.02 std, residual scaling), memory layouts, and the importance of consistent naming (WTE vs LM Head) to streamline weight transfer.
- The speaker calls out the dynamic nature of hyperparameters; there is no single best set, and domain knowledge from GPT-2 and GPT-3 papers helps guide sensible defaults and safe exploration.
- The content includes references to practical tooling (HF Transformers, PyTorch, Torch.compile) and real-world HPC constraints (8x A100 GPUs, memory budgets, and data-parallel synchronization).
Action Items
- Implement a GPT-2 124M-like PyTorch module with WTE, positional embeddings, 12 decoder blocks, final LayerNorm, and an LM head with weight tying.
- Load OpenAI GPT-2 124M weights via Hugging Face to verify architecture alignment and parameter shapes.
- Create a simple data loader that forms B x T batches and offsets targets by one token; verify overfitting on a single batch.
- Enable mixed precision (bf16/TF32) and test performance across CPU, CUDA, and MPS backends; validate numerical stability.
- Integrate Flash Attention for attention kernels; compare with HF’s attention path and Torch.compile for speedups.
- Set up AdamW with decoupled weight decay, gradient clipping, warmup + cosine LR scheduler, and experiment with gradient accumulation to simulate large batches.
- Configure DDP with eight GPUs (in a single node or multi-node) and implement gradient synchronization after the final micro-step; ensure loss averaging is synchronized across ranks.
- Adopt a higher-quality data mix (FineWeb EDU subset) for training, and implement data shuffling/per-epoch permutation to avoid order biases.
- Add HellaSwag evaluation integration to monitor world knowledge and common sense progression; print and log periodic scores and compare against GPT-2 baselines.
- Document all commits in build-nanogpt with explicit notes on hyperparameters, initialization, and architectural changes to enable reproducibility.
Mental Models
Glossary
- GPT-2 124M
- A 124-million-parameter GPT-2 model: 12 decoder-only Transformer layers, 768 hidden units, 50257-token vocabulary.
- WTE
- Word/token Embeddings matrix; maps token IDs to embedding vectors (vocab_size x embed_dim).
- LM head
- The final linear layer projecting hidden states to vocabulary logits; often weight-tied to WTE.
- Weight tying
- Sharing the same weight matrix between input embeddings and the LM output projection to reduce parameters and improve coherence.
- Positional embeddings
- Learned vectors added to token embeddings to encode the position of tokens in a sequence.
- Decoder-only Transformer
- Transformer architecture without an encoder, used for autoregressive text generation; uses masked self-attention.
- TF32
- TensorFloat-32 on Nvidia Ampere GPUs: same exponent range as FP32 but reduced mantissa, enabling faster matmul operations.
- BF16
- bfloat16: 16-bit floating point with the same exponent range as FP32 but reduced mantissa; supports stable mixed-precision training without gradient scaling on Ampere devices.
- AutoCast
- PyTorch mechanism to automatically use mixed precision for certain ops; lowers precision where safe to speed up computation.
- Flash Attention
- An optimized attention kernel that reduces memory reads/writes by avoiding explicit attention matrix materialization; uses online softmax to accelerate attention.
- AdamW
- Adam optimizer with decoupled weight decay (no coupling of L2 regularization to the gradient update).
- FusedAdamW
- CUDA-optimized, fused variant of AdamW that updates many parameters in a single kernel for speed.
- DDP
- Distributed Data Parallel: PyTorch construct to parallelize training across GPUs by synchronizing gradients via all-reduce.
- HellaSwag
- A benchmark for evaluating common-sense reasoning in language models via sentence completions; historically used to gauge world knowledge and reasoning.
- FineWeb EDU
- A curated subset of educational content from the web intended to improve model training with high-quality material.
- Logits
- The raw, unnormalized scores output by a model for each token in the vocabulary; softmax converts logits to probabilities.
- State dict
- A Python dictionary in PyTorch containing model parameters and buffers.
- Tokenizer
- Tool that converts text into a sequence of token IDs from the model's vocabulary.
- Tokenization tokens
- Subword units used by GPT-2's vocabulary; a single 'word' is broken into multiple tokens.
- Block size
- Maximum sequence length processed by the model, often 1024 for GPT-2 124M in this context.
Notable Quotes
“"we are going to reproduce the gpt2 model the 124 million version of it",”
“"the 124 million parameter had 12 layers in the Transformer and it had 768 channels in the Transformer"”
“"we're going to be implementing the GPT model here in parallel and as our first task let's load the gpt2 124 M into the class that we're going to develop here from scratch"”
“"the problem with that is the initial code is intenser flow we'd like to use pytorch",”
“"sample from the pipeline and sample from huggingface, and these are the five sequences…"”
“"we can load the weights and the biases and everything else into our nn module",”
“"We are going to be using BF16 this is only possible to do on the ampere",”
“"Flash Attention is a kernel fusion technique that reduces memory traffic…"”
“"We are rebuilding GPT-2 from scratch and then speeding it up with a series of optimization techniques",”
Topics
More from Neural Networks: Zero to Hero
See all




