Language Modeling from Scratch, Part 1: Course Primer & Overview
Stanford's CS336 doesn't teach you to call an LLM API. It walks you through building one โ tokenizer, architecture, training loop, systems, scaling, data, and alignment โ the same way an operating-systems course builds an OS from scratch. This opens a lecture-by-lecture series covering all nineteen sessions in depth, starting with what the course actually is, who teaches it, and how it's structured. Tokenization โ technically bundled into the same first lecture โ gets its own full treatment next, in Part 2.
What This Course Actually Is
The course's own description, quoted directly from its site, states its purpose plainly:
That operating-systems comparison is doing real work, not just flavor text. An OS-from-scratch course doesn't stop at "here's how a kernel works conceptually" โ it has you write a scheduler, a memory allocator, a filesystem, things that either function or don't. CS336 applies the same standard to language models: rather than treating the transformer, the tokenizer, or the training loop as black boxes you import, you build each one, and it either trains a working model or it doesn't. The course's own site does not use a phrase like "efficiency frontier" or name any single unifying philosophy beyond this โ worth stating plainly rather than inventing a tidier narrative than what's actually there.
One structural note that matters immediately: the course is officially listed as a 5-unit class, and the site adds a direct warning about workload โ "this is a very implementation-heavy class, so please allocate enough time for it." That's not throat-clearing. The prerequisites section backs it up with specifics.
Prerequisites
If you're following this series without the Stanford enrollment behind it, none of this is disqualifying โ but it does mean the earlier parts of this series (this one included) will occasionally point you toward a prerequisite concept rather than re-deriving it from first principles, the same way the course itself would.
The Five Assignments
The course's coursework is organized around five large public assignments, each with its own GitHub repository, and each corresponding to a cluster of lectures later in this series. Their official one-line descriptions, quoted directly:
| Assignment | What it covers (official description) | Repo |
|---|---|---|
| 1 โ Basics | "Implement all of the components (tokenizer, model architecture, optimizer) necessary to train a standard Transformer language model." Train a minimal LM. | assignment1-basics |
| 2 โ Systems | Profile and benchmark the Assignment 1 model; write your own Triton implementation of FlashAttention2; build memory-efficient, distributed training. | assignment2-systems |
| 3 โ Scaling | Understand each Transformer component's function; query a hosted training API to fit and study scaling laws. | assignment3-scaling |
| 4 โ Data | Convert raw Common Crawl dumps into usable pretraining data; filtering and deduplication. | assignment4-data |
| 5 โ Alignment & Reasoning RL | SFT and RL to train LMs to reason on math problems; optional Part 2: safety alignment methods like DPO. | assignment5-alignment |
Two competitive leaderboard repos also exist publicly โ assignment1-basics-leaderboard and assignment2-systems-leaderboard โ if you want to benchmark your own implementation against other public submissions once you get there.
Instructors and Offerings
CS336 is taught by Percy Liang and Tatsunori Hashimoto, both Stanford faculty (Liang leads the Stanford NLP Group and Stanford CRFM; both are listed as instructors on every public offering of the course). The course has run at least three times โ Spring 2024, Spring 2025 (now archived), and Spring 2026 (the current offering this series follows by default) โ and the syllabus genuinely differs between years, not just in dates. Spring 2025, for instance, taught Kernels/Triton as its own dedicated lecture by Hashimoto; Spring 2026 moved that same topic to a different lecture slot taught by Liang, and added TPU coverage alongside GPUs. This series will follow the Spring 2026 structure as its primary source, and flag it explicitly whenever a prior year handled a topic differently in a way that's worth knowing.
The Nineteen Lectures
The official Spring 2026 schedule, in order:
| # | Topic | Instructor |
|---|---|---|
| 1 | Overview, tokenization | Liang |
| 2 | PyTorch (einops), resource accounting (FLOPs, memory, arithmetic intensity) | Liang |
| 3 | Architectures, hyperparameters | Hashimoto |
| 4 | Attention alternatives and mixture of experts | Hashimoto |
| 5 | GPUs, TPUs | Hashimoto |
| 6 | Kernels, Triton | Liang |
| 7 | Parallelism | Liang |
| 8 | Parallelism (continued) | Hashimoto |
| 9 | Scaling laws | Hashimoto |
| 10 | Inference | Liang |
| 11 | Scaling laws (continued) | Hashimoto |
| 12 | Evaluation | Liang |
| 13 | Data โ sources, datasets | Liang |
| 14 | Data โ filtering, deduplication, mixing, synthetic data | Liang |
| 15 | Mid/post-training โ SFT/RLHF | Hashimoto |
| 16 | Post-training โ RLVR | Hashimoto |
| 17 | Alignment โ multimodality | Liang |
| 18 | Guest lecture โ Daniel Selsam | โ |
| 19 | Guest lecture โ Dan Fu | โ |
Official lecture recordings are published on YouTube, linked directly from the course's own schedule page. Video recordings and lecture materials (executable code traces and PDF slide decks, committed to the course's public lectures repository) are the two primary sources this series draws on lecture by lecture, alongside the actual assignment repos.
Thinking Like the Course, Day One
Before Part 2 gets into tokenization properly, it's worth sitting with one idea the course leads with even in its overview: nothing here is free, and the course wants you counting the cost from the start. A simple way to get into that mindset immediately โ before writing a single line of the actual assignment code โ is to ask a question the course's own Lecture 2 makes central: given a model's shape, how many parameters does it have, and roughly how much compute does one training step cost?
Here's a small, original Python script that answers exactly that for a toy decoder-only Transformer โ the same kind of back-of-envelope resource accounting the course treats as a foundational skill, not an afterthought:
# A toy resource-accounting script, in the spirit of CS336's own framing: # "how big is this model, and how much does one training step cost?" # This is original example code for this series, not copied from any # CS336 assignment repo. def transformer_param_count(vocab_size, d_model, n_layers, d_ff, n_heads): # Embedding + output projection (often tied, counted once here) embedding = vocab_size * d_model # Per-layer: attention (Q, K, V, O projections) + feed-forward (2 matrices) attn_per_layer = 4 * d_model * d_model ffn_per_layer = 2 * d_model * d_ff per_layer = attn_per_layer + ffn_per_layer total = embedding + n_layers * per_layer return total def training_step_flops(n_params, batch_size, seq_len): # Rule of thumb used throughout the scaling-laws literature: # ~6 FLOPs per parameter per token for a full forward+backward pass tokens_per_step = batch_size * seq_len return 6 * n_params * tokens_per_step # A GPT-2-small-ish configuration config = { "vocab_size": 50257, "d_model": 768, "n_layers": 12, "d_ff": 3072, "n_heads": 12, } n_params = transformer_param_count(**config) flops = training_step_flops(n_params, batch_size=32, seq_len=1024) print(f"Parameters: {n_params:,} (~{n_params/1e6:.1f}M)") print(f"FLOPs per training step: {flops:.2e}")
What's Coming in This Series
Part 2 picks up the other half of Lecture 1 โ tokenization: byte-pair encoding, why it exists, and a from-scratch implementation walkthrough grounded in what assignment1-basics actually asks you to build. From there, this series follows the Spring 2026 lecture order one part per lecture: architectures and attention alternatives, the systems stack (GPUs/TPUs, kernels, parallelism), scaling laws and inference, data and evaluation, and post-training/alignment โ nineteen parts in total, each with its own real citations, code walkthroughs, and hands-on directions tied to the actual public assignment repos.