I kept running into the same problem while learning about large language models.

I'd read a blog post about attention, nod along, and two days later I couldn't tell you why we divide by √d_k. I'd see "GQA", "MLA", "MoE", "LoRA", "HNSW" or "context rot" in a paper or a tweet, open five tabs, and close them all with the uneasy feeling that I sort of got it. And the field keeps moving, so there's always a new term on top of the ones I hadn't really nailed down.

So I built the resource I wished I had: LLM Explained. It's a free, interactive course that goes from "why did RNNs hit a wall?" all the way to "how does a production agent retrieve, reason, act and get evaluated?"

I built it to learn, and writing each page forced me to understand things properly. I'm sharing it because I think it can help other people too.

🔗 Live site: https://llm-explained-lovat.vercel.app/
💻 Source code: https://github.com/amananandrai/llm-explained

💌 This is a work in progress and I'd love your help. Suggestions are always welcome. If you find it useful, please ⭐ star the repo on GitHub. Spotted a mistake or have an idea? Open an issue. Want to fix or add something yourself? Pull requests are very welcome!

The LLM Explained home page: an attention matrix for "The cat sat on the mat"

What is LLM Explained?

It's 42 modules in seven parts plus a capstone (43 interactive pages if you count the KL divergence sub-page). Every concept appears as a picture you can play with before you see its equation.

A few principles shaped every page:

  1. Picture first, symbol second. Each equation sits next to the animation that computes it, and they use the same colours. If the query is blue in the diagram, it's blue in the formula.
  2. One idea per scroll step. Animations move forward as you scroll and never run on without you.
  3. Real numbers at toy scale. 4-dimensional embeddings and 3–5 token sentences, so every value fits on screen and you can check it.
  4. Touch the knob. Every module has at least one widget you control.
  5. Run it yourself. Optional in-browser Python (NumPy) cells reproduce the figures.
  6. Honest limits. Every module ends with a "what this picture leaves out" box, because simplified diagrams can mislead you if you don't know what they skip.

Also, every number on screen is computed in your browser. When something is a simulation or an illustrative figure, the page says so.

How to use the site

1. Start with the curriculum map

The Curriculum link in the top navigation shows the whole course. Parts 1 and 2 are meant to be read in order, and everything after them builds on the attention module. Beyond that you can jump around:

  • Parts 3, 4 and 7 can be read in any order within each part.
  • Part 5 (RAG) follows the order of a retrieval pipeline.
  • Part 6 (Agents) starts from the agents and ReAct module.

If you already know the transformer well, skip to whatever you're curious about. If you're new, start at Module 1 (or the optional maths primer, Module 0).

Going from the home page to the curriculum map and into a module

2. Pick your depth: Intuition, Mechanics or Maths

This is my favourite feature. Every page has a depth switch with three levels:

Depth What you get Good for
Intuition Pictures and plain language, no symbols A first read, or a quick refresher
Mechanics Tensor shapes and step-by-step operations Engineers who want to implement it
Maths Full derivations, colour-linked KaTeX equations Going deep, or interview prep

Three buddies: Intuition with a crayon drawing, Mechanics in a hard hat, Maths with glasses and a chalkboard

You can read a page at Intuition level, come back a week later and flip to Mechanics. The page grows with you.

Flipping the depth switch between Intuition, Mechanics and Maths

And here's what the Maths depth looks like. Notice that Q, K and V keep the same blue, orange and green as in the animations:

Maths depth: the attention formula and the √d_k variance argument in colour-linked KaTeX

3. Scroll, step and scrub the animations

Each page has a hero animation driven by your scroll position. There are also play, pause, step back, step forward and a scrubber, so you can pause on exactly the frame that confuses you.

For example, in the attention module a 5-token attention matrix fills in cell by cell, the heads split into colours, and you see each output vector built up as a weighted sum of value vectors.

Scrolling through the 8-step attention animation in Module 5

Kawaii tokens: "mat" gives 34% of its attention to "cat"

Every animation also has a text transcript, and if your system has reduced motion turned on, animations turn into numbered static frames.

