Working Notes on Large Language Models

I wrote these notes for students who know some Python and some linear algebra and want to understand how a language model actually works, not just how to call one. Each chapter ends in a project you can run on a laptop, and no chapter needs a GPU.

Nothing here needs a cluster. The models are small on purpose, so you can print every tensor and check the numbers by hand. That is also how you find out when you are wrong.

Why these notes are free

I believe knowledge should be shared, and that no one should have to pay to learn.

Almost everything I know about these models I learned because someone decided to give what they knew away: a researcher who published openly, a teacher who put lecture notes online, a stranger who took the time to answer a question. I never met most of them and I could never repay them. The only way I know to thank them is to do the same for someone else.

So these notes are free, and they will stay free. The text, the figures, the notebooks and the trained models are yours to read, run, copy and adapt. There is nothing to register for and nothing to buy, and no chapter needs a GPU or a paid service. That was a deliberate choice. Curiosity and talent are found everywhere; access to good teaching is not. A student anywhere in the world with an ordinary laptop should be able to learn how these models really work, and the only cost should be their time.

If you teach, use these chapters in your own classes. If you are learning on your own, take them at your own pace, and do not be discouraged when something does not make sense the first time. It did not make sense to me the first time either.

If the notes help you, the one thing I ask in return is that you pass it on. Explain an idea to someone who is just starting, or share what you build. And if you find a mistake, tell me by opening an issue, so that the next reader learns it right.

Ali Al Bataineh

Chapters

  1. Attention and the transformer blockProject: A two-block transformer in PyTorch that learns to reverse strings, tested on unseen strings and on longer ones; read what each head attends to. CPU, 41 s of training on a laptop.
  2. What makes transformers fastProject: Add rotary positions and a KV cache to the chapter 1 model; measure generation speed and length generalisation before and after. CPU.
  3. From transformer to language modelProject: Train a byte-pair tokenizer and a small GPT on one public-domain book; sample with temperature, top-k and top-p. CPU.
  4. Training: pretraining, SFT and LoRAProject: Instruction-tune the chapter 3 model on checkable word-list tasks, full fine-tuning against LoRA, with a loss mask, a schedule, a forgetting check and a held-out-word experiment. CPU.
  5. Tuning on preferences: RLHF, PPO and DPOProject: Preference pairs for the chapter 4 model, a reward model, then DPO; the preference is measured before and after. CPU.
  6. Reasoning: scaling RL with GRPOProject: GRPO on a composed instruction the chapter 4 model was never taught, with a dense checkable reward. CPU.
  7. Agents: retrieval, tools and loopsProject: A BM25 retriever over these notes and a tool loop run by a small open instruct model, with a failure log. CPU; one 700 MB download.
  8. Evaluation: benchmarks and LLM-as-a-judgeProject: An exact-match harness across the chapter 4 to 6 models, a contamination demonstration, and a position-bias test of an LLM judge. CPU.

Code, notebooks and figures: github.com/aalbata/from-attention-to-agents