What we'll cover
This lab turns the pipeline of 5.1–5.3 from words into code, in two parts. First you find the training stages in a real, readable codebase: Karpathy's nanochat, a complete ChatGPT-style pipeline written to be read. Then you put a base model beside the instruction-tuned model built from it and work out what the tuning changed.
The usual account of that second part is that base models ramble and tuned models answer. Run it before you decide whether that is what happens. Everything runs on free Google Colab in about two minutes of compute; the hour is for thinking about what comes out.
Setup Colab — no GPU needed
- Open the notebook in Colab. It opens read-only from GitHub, so use File → Save a copy in Drive before you change anything; the copy in your Drive is the one you edit and submit.
- Run the first cell. Colab will warn you that the notebook "was not authored by Google", which it says of anything loaded from GitHub; choose Run anyway.
- Work down the notebook with Shift+Enter, reading each cell before you run it. The two models together are about 2 GB of download and a minute of CPU.
You can also read the whole notebook on this site before you start, or download the .ipynb for Jupyter.
The code is written for you, so this lab is about running it and pulling at it rather than building it. The second part ends with an "Explore" cell: two or three things to change and re-run, and one short question to answer. The first ends with a written question.
① Find the stages in a real pipeline
Three objectives, three files
nanochat (github.com/karpathy/nanochat, MIT-licensed) runs tokenisation, pretraining, supervised fine-tuning, reinforcement learning, evaluation and inference. You will not run it, since it targets a multi-GPU node, but the notebook fetches the three scripts that matter and finds the line in each where that stage's objective lives:
base_train.py: pretraining is one line,loss = model(x, y), whereyisxshifted by one token. That one line is the pretraining objective of 5.1.chat_sft.py: fine-tuning uses the same loss, with the targets for every user token set to the ignore index. The model is trained only on the assistant's words. That is 5.2, in three lines of tensor indexing.chat_rl.py: the reward comes fromtrain_task.reward(...), a checker that marks a GSM8K answer right or wrong.
nanochat does have a reinforcement learning stage: GRPO on grade-school maths, described in its own docstring as close to plain REINFORCE once the trust region and clipping come off. What it does not have is a reward model learned from human preferences. Those are different stages of the 5.3 table, and the difference is where the reward comes from: a checker that can be verified against ground truth, or a model trained to predict what a person would prefer. Session 6 is about the second kind, and about what goes wrong with it.
The notebook searches for these patterns rather than quoting line numbers, because the repository is actively developed and any line number printed here would be wrong within a month. If a search comes back empty, read the file and find where the objective moved.
② The same questions, two models
The matched pair
Qwen2.5-0.5B and Qwen2.5-0.5B-Instruct share an architecture, a size, a tokeniser and a pretraining run. The second has been through supervised fine-tuning and preference tuning; the first has not. Whatever differs between them is what post-training did, isolated. The notebook puts five prompts to both and prints the answers side by side, with greedy decoding, so your output will match the discussion exactly.
- Note the two call shapes. The base model gets a raw string and continues it. The instruct model gets a chat template: special tokens marking who is speaking, which its tuning taught it to expect. The notebook prints the template so you can see what those tokens are.
- Check whether the textbook contrast appears. On most of these prompts the base model answers the question competently, and the differences that are there are smaller and easier to miss.
- Read the two answers to "What is the capital of Kenya?". One is wrong, and it is not the one the story predicts.
- One model summarises Romeo and Juliet. The other declines, asserting that no such text exists. Work out which is which, and what a refusal like that costs a user.
- Both models translate "good morning" into isiZulu, and both produce something. If you read isiZulu, judge them. If you do not, notice how confident the fluent one sounds and ask how you would have known otherwise. Session 9.4 turns this into a measurement.
- Then read the last line of the base model's isiZulu attempt. Nothing in the prompt asked for it, and it explains why the first bullet turned out as it did.
The Explore cell asks you to feed the chat template to the base model, raise the token cap, and try prompts in a language you speak. The question at the end asks you to sort what you found into form and substance: which of these differences is about how an answer is presented, and which is about what the model knows or gets right. A model that has been through this pipeline is routinely called "aligned". On this evidence, decide what that word licenses you to assume.
Submit
Your notebook, run end to end with output visible: the nanochat stage-mapping (①), and the base-versus-instruct comparison with your two or three sentences separating form from substance (②). Graded on completion and the quality of your observations; resubmission allowed.
Tools and references
Core
• Karpathy, nanochat (github.com/karpathy/nanochat, MIT): the readable full pipeline; nanoGPT (github.com/karpathy/nanoGPT) for the pretraining loop alone.
• Qwen Team, Qwen2.5 Technical Report (arXiv:2412.15115): the models used in ②, including what the post-training consisted of.
• Hugging Face Transformers docs: generate, chat templates and the model hub.
Session 5 summary and what's next
An LLM is built in stages: web-scale self-supervised pretraining yields a capable but unaligned base model (5.1); supervised fine-tuning on demonstrations makes it follow instructions but can only imitate, never select the better answer (5.2); the full post-training stack shapes the assistant as a thin proxy-driven layer over a vast base, with a distinct misalignment opening at every stage (5.3); and you have now read those stages as code and measured what the last of them changed, which is less than the usual story claims (5.4).
Next (Session 6): the stage that breaks through SFT's ceiling, RLHF. We learn a reward model from human preferences, optimise the policy against it with a KL leash, and confront the price: optimising a learned proxy invites the Goodhart failures of Session 3.1: reward hacking and sycophancy.