4. Play with the widgets

This is where things click. Some examples:

  • A "remove √d_k" toggle that shows softmax saturating when you drop the scaling factor. You can see why the scale is there.

Toggling √d_k on and off, then exploring attention-head patterns

With √d_k everyone gets a share; without it, key 5 eats 99.8% of the attention

  • A parameter counter that checks the 12·d² rule against GPT-2 and GPT-3.

The parameter counter widget

  • A real byte-level BPE tokeniser running in the browser. Try the Hindi example and watch the token bill go up.

The tokenizer playground switching between examples

A bread loaf labelled "unbelievable" gets sliced into "un", "believ" and "able"

  • A numerical KL divergence explorer and the closed-form RLHF optimum.

5. Run the Python yourself

Most modules include a "Run it yourself" cell: editable Python running in your browser through Pyodide with NumPy. Change a number, hit Run, and watch the result update. You don't need to install anything. (Pyodide downloads on your first run, so give it a moment.)

An editable Python cell: scaled dot-product attention by hand

6. Check yourself with the quiz

Each page ends with a "what this picture leaves out" box, a 3-question quiz and a further reading list linking the primary papers. Every module cites its sources, from Attention Is All You Need to LoRA, DPO and PagedAttention.

Answering the end-of-module quiz

What's covered

Here's the full curriculum. I tried to cover both the core fundamentals and the newer ideas that keep showing up in papers and on Twitter/X.

The curriculum map

Part 1 · Foundations: how text becomes numbers

  • M0 Maths primer (optional), plus a dedicated KL divergence page
  • M1 How models learn: training terms
  • M2 Why transformers were needed
  • M3 Tokenisation
  • M4 Embeddings

Part 2 · The Transformer and GPTs

  • M5 Attention and the transformer block
  • M6 Encoder, decoder and encoder–decoder
  • M7 GPTs: from pretraining to generation
  • M8 Post-training: SFT, RLHF, DPO and reasoning
  • M9 Prompt engineering: zero-shot, few-shot and beyond

Part 3 · Faster, bigger, smaller

  • M10 Evolution of attention: MHA vs GQA vs MLA (and LRKV)
  • M11 Taming the KV cache
  • M12 Mixture of experts
  • M13 Scaling training: parallelism, ZeRO and FSDP
  • M14 Distillation
  • M15 Quantisation: FP8, FP4 and TurboQuant

Part 4 · Real models, new ideas and adapting them

  • M16 Open-source LLM architectures compared
  • M17 New block designs: Attention Residuals and beyond
  • M18 Beyond next-token LLMs: concept models, JEPA and decision models
  • M19 Multimodality
  • M20 Fine-tuning: full, LoRA and QLoRA

Part 5 · Retrieval and RAG

  • M21 Embedding models in depth
  • M22 Vector search and HNSW
  • M23 Chunking strategies
  • M24 Re-ranking with cross-encoders
  • M25 The seven types of RAG
  • M26 Graph RAG, open knowledge graphs and vectorless RAG

Part 6 · Agents and harnesses

  • M27 Agents, tool use and the ReAct framework
  • M28 Context engineering and context rot
  • M29 Types of memory
  • M30 Harness engineering: building the harness
  • M31 Loop engineering and the Ralph Wiggum loop
  • M32 MCP: the Model Context Protocol
  • M33 Skills and plugins
  • M34 Agent orchestration and subagents
  • M35 Agent-to-agent communication
  • M36 Agentic engineering

An agent buddy running in a Think → Act → Observe hamster wheel

The ReAct agent trace in Module 27

Part 7 · Production and safety

  • M37 Benchmarking and evaluation
  • M38 LLMOps
  • M39 Safety, alignment and interpretability
  • M40 Model governance

Capstone

  • M41 Follow one request end to end. One prompt's whole journey: text → tokens → embeddings with RoPE → transformer blocks (GQA attention with a KV cache, MoE feed-forward) → logits → sampling → text. Then the same request inside an agent harness that chunks, retrieves and re-ranks context, calls a tool, writes to memory, and is traced and evaluated. A tiny real transformer block runs in your browser, and you can inspect every intermediate tensor.

