{ "cells": [ { "cell_type": "markdown", "id": "1c33ef37", "metadata": {}, "source": [ "# 4. Tokens and a Bigram Language Model\n", "\n", "Behind the Secrets of LLMs, crash course part 2\n", "\n", "In notebooks 0 to 3 we fitted lines, curves and handwritten digits. From now on the data is text, and the task is the one every LLM solves: given the text so far, guess the next token.\n", "\n", "In this notebook we\n", "\n", "1. turn text into numbers (tokenization), first with characters and then with a small BPE that we write ourselves,\n", "2. build a language model that simply counts which character follows which (a bigram model),\n", "3. measure how good it is with the negative log-likelihood, cross-entropy and perplexity,\n", "4. learn the same model with gradient descent in PyTorch, using the training loop from notebook 3b,\n", "5. generate text and control it with the temperature.\n", "\n", "Time: about 45 minutes. A CPU is enough (in Colab: Runtime > Change runtime type > CPU)." ] }, { "cell_type": "code", "execution_count": 1, "id": "2359b839", "metadata": { "execution": { "iopub.execute_input": "2026-10-10T20:22:39.460175Z", "iopub.status.busy": "2026-10-10T20:22:39.458689Z", "iopub.status.idle": "2026-10-10T20:22:43.910412Z", "shell.execute_reply": "2026-10-10T20:22:43.906622Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "torch 2.14.1+cu130\n" ] } ], "source": [ "import math, os, urllib.request, collections\n", "import torch\n", "import torch.nn as nn\n", "import torch.nn.functional as F\n", "import matplotlib.pyplot as plt\n", "\n", "torch.manual_seed(42)\n", "show_ch = lambda c: {\" \": \"␣\", \"\\n\": \"\\\\n\"}.get(c, c) # make spaces/newlines visible in plots\n", "print(\"torch\", torch.__version__)" ] }, { "cell_type": "markdown", "id": "b683e3b3", "metadata": {}, "source": [ "## 1. Text is just a long list of characters\n", "\n", "We use tiny Shakespeare, about 1 MB of Shakespeare plays in a single text file." ] }, { "cell_type": "code", "execution_count": 2, "id": "778494b2", "metadata": { "execution": { "iopub.execute_input": "2026-10-10T20:22:43.912901Z", "iopub.status.busy": "2026-10-10T20:22:43.912367Z", "iopub.status.idle": "2026-10-10T20:22:43.935580Z", "shell.execute_reply": "2026-10-10T20:22:43.934867Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1,115,394 characters\n", "First Citizen:\n", "Before we proceed any further, hear me speak.\n", "\n", "All:\n", "Speak, speak.\n", "\n", "First Citizen:\n", "You are all resolved rather to die than to famish?\n", "\n", "All:\n", "Resolved. resolved.\n", "\n", "First Citizen:\n", "First, you know Caius Marcius is chief enemy to the people.\n", "\n", "All:\n", "We know't, we know't.\n", "\n", "First Citizen:\n", "Let us\n" ] } ], "source": [ "URL = \"https://raw.githubusercontent.com/karpathy/char-rnn/master/data/tinyshakespeare/input.txt\"\n", "if not os.path.exists(\"input.txt\"):\n", " urllib.request.urlretrieve(URL, \"input.txt\")\n", "\n", "with open(\"input.txt\", encoding=\"utf-8\") as f:\n", " text = f.read()\n", "\n", "print(f\"{len(text):,} characters\")\n", "print(text[:300])" ] }, { "cell_type": "markdown", "id": "0ea9b9aa", "metadata": {}, "source": [ "## 2. Tokenization: from text to integers\n", "\n", "A neural network only works with numbers. A tokenizer maps text to a list of integer IDs from a fixed vocabulary $\\mathcal{V}$:\n", "\n", "$$\\text{encode}: \\text{string} \\rightarrow (x_1, \\dots, x_n), \\quad x_t \\in \\{0, \\dots, |\\mathcal{V}|-1\\}$$\n", "\n", "and `decode` turns the IDs back into text. The simplest choice is one token per character." ] }, { "cell_type": "code", "execution_count": 3, "id": "f46fe3f2", "metadata": { "execution": { "iopub.execute_input": "2026-10-10T20:22:43.937616Z", "iopub.status.busy": "2026-10-10T20:22:43.937300Z", "iopub.status.idle": "2026-10-10T20:22:43.950094Z", "shell.execute_reply": "2026-10-10T20:22:43.949453Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "vocabulary size |V| = 65\n", "vocabulary: \"\\n !$&',-.3:;?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\"\n", "[20, 43, 50, 50, 53, 1, 58, 46, 43, 56, 43, 2]\n", "Hello there!\n" ] } ], "source": [ "chars = sorted(set(text))\n", "V = len(chars)\n", "stoi = {ch: i for i, ch in enumerate(chars)} # string -> integer\n", "itos = {i: ch for ch, i in stoi.items()} # integer -> string\n", "\n", "encode = lambda s: [stoi[c] for c in s]\n", "decode = lambda ids: \"\".join(itos[i] for i in ids)\n", "\n", "print(\"vocabulary size |V| =\", V)\n", "print(\"vocabulary:\", repr(\"\".join(chars)))\n", "print(encode(\"Hello there!\"))\n", "print(decode(encode(\"Hello there!\")))" ] }, { "cell_type": "markdown", "id": "7f0b25cf", "metadata": {}, "source": [ "### Characters, words, or something in between?\n", "\n", "| tokens are | vocabulary | sequence length | problem |\n", "|---|---|---|---|\n", "| characters | tiny (about 65) | very long | the model has to learn spelling, and the context fills up fast |\n", "| words | huge (100k and more) | short | unknown words, and *run*, *runs*, *running* get unrelated IDs |\n", "| subwords (BPE) | you choose (e.g. 50k) | medium | this is what GPT, Llama and Qwen use |\n", "\n", "Byte-Pair Encoding (BPE) starts from single bytes and keeps merging the most frequent pair of neighbouring tokens into a new token. It only takes a few lines, so let's write it." ] }, { "cell_type": "code", "execution_count": 4, "id": "c2344b44", "metadata": { "execution": { "iopub.execute_input": "2026-10-10T20:22:43.953494Z", "iopub.status.busy": "2026-10-10T20:22:43.953091Z", "iopub.status.idle": "2026-10-10T20:22:44.201429Z", "shell.execute_reply": "2026-10-10T20:22:44.200035Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "first 15 merges: ['e ', 'th', 't ', 's ', 'ou', ', ', 'd ', 'r ', 'in', 'an', 'en', ':\\n', 'y ', '\\n\\n', 'er']\n", "20,000 bytes -> 13,228 tokens (compression x1.51)\n" ] } ], "source": [ "def get_pair_counts(ids):\n", " # count how often each adjacent pair (a, b) occurs\n", " return collections.Counter(zip(ids, ids[1:]))\n", "\n", "def merge(ids, pair, new_id):\n", " # replace every occurrence of `pair` by the single token `new_id`\n", " out, i = [], 0\n", " while i < len(ids):\n", " if i < len(ids) - 1 and (ids[i], ids[i + 1]) == pair:\n", " out.append(new_id); i += 2\n", " else:\n", " out.append(ids[i]); i += 1\n", " return out\n", "\n", "# train BPE on a slice of the text, starting from raw UTF-8 bytes (256 base tokens)\n", "train_ids = list(text[:20000].encode(\"utf-8\"))\n", "ids = list(train_ids)\n", "merges = {} # (a, b) -> new token id\n", "vocab = {i: bytes([i]) for i in range(256)}\n", "for k in range(60): # 60 merges -> vocabulary of 256 + 60 tokens\n", " pair = get_pair_counts(ids).most_common(1)[0][0]\n", " new_id = 256 + k\n", " ids = merge(ids, pair, new_id)\n", " merges[pair] = new_id\n", " vocab[new_id] = vocab[pair[0]] + vocab[pair[1]]\n", "\n", "print(\"first 15 merges:\", [vocab[256 + k].decode(\"utf-8\", \"replace\") for k in range(15)])\n", "print(f\"{len(train_ids):,} bytes -> {len(ids):,} tokens (compression x{len(train_ids) / len(ids):.2f})\")" ] }, { "cell_type": "code", "execution_count": 5, "id": "9ea40da1", "metadata": { "execution": { "iopub.execute_input": "2026-10-10T20:22:44.204009Z", "iopub.status.busy": "2026-10-10T20:22:44.203285Z", "iopub.status.idle": "2026-10-10T20:22:44.210681Z", "shell.execute_reply": "2026-10-10T20:22:44.209554Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "39 characters -> 25 BPE tokens\n", "['F', 'ir', 'st ', 'C', 'it', 'i', 'z', 'en', ': ', 'the ', 'c', 'it', 'i', 'z', 'en', 's ', 'ar', 'e ', 'h', 'u', 'n', 'g', 'r', 'y', '.']\n" ] } ], "source": [ "def bpe_encode(s):\n", " ids = list(s.encode(\"utf-8\"))\n", " while len(ids) >= 2:\n", " # apply the merge that was learned EARLIEST among the pairs present\n", " pair = min(get_pair_counts(ids), key=lambda p: merges.get(p, float(\"inf\")))\n", " if pair not in merges:\n", " break\n", " ids = merge(ids, pair, merges[pair])\n", " return ids\n", "\n", "def bpe_decode(ids):\n", " return b\"\".join(vocab[i] for i in ids).decode(\"utf-8\", errors=\"replace\")\n", "\n", "s = \"First Citizen: the citizens are hungry.\"\n", "toks = bpe_encode(s)\n", "print(len(s), \"characters ->\", len(toks), \"BPE tokens\")\n", "print([bpe_decode([t]) for t in toks])\n", "assert bpe_decode(toks) == s" ] }, { "cell_type": "markdown", "id": "4bd8e5d8", "metadata": {}, "source": [ "**Try it:** encode a German or Hindi sentence with `bpe_encode`. Our BPE has only seen English, so how many tokens per character do you get now? Notebook 6 does the same with real LLM tokenizers.\n", "\n", "For the rest of this notebook we stay with characters. The vocabulary is small and easy to look at." ] }, { "cell_type": "markdown", "id": "5444c0f9", "metadata": {}, "source": [ "## 3. A language model gives text a probability\n", "\n", "With the chain rule of probability, any text can be scored one token at a time:\n", "\n", "$$P(x_1, x_2, \\dots, x_n) = \\prod_{t=1}^{n} P(x_t \\mid x_1, \\dots, x_{t-1})$$\n", "\n", "An LLM is a function that gives us $P(x_t \\mid x_{" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "data = torch.tensor(encode(text), dtype=torch.long)\n", "n = int(0.9 * len(data))\n", "train_data, val_data = data[:n], data[n:] # hold out 10% to measure generalisation\n", "\n", "N = torch.zeros((V, V), dtype=torch.long) # N[a, b] = how often b follows a\n", "N.index_put_((train_data[:-1], train_data[1:]), torch.ones(n - 1, dtype=torch.long), accumulate=True)\n", "\n", "# look at the counts for lowercase letters + space\n", "show = [stoi[c] for c in \" abcdefghijklmnopqrstuvwxyz\"]\n", "plt.figure(figsize=(8, 8))\n", "plt.imshow(N[show][:, show], cmap=\"Blues\")\n", "plt.xticks(range(len(show)), [show_ch(itos[i]) for i in show])\n", "plt.yticks(range(len(show)), [show_ch(itos[i]) for i in show])\n", "plt.xlabel(\"next character b\"); plt.ylabel(\"current character a\")\n", "plt.title(\"bigram counts N[a, b]\"); plt.show()" ] }, { "cell_type": "markdown", "id": "1f9c8566", "metadata": {}, "source": [ "If we divide each row by its sum, the counts become a probability distribution over the next character:\n", "\n", "$$P(b \\mid a) = \\frac{N[a,b] + 1}{\\sum_{b'} \\left(N[a,b'] + 1\\right)}$$\n", "\n", "The $+1$ is called smoothing. It makes sure that no probability is exactly 0. Now we can sample text, one character at a time." ] }, { "cell_type": "code", "execution_count": 7, "id": "31ea41d6", "metadata": { "execution": { "iopub.execute_input": "2026-10-10T20:22:44.844394Z", "iopub.status.busy": "2026-10-10T20:22:44.844146Z", "iopub.status.idle": "2026-10-10T20:22:44.868010Z", "shell.execute_reply": "2026-10-10T20:22:44.867148Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "th remofed hexpselteredoca meaman youd INAlste grecofurey h fotherere hath thig berelisseanongilost.\n", "tho y we w ke RYORD:\n", "Widarthofr nd; my f tsoo we w y mer aim whioervoto,\n", "Pre co n s uzed\n", "I s h. fo INVeprf pllie-milyompofond ssay eint odeld fleome igle inkee he t,\n", "As toinobo y tonesthast st hayowa\n" ] } ], "source": [ "P = (N + 1).float()\n", "P = P / P.sum(dim=1, keepdim=True) # every row sums to 1\n", "\n", "def sample_bigram(P, n_chars=300, start=\"\\n\"):\n", " g = torch.Generator().manual_seed(0)\n", " ix, out = stoi[start], []\n", " for _ in range(n_chars):\n", " ix = torch.multinomial(P[ix], num_samples=1, generator=g).item()\n", " out.append(itos[ix])\n", " return \"\".join(out)\n", "\n", "print(sample_bigram(P))" ] }, { "cell_type": "markdown", "id": "ef9f9a0a", "metadata": {}, "source": [ "It looks a bit like Shakespeare letter by letter, but not word by word. To compare models we need a number.\n", "\n", "## 4. How good is a language model?\n", "\n", "A good model gives a high probability to real text it has not seen before. For a held-out text $x_1, \\dots, x_n$ we look at\n", "\n", "* the **likelihood** $\\prod_t P(x_t \\mid x_{t-1})$. This is a tiny number, so we take logs.\n", "* the **negative log-likelihood** per token, also called the **cross-entropy**:\n", "$$\\mathcal{L} = -\\frac{1}{n}\\sum_{t=1}^{n} \\log P(x_t \\mid x_{t-1})$$\n", "* the **perplexity** $\\text{PPL} = e^{\\mathcal{L}}$. You can read it as \"the model is as unsure as if it had to pick uniformly from PPL options\".\n", "\n", "A quick sanity check: a model that knows nothing picks uniformly from all $|\\mathcal{V}|$ characters, so $\\mathcal{L} = \\log |\\mathcal{V}|$ and $\\text{PPL} = |\\mathcal{V}|$." ] }, { "cell_type": "code", "execution_count": 8, "id": "3680fd53", "metadata": { "execution": { "iopub.execute_input": "2026-10-10T20:22:44.872829Z", "iopub.status.busy": "2026-10-10T20:22:44.872326Z", "iopub.status.idle": "2026-10-10T20:22:44.915819Z", "shell.execute_reply": "2026-10-10T20:22:44.914728Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "uniform model : loss 4.174 perplexity 65.0\n", "bigram (train): loss 2.455 perplexity 11.6\n", "bigram (val) : loss 2.482 perplexity 12.0\n" ] } ], "source": [ "def nll(P, d):\n", " return -torch.log(P[d[:-1], d[1:]]).mean().item()\n", "\n", "uniform = math.log(V)\n", "print(f\"uniform model : loss {uniform:.3f} perplexity {math.exp(uniform):5.1f}\")\n", "print(f\"bigram (train): loss {nll(P, train_data):.3f} perplexity {math.exp(nll(P, train_data)):5.1f}\")\n", "print(f\"bigram (val) : loss {nll(P, val_data):.3f} perplexity {math.exp(nll(P, val_data)):5.1f}\")" ] }, { "cell_type": "markdown", "id": "c1376d25", "metadata": {}, "source": [ "## 5. The same model, learned with gradient descent\n", "\n", "Counting stops working once the context is longer than one token. Neural language models learn the probabilities instead. For the bigram case the whole network is one $|\\mathcal{V}| \\times |\\mathcal{V}|$ weight matrix $W$:\n", "\n", "1. one-hot encode the current character: $\\mathbf{e}_a \\in \\{0,1\\}^{|\\mathcal{V}|}$\n", "2. compute the logits (raw scores) $\\mathbf{z} = \\mathbf{e}_a W$, which is just row $a$ of $W$\n", "3. turn them into probabilities with the softmax: $p_b = \\dfrac{e^{z_b}}{\\sum_{b'} e^{z_{b'}}}$\n", "4. the loss is the cross-entropy with the real next character $y$: $\\mathcal{L} = -\\log p_y$\n", "\n", "\"One-hot times a matrix picks a row\" is exactly what `nn.Embedding` does. It is the first layer of every LLM." ] }, { "cell_type": "code", "execution_count": 9, "id": "d25259cc", "metadata": { "execution": { "iopub.execute_input": "2026-10-10T20:22:44.917628Z", "iopub.status.busy": "2026-10-10T20:22:44.917315Z", "iopub.status.idle": "2026-10-10T20:22:44.940359Z", "shell.execute_reply": "2026-10-10T20:22:44.938824Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "one-hot @ W == W[a] : True\n", "embedding output shape: torch.Size([2, 65])\n" ] } ], "source": [ "W = torch.randn(V, V)\n", "a = stoi[\"h\"]\n", "one_hot = F.one_hot(torch.tensor(a), V).float()\n", "print(\"one-hot @ W == W[a] :\", torch.allclose(one_hot @ W, W[a]))\n", "\n", "emb = nn.Embedding(V, V) # a learnable lookup table\n", "print(\"embedding output shape:\", emb(torch.tensor([a, stoi[\"e\"]])).shape)" ] }, { "cell_type": "code", "execution_count": 10, "id": "d7cea3d1", "metadata": { "execution": { "iopub.execute_input": "2026-10-10T20:22:44.943359Z", "iopub.status.busy": "2026-10-10T20:22:44.942975Z", "iopub.status.idle": "2026-10-10T20:23:09.177153Z", "shell.execute_reply": "2026-10-10T20:23:09.176571Z" } }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "neural bigram val loss 2.490 vs counting 2.482\n" ] } ], "source": [ "class BigramLM(nn.Module):\n", " def __init__(self, V):\n", " super().__init__()\n", " self.table = nn.Embedding(V, V) # logits for the next char, one row per current char\n", "\n", " def forward(self, idx, targets=None):\n", " logits = self.table(idx) # (B, V)\n", " loss = None if targets is None else F.cross_entropy(logits, targets)\n", " return logits, loss\n", "\n", "model = BigramLM(V)\n", "opt = torch.optim.Adam(model.parameters(), lr=0.05)\n", "\n", "def batch(d, bs=4096):\n", " ix = torch.randint(len(d) - 1, (bs,))\n", " return d[ix], d[ix + 1] # (current char, next char)\n", "\n", "history = []\n", "for step in range(1500):\n", " x, y = batch(train_data)\n", " _, loss = model(x, y) # 1. forward\n", " opt.zero_grad()\n", " loss.backward() # 2. backward (autograd, as in notebook 3a)\n", " opt.step() # 3. update\n", " history.append(loss.item())\n", "\n", "with torch.no_grad():\n", " val_loss = F.cross_entropy(model.table(val_data[:-1]), val_data[1:]).item()\n", "\n", "plt.plot(history, alpha=0.6, label=\"neural bigram (train batches)\")\n", "plt.axhline(nll(P, val_data), color=\"r\", ls=\"--\", label=\"counting model (val)\")\n", "plt.axhline(uniform, color=\"gray\", ls=\":\", label=\"uniform log|V|\")\n", "plt.xlabel(\"step\"); plt.ylabel(\"cross-entropy loss\"); plt.legend(); plt.show()\n", "print(f\"neural bigram val loss {val_loss:.3f} vs counting {nll(P, val_data):.3f}\")" ] }, { "cell_type": "markdown", "id": "18b760ae", "metadata": {}, "source": [ "Both end up at almost the same loss. Counting gives the maximum-likelihood answer, and gradient descent finds it too. The neural version has one big advantage: it still works for models where counting is impossible.\n", "\n", "### Why cross-entropy is so convenient\n", "\n", "For logits $\\mathbf{z}$, softmax output $\\mathbf{p}$ and one-hot target $\\mathbf{y}$, the gradient is simply\n", "\n", "$$\\frac{\\partial \\mathcal{L}}{\\partial z_b} = p_b - y_b,$$\n", "\n", "the predicted probability minus the truth. Let's check that autograd agrees." ] }, { "cell_type": "code", "execution_count": 11, "id": "0927a5e7", "metadata": { "execution": { "iopub.execute_input": "2026-10-10T20:23:09.187155Z", "iopub.status.busy": "2026-10-10T20:23:09.186796Z", "iopub.status.idle": "2026-10-10T20:23:09.198314Z", "shell.execute_reply": "2026-10-10T20:23:09.197371Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "autograd == softmax - one_hot : True\n" ] } ], "source": [ "z = torch.randn(4, V, requires_grad=True) # logits for a batch of 4\n", "y = torch.tensor([stoi[\"a\"], stoi[\"b\"], stoi[\"c\"], stoi[\"d\"]])\n", "F.cross_entropy(z, y).backward() # mean over the batch\n", "\n", "manual = (F.softmax(z, dim=1) - F.one_hot(y, V).float()) / 4\n", "print(\"autograd == softmax - one_hot :\", torch.allclose(z.grad, manual.detach(), atol=1e-6))" ] }, { "cell_type": "markdown", "id": "9a7d1d9e", "metadata": {}, "source": [ "## 6. Controlling the output with the temperature\n", "\n", "Before sampling we can divide the logits by a temperature $T$:\n", "\n", "$$p_b = \\frac{e^{z_b / T}}{\\sum_{b'} e^{z_{b'}/T}}$$\n", "\n", "* for a small $T$ the model almost always picks the most likely token (greedy and repetitive)\n", "* $T = 1$ is the model's own distribution\n", "* for a large $T$ the distribution gets flatter: more surprising text, and more mistakes" ] }, { "cell_type": "code", "execution_count": 12, "id": "e3801046", "metadata": { "execution": { "iopub.execute_input": "2026-10-10T20:23:09.202527Z", "iopub.status.busy": "2026-10-10T20:23:09.202330Z", "iopub.status.idle": "2026-10-10T20:23:09.486233Z", "shell.execute_reply": "2026-10-10T20:23:09.485554Z" } }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAABHAAAAEuCAYAAADmyuX6AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjIsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvgI3uAAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAR7BJREFUeJzt3Xl8Tdf+//F3JiFkkhgiQsxDY44qami1RU3VonrVvUVbUyedJF+US1VMrZZeStHSFtdVraqaOt1y3SpKhVSphChJERklR4b9+8Mv5zqSkJPpbPJ6Ph778ehZe+2zP1vSz9n5nLXWdjIMwxAAAAAAAABMy9nRAQAAAAAAAODGKOAAAAAAAACYHAUcAAAAAAAAk6OAAwAAAAAAYHIUcAAAAAAAAEyOAg4AAAAAAIDJUcABAAAAAAAwOQo4AAAAAAAAJkcBBwAAAAAAwOQo4OC28cEHH6h79+6ODgMA4AAtW7bUpk2bHB0GAKAMjB49WuHh4Y4OAyhzro4OACgpaWlpio+Pd3QYAAAHOHfunNLT0x0dBgCgDCQkJMjZmbEIKH/4rQcAAAAAADA5Cji4oSlTpuiFF15wdBimkJ2drQEDBujDDz90dCil4uLFi7py5YqjwwBgEsePH9f999+vAwcOODoUU/jnP/+pvn37lvtRPoZhKC4uztFhAChhWVlZeuSRR7Ry5UpHh2IKx44d0/3336+DBw86OpQSl5mZqT/++EOGYdh9bHp6ui5dulQKUaGwKOCUIy+99JLc3NysW8WKFRUSEqKxY8fqwoULefr//vvvmjVrlurUqeOAaK/KzMzUqVOnSvSGecyYMapWrZpN27lz53T+/Hmbtt9++01ubm7WDzIXFxd5eXkpPDxcGRkZJRJL69atbX4m+W3//Oc/S+RcBdm6dauaNm0qf39/eXt7q1+/fkpISLjpcUOHDs033rvvvrtU4wVgv6SkpDz/r1avXl3du3fXZ599lu8xb7zxhn7++WeFhISUbbDXOH/+vM6dO1di73f27Fm5ublp4cKF1rb09HSdOnVKmZmZNn0ff/xx1atXz/q6bdu2+vLLL7V06dISieXTTz+9af4v7X/7bdu2KSAgQG5ubvrkk09u2NcwDE2cOFHVqlVTQECAatasqRkzZpRqfACKLjQ01CafeHl56c4779Ts2bOVlZWVp//HH3+sTz/9VK1atXJAtFelpKTo1KlTRSosFKRZs2YaNGiQ9bVhGDp16pRSUlJs+i1btkxubm46efKkJKlx48b67bff9Pe//71E4rh48eJNc76bm1upLgcRHx+voUOHqnLlyqpdu7a8vb01ffr0fH8frnfmzBn16NFDPj4+8vPzU8uWLbVnz55SixUFYw2cciQnJ0c5OTlasWKFpKvFkV9//VXLli3Tli1bdOTIEVWpUsXa//3335ck/eUvf3FIvNLVIkpISIg2b96sPn36lMh7VqxYURUqVLBp69+/v4KDg7V+/Xprm4eHh7KyslSxYkVr21//+ld99NFH+vzzz/Xoo48WO5a///3vSkxMlHR1hM+oUaPUp08fDR482NrnzjvvLPZ5CrJjxw71799fvXr10ltvvaW4uDhNmjRJXbp00YEDB+Tu7l7gsdHR0WrTpo3Gjx9v0359cQyAOWRlZenhhx9W//79JUkXLlzQl19+qYEDB+qdd97Rs88+a+2bnJysNWvW6KmnnsqTL8vSuHHjFBMTo59++qlE3i+/vP7NN9+ob9++ioyM1B133GFtv/6zomHDhurUqZOWLFmi559/vtixtGvXzvo5K0kbNmzQF198Yf0jQpK8vb2LfZ78ZGVladKkSZo7d666d++ub7/99qZ/MI0dO1bvv/++pk6dqs6dO2v79u167bXXlJGRoZkzZ5ZKnACKLjs7W40bN9arr74qSUpNTdXevXv1f//3f9q7d682bNhg03/JkiW644471LZtW0eEK0latWqVnnnmGaWmpqpy5col8p7u7u4297OXL19WcHCwFi1aZHMPW6lSJWVlZalSpUqSJCcnJz3++OOKiIjQuXPnFBAQUKw4qlSpYpPzjxw5orlz5+qll15SixYtrO2llfezs7M1cOBAnT59Wu+//74aNGignTt3avr06crOzr5hoSohIUGdO3dWhQoVtGLFCnl5eenNN9/Ufffdp++//16hoaGlEjMKYKDceOGFFwxXV9c87fv27TOcnJyMOXPm2LQ3bNjQePDBB2/4nhaL5abnTU9Pty/Qa0RGRhqSjM2bN9+076JFi4ymTZvetF94eLjRsGFDm7bQ0FBj0KBBNm0XL140JBmfffaZtS07O9sIDAw0HnnkkUJeQeFlZWUZkoywsLASf++CdOnSxWjfvr1x5coVa9u+ffsMScYHH3xww2Nr1Khh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LRZLgU8euX5NgNw/8HPXWzl58qTS09MLvBE/fvy4HnjgAUlSUFCQnnjiCb399ttatGhRnuHqZpR7E1tSjxIvju3bt9/waSiHDh0q8OcYGBgoSfrzzz/zDHuMj4+Xv79/gcMpXVxcVLduXZs2b29vTZo0SYMHD1ZkZKS1sAfAPBISEqyfAb6+vnrqqaf05JNP2qw1YLFYJCnf3FGxYkU5O9sun+fm5mbNh+fPn1dKSormz5+v+fPn5zne39/f5nV4eLjeeecd+fn5acKECcW6trLi7u5uivwvXX2CYkHTl5566inrehLFFRgYqKNHj+a7Lz4+Xp07dy6R8wAoWenp6dacX7FiRT344IN6+OGH1aVLF5t+9t73X7vG4smTJ3X06FE1bdo03+NPnjxpnbrTr18/tWjRQgcPHtSaNWuKfF1lyUz3/a+//ro+/vjjfPe1atVKa9euLdT77Nq1S0OHDtWQIUM0a9asG/YNCAiQs7Oz/vzzzzz7ch95XhJLXKDwKOCUMy4uLvr2229v2q9q1apKSEgo0jmqV68uT09P/fbbb/kujnht9frEiRN6//33FRoaqrfeekt/+9vfbB5lbkYXL16UlPcPEUcIDAy0WXDuetf/oXWt3ALMwYMH1aRJE5t9hw4dylOgKWw8kvJN8gAcb9SoUdaF2guSW9DNzXX28PX1lZubmyZNmqQxY8bk2X/9Z8KkSZNUr149xcfHa+nSpRo7dqzd5yxrFy9eNEX+l6T777+/wHXHQkJCSuw8devW1WeffabLly/b/DEXHx+vuLi4In1eACh97dq1044dO27ar2rVqkXK+dLV+/7atWtr1apV+e738/Oz/veaNWsUFRWlkJAQTZ8+/ZZYAN1M9/2tW7e2fslyvcIWUX755Rf169dP3bp104cffnjThexdXFwUGBhoM4I2V+5oVB5qUrYo4CBfjRo1ksVi0e+//17gkMqCtGnTRikpKYqJidFdd91lbY+Li1N8fLyqV68u6ep0rr/97W8KCQnRjh071LRpU02YMEHLli3L8543eppSSSnsOXIXjHT0AsbS1QXJZsyYUaRjW7ZsqebNm2vlypV69NFHre0xMTH67rvvFBERUeCxq1ev1osvvqh9+/bZ3Lh/88031vcGcGtyc3NTcHBwgSMubsTV1VUhISHas2ePpk6darNvz549atasmfX1V199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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "----- T = 0.3\n", "\n", "\n", "\n", "I s there the ange be the the t hathe me t the the the thin he my ind me the thanghe he the the me withe the tor the the the the s hist t thanours me t the the me the t t t win t thin t the, there \n", "\n", "----- T = 1.0\n", "\n", "Caw;\n", "\n", "By\n", "M:\n", "The usil, thartie, by f ces.\n", "Bowin'sanvif tearaicadeemotiraim. s, aroflfogaiee, hees n, grit ofoutelor d:\n", "BUCO:\n", "ARYeatsishisot therdvees me y! we, d deh famy bu iswhit RLLLIUCLENa, it rsh\n", "\n", "----- T = 2.0\n", "\n", "Caw;\n", "\n", "qWers! me uagl,' thavieyoZo f ces.\n", "Bowin'sacvy ceeacaic heemotirawi. xpooroalfXgaiee, je's'd, gridgofZALelordd:\n", "Byt prn beatssasifotSt'Erdv$POH: Ra!'rehe-ghehckmmy bu izwhi'GRLLLNLOLuft, itursh\n", "\n" ] } ], "source": [ "logits = model.table.weight[stoi[\"t\"]].detach() # what follows the letter 't'?\n", "top = torch.topk(logits, 8).indices\n", "\n", "fig, axes = plt.subplots(1, 3, figsize=(14, 3), sharey=True)\n", "for ax, T in zip(axes, [0.5, 1.0, 2.0]):\n", " p = F.softmax(logits / T, dim=0)[top]\n", " ax.bar([show_ch(itos[i.item()]) for i in top], p)\n", " ax.set_title(f\"P(next | 't'), T = {T}\")\n", "plt.show()\n", "\n", "def sample_model(T, n_chars=200):\n", " g = torch.Generator().manual_seed(1)\n", " ix, out = stoi[\"\\n\"], []\n", " for _ in range(n_chars):\n", " p = F.softmax(model.table.weight[ix].detach() / T, dim=0)\n", " ix = torch.multinomial(p, 1, generator=g).item()\n", " out.append(itos[ix])\n", " return \"\".join(out)\n", "\n", "for T in [0.3, 1.0, 2.0]:\n", " print(f\"----- T = {T}\\n{sample_model(T)}\\n\")" ] }, { "cell_type": "markdown", "id": "1c768173", "metadata": {}, "source": [ "## 7. What is still missing?\n", "\n", "The bigram model only ever sees one previous character, so it cannot learn words, grammar or who is speaking. Its validation loss gets stuck around 2.5.\n", "\n", "In notebook 5 (Attention and TinyGPT) every position can look at all the positions before it, using self-attention. Same data, same loss, same training loop, and much better text.\n", "\n", "---\n", "\n", "### Exercises\n", "\n", "1. **Tokens per language.** Train the mini BPE with 200 merges. Compare the compression on English and on a German text you paste in.\n", "2. **A trigram model.** Count `N[a, b, c]` in a $V \\times V \\times V$ tensor. Does the validation loss go down? What happens to the number of combinations you never saw?\n", "3. **Smoothing.** Replace $+1$ by $+0.01$ and by $+100$. How do the train and validation loss change, and why?\n", "4. **Perplexity.** Compute the perplexity of the model on `\"zzzzzzzzzz\"` and on `\"the the the\"`. Why are they so different?\n", "5. **Temperature.** Which temperature gives the lowest validation loss on the trained logits? Why?" ] } ], "metadata": { "colab": { "provenance": [] }, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.16" } }, "nbformat": 4, "nbformat_minor": 5 }