Scrolling through the capstone: one request, end to end

One visual language across every page

Something I cared about a lot: colours mean the same thing everywhere. The blue you learn as "query" in Module 5 is still "query" in the capstone.

Element Colour
Query (Q) Blue
Key (K) Orange
Value (V) Green
Residual stream Neutral grey
Router and experts (MoE) Purple
Frozen weights vs trainable adapters (LoRA) Grey vs bright pink
Retrieved passages (RAG) Filled teal
Pass / fail / needs review (evals) Green / red / amber, always with an icon
Untrusted or injected content Red hatching

Once you learn the colours, later diagrams are much easier to read, because half the explanation is already done for you.

Colour never carries meaning on its own, though. There are icons, labels and transcripts too, and both light and dark themes aim for WCAG AA contrast.

The attention module in dark mode

Who is this for?

  • Software engineers and students who know some Python and school-level maths and want to really understand what's going on inside an LLM.
  • ML practitioners who want the maths and architecture details collected in one place.
  • Anyone building with LLMs (RAG apps, agents, MCP servers) who wants a mental model of the stack underneath.

Two goals I used to test the site:

After Module 7, you should be able to sketch a decoder block and estimate its parameter count to within 10%.

After Module 36, you should be able to sketch a RAG agent's harness and name where it can fail.

Under the hood (for the curious)

I deliberately kept the tech simple:

  • Plain JavaScript and static files, no build step. index.html is the shell, and each module is its own file (assets/m/m<id>.js) that loads lazily when you navigate to it.
  • A small reusable component library (core.js, kit.js): router, depth switch, ScrollyStage (sticky visual next to scrolling text), sliders, probability bars, matrix grids, line charts, quizzes, colour-linked math blocks, pipeline diagrams and agent traces.
  • KaTeX for the maths and Pyodide + NumPy for the runnable Python cells.
  • Plan-driven content. The whole course is written as a single build plan in Markdown. A Python script (scripts/build_data.py) parses it into the curriculum, tables and reading lists. If a module script fails to load, the page falls back to an outline generated from the plan.
  • Deployed on Vercel as a static site.

To run it locally:

git clone https://github.com/amananandrai/llm-explained cd llm-explained ./scripts/dev.sh # wraps index.html into dev.html python3 -m http.server 8765 # open http://localhost:8765/dev.html 

Honest limits

In the same spirit as the "what this picture leaves out" boxes, here's what the site doesn't do yet:

  • It doesn't use real production tokenisers, recorded agent traces or live LLM calls. Widgets that would need those use in-browser computation (byte-level BPE, a real HNSW, numerical KL, a tiny real transformer block) or written examples with illustrative numbers, and the page labels them.
  • The model spec cards in Module 16 are transcribed from published configs. If you spot an error, please tell me!

Why I built it, and why I'm sharing it

Building this was the best way I've found to learn. You can't animate attention cell by cell, or write a widget that shows a KV cache growing, without understanding exactly what's happening. Every page exposed a gap in my own understanding that I then had to fill.

I'm sharing it because if it helped me, it may help you too. And sharing it means people will find my mistakes, which is how I keep learning.

🤝 Help make it better

![Three buddies: one holding a star, one catching a bug, one sending a love-letter PR]

This project gets better with every pair of eyes on it. Suggestions are always welcome, big or small. Here's how you can help:

  • ⭐ Star the repo on GitHub. It helps more learners find it, and it makes my day.
  • 🐛 Raise an issue for anything wrong, confusing or broken: open an issue.
  • 🔧 Raise a PR to fix a typo, improve an explanation, add a widget or even a whole module: pull requests are welcome.
  • 💡 Suggest a topic you want explained, right here in the comments.
  • 🔁 Share it with a friend, classmate or teammate who's learning about LLMs.

Pick a module, flip the depth switch, play with a knob, and tell me which concept finally clicked for you. 👇

👉 llm-explained-lovat.vercel.app