CS 601.471/671  ·  NLP: Self-supervised Models  ·  Fall 2026

Handout #2 — Language Modeling

Session 2 (Thu, Sept 3)  ·  Slides: Language Modeling  ·  Course page

Handout #1 ended with one line: a language model is a distribution over sequences, factored by the chain rule into one next-word prediction per position. This handout asks what that buys you, how to estimate those predictions by counting, how to measure whether they are any good, and what to do when one of them comes out as exactly zero.

Assigned papers
None. This handout is the reading for Session 2. §7 lists optional depth if you want it.
Time
50–70 minutes.
By the end you should be able to
  • state the language modeling problem formally, and say what the Markov assumption gives up;
  • describe the two things an LM lets you do — score and generate — and how recursive sampling works;
  • estimate n-gram probabilities from counts, by hand, on a small corpus;
  • define perplexity two equivalent ways, and read it as a branching factor;
  • explain why sparsity — not compute — is what limited counting-based models;
  • say why counting hits a wall, and what would have to replace it.
Assumes
Handout #1 §2.2 (the chain-rule factorization and the cross-entropy objective) and §1.2 (conditionals, log space).

1What a language model is

A language model assigns a probability to a sequence of words. That is the entire definition — and it is worth noticing how strange a goal it is. Nobody wants the number. What we want is what the model must know in order to produce a good one.

1.1  The problem, stated formally

Fix a finite vocabulary $\Sigma = \{x_1, x_2, \ldots, x_V\}$. Let $\Sigma^*$ be the set of all finite sequences over it — the, the cat, cat the the, and so on, an infinite set. A language model is a probability distribution over $\Sigma^*$:

$$ \sum_{e \in \Sigma^*} p_{\text{LM}}(e) = 1, \qquad p_{\text{LM}}(e) \geq 0 \;\; \forall e \in \Sigma^*. $$

Two things in that statement deserve attention. First, the mass has to be spread over an infinite set, which is why the end-of-sequence token matters so much — it is what lets the total converge rather than leaking away into ever-longer strings. Second, the definition never says what the atomic unit is. Words, characters, bytes, subword pieces: all are legal choices of $\Sigma$, and the choice turns out to matter enormously (both for the zero problem in §4 and for the numbers in §5).

1.2  Trained on conditionals, learning the joint

In practice we never touch $p_{\text{LM}}(e)$ directly. We train on next-word predictions — "the cat sat on the ___" — which are conditionals, sometimes loosely called the marginals the model is fit to. The chain rule from Handout #1 is what promotes those local predictions into the full joint distribution:

$$ p(x_1, \ldots, x_T) = \prod_{t=1}^{T} p(x_t \mid x_{<t}). $$
The point to hold on to You train on conditionals and you get the joint for free. Nothing in the training procedure ever computes a probability over a whole document, yet the chain rule means the model implicitly defines one. Every sampling, scoring and ranking trick in the rest of the course is cashing in on that identity.
Quick check — what is language modeling? Quiz 1, sp2024 & sp2025

Which of these describes language modeling?

  • ○ Self-supervised learning over language data.
  • ○ Learning a joint distribution over word sequences in a language.
  • ○ Learning a marginal (conditional) distribution over word sequences.
  • ○ All of the above.
Answer
All of the above — which is the point of this subsection, and the reason the question is worth asking. The three descriptions are not competing definitions; they are the same object from three angles. It is self-supervised because the targets come from the text itself; you fit it to conditionals; and the chain rule means those conditionals define the joint whether you compute it or not. A student who picks only one has usually lost track of which of the three the training loop actually touches.

1.3  The Markov assumption

The factorization is exact — no assumptions. But there is a problem hiding in $x_{<t}$: as $t$ grows, the conditioning context grows without bound. To predict word 500 you would need a distribution conditioned on a specific 499-word prefix, and essentially every 499-word prefix in the language has occurred either once or never. No amount of data fixes this.

So we approximate, by truncating the context:

$$ p(x_t \mid x_{<t}) \approx p(x_t \mid x_{t-n+1}, \ldots, x_{t-1}). $$

Concretely, for P(mat | the cat sat on the), keeping one word of context gives P(mat | the); two gives P(mat | on the); three gives P(mat | sat on the). This is the only approximation an n-gram model makes. Everything else — the counting, the smoothing — is bookkeeping.

It is also obviously false, and the lecture's example is the one to remember: "The computer which I had just put into the machine room on the fifth floor crashed." The subject of crashed is computer, thirteen words back. No n-gram model of any practical order can see it. And yet for two decades this was the best we had, and it was good enough to build speech recognition and machine translation on. Understanding why it worked, and precisely where it broke, is the fastest route to understanding what replaced it.

1.4  A very short history

WhenWhatWhy it mattered
1913 Markov counts letter transitions in Eugene Onegin. The first n-gram model, built by hand, to argue about dependent random variables.
1948–51 Shannon frames language as an information source, measures the entropy of printed English by having people guess the next letter, and builds "$k$-th order approximations" to English from co-occurrence counts. Establishes the idea this whole course rests on: how well you can predict the next symbol measures how well you model the language. Perplexity is his entropy, exponentiated.
1980s–90s Fred Jelinek's group at IBM — and later here at Hopkins, where he founded CLSP — scales n-grams into working speech recognition and statistical machine translation. The smoothing literature (Good–Turing, Kneser–Ney) grows up around the zero problem. Language models become infrastructure. Jelinek's provocation — "every time I fire a linguist, the performance of the speech recognizer goes up" — is the moment the field's centre of gravity moved from hand-built rules to counting, and it prefigures every scaling argument you will meet later.
2003 Bengio et al. replace the count table with a neural network over word vectors. The fix for sparsity: similar contexts share statistical strength instead of being separate table entries. That is Handout #3, and the rest of the course.

2What you can do with one

Suppose someone hands you a trained language model. You can do exactly two things with it, and everything else is built from them.

2.1  Score, and therefore rank

An LM assigns a probability to any string. So you can compare strings, and the probability behaves as a rough measure of how familiar — how fluent, how grammatical, how plausible — the string is:

Higher probabilityLower probabilityWhat the gap reflects
I like Johns Hopkins University  ($\approx 10^{-5}$) like Hopkins I University Johns  ($\approx 10^{-15}$) word order — syntax
I like Johns Hopkins University I like John Hopkins University a spelling/naming error
JHU is located in Baltimore. JHU is located in Virginia. a fact about the world

That last row is the one to dwell on. Nothing in the training objective mentions truth, and yet the true sentence is the more probable one — because true sentences are the ones people wrote. This is exactly the mechanism Handout #1 §2.3 described, now visible as a comparison of two numbers. It is also why the same mechanism fails: where the corpus is confidently wrong, the model will be too.

Ranking by probability is directly useful. Spelling correction, speech recognition and machine translation all generate several candidate strings by other means and then ask a language model which one sounds most like the language. That was the dominant application of LMs for thirty years.

2.2  Generate, by sampling recursively

The second thing is more surprising. A model that only ever predicts one next word can produce arbitrarily long text, by feeding its own output back in as context. Start with a prompt and repeat:

context = "Johns Hopkins is"
while True:
    next_word = sample(p(X | context))   # draw from the model's distribution
    if next_word == "</s>":
        break
    context = context + " " + next_word

Which might run:

One trajectory Johns Hopkins islocatedatthestateofMaryland</s>

Note the last step. The model does not run until we stop it; it predicts that the sequence is over, by assigning high probability to the end-of-sequence token. That is what makes $p_{\text{LM}}$ a distribution over $\Sigma^*$ rather than an infinite stream — and it is the same $\texttt{</s>}$ that will show up in the counts in §3.

Everything you have ever seen a chatbot do is this loop. The model is still only answering "what word comes next?"; the essay is an emergent property of asking that question a thousand times in a row.

2.3  Why care

Two reasons, and the second is the ambitious one.

Language modeling is a subcomponent of an enormous number of tasks. Summarization, translation, spelling correction, dialogue — each needs to produce or evaluate fluent text, and that is what an LM provides.

Language modeling is a proxy for language understanding. To predict the next word reliably, you must have understood the context — the syntax, the topic, the facts, the intent. There is no shortcut that gets you low loss without that. This is a claim, not a theorem, and it is the bet the entire field has placed. Handout #1 §2.4 argued for it and against it; keep both arguments live.

3Estimating by counting

Given the Markov assumption, the maximum-likelihood estimate is exactly what you would guess: count, and divide.

$$ \hat{p}(x_t \mid x_{t-n+1}^{\,t-1}) = \frac{C(x_{t-n+1}, \ldots, x_{t-1}, x_t)}{C(x_{t-n+1}, \ldots, x_{t-1})} $$

"Of all the times I saw this context, what fraction of the time was the next word this?" There is no optimization, no gradient, no training loop — one pass over the corpus to build a table of counts, and you are done. A trigram model over a 1.7-million-word corpus trains in seconds on a laptop. That simplicity is worth appreciating before we spend the rest of the semester on the alternative.

Terminology, and an off-by-one worth pinning down An n-gram is a chunk of $n$ consecutive words: cat is a unigram, the cat a bigram, the cat sat a trigram, the cat sat on a four-gram. An n-gram model is named for the size of that chunk, so it conditions on $n-1$ words: a trigram model predicts the next word from the two before it.

Shannon's older phrasing counts differently — his "3rd order approximation" conditions on three words, which is a four-gram model. Both conventions are still in use. When you read a number, check whether it names the chunk or the context.

3.1  Counting, hands on

The widget below does exactly this over an 18-sentence corpus, small enough that you can check any probability it reports by hand:

Next-token explorer Type a context, switch orders, and sample from the model. Watch what happens to the distribution's sharpness — and to whether it exists at all.
Work through these
  1. Type the cat and switch between Unigram, Bigram and Trigram. The unigram distribution is the same no matter what you type; the trigram is sharp. Higher order means more context means sharper predictions.
  2. Verify one number by hand — and notice the trap. With Trigram and context the cat, the widget reports $\hat{p}(\texttt{sat} \mid \texttt{the cat}) = 0.4$, not the $2/3$ you get from counting the cat sat (twice) against the cat slept (once). The context the cat occurs five times, because two sentences end with it — the dog barked at the cat and the dog chased the cat. In both, the next token is </s>, so the count is $2/5$, and $\hat{p}(\texttt{</s>} \mid \texttt{the cat}) = 2/5$ as well. As §2.2 said, </s> is a real token the model must predict.
  3. Type the dog slept with Trigram selected. The context dog slept never occurs, so the model has no estimate — not a bad one, none. Now switch to Bigram: the shorter context slept has been seen, so an estimate reappears. Shorter contexts survive where longer ones do not, which is the observation §4.2 builds on.
  4. Watch the comparison table at the bottom. On the student read the book — every n-gram of which the corpus contains — perplexity falls steeply with order: $21.0$ (unigram) → $3.99$ (bigram) → $1.78$ (trigram). Then try the dog slept on the mat, built entirely from words the corpus knows but containing the trigram the dog slept, which it does not: the unigram still manages $25.2$, and both higher-order models give $\infty$. That inversion is the whole tension of this session in one table.
  5. Clear the context, then press Generate a few times at each order. At unigram you get word salad (the cat read a ran the about). At trigram you get clean sentences (the cat slept on the mat) — but look closely: they are corpus sentences. With only 18 examples a trigram model has essentially memorized them, so "fluent" here means overfit. That is the same coin as the sparsity in §3.3, seen from the other side.

    Keep the context as the cat instead and generation will often stop immediately. That is not a bug — $\hat{p}(\texttt{</s>} \mid \texttt{the cat}) = 0.4$, so two draws in five end the sentence right there, exactly as item 2 said they should.

To see what generation looks like when the corpus is large enough that the model is not merely reciting, here is a trigram model trained on 1.7 million words of newswire, sampled freely:

Trigram output, 1.7M-word corpus "today the price of gold per ton, while production of shoe lasts and shoe industry, the bank intervened just after it considered and rejected an imf demand to rebuild depleted european stocks, sept 30 end primary 76 cts a share."

Surprisingly grammatical, and completely incoherent. Every three-word window is plausible English, because that is precisely what the model was fit to; nothing holds the sentence together across a longer span, because the model cannot see that far. The obvious fix — raise $n$ — makes coherence better and sparsity worse, and that trade-off is a wall, not a dial. §3.3 says why.

3.2  The whole model, in code

§3 claimed the model is "one pass over the corpus and you are done." That is worth seeing literally, because it is the last time in this course a model will be this small. Here is the entire trigram estimator — the same one the widget runs:

from collections import Counter

N = 3                                    # trigram: condition on the previous N-1 = 2 words

context_counts, ngram_counts = Counter(), Counter()

for line in CORPUS:                                    # ONE pass. No epochs.
    tokens = ["<s>"] * (N - 1) + line.split() + ["</s>"]
    for i in range(N - 1, len(tokens)):
        context = tuple(tokens[i - N + 1:i])           # the two preceding words
        context_counts[context] += 1
        ngram_counts[(context, tokens[i])] += 1

def p(word, context):
    """MLE estimate. Returns None when the context was never observed."""
    context = tuple(context[-(N - 1):])
    if context_counts[context] == 0:
        return None                                    # not zero -- undefined
    return ngram_counts[(context, word)] / context_counts[context]

p("sat",   ("the", "cat"))     # 0.4   -- matches the widget, and 2/5 by hand
p("</s>", ("the", "cat"))     # 0.4   -- the two sentences that END here
p("on",    ("cat", "sat"))     # 1.0   -- certain, on two observations
p("on",    ("dog", "slept"))   # None  -- context never seen

Four details in there are the whole lesson of this section:

Try it Paste the snippet into a file with CORPUS set to the sentence list from §3.1 and check a few probabilities against the widget. Then set N = 2 and N = 4 — the code does not otherwise change, which is exactly why $n$ is the only knob an n-gram model has, and why §3.3 is about what happens when you turn it up.

3.3  Why this stops working: sparsity

The failure of counting is not that it is inaccurate. On contexts it has seen often, the MLE is excellent. The failure is that most contexts are seen rarely or never, and the problem gets exponentially worse with $n$.

Count the parameters. With a vocabulary of $V$ words, an order-$n$ model has $V^{n-1}$ possible contexts, each needing a distribution over $V$ words — so $V^n$ numbers. For a modest $V = 50{,}000$:

OrderPossible n-gramsvs. a 109-word corpus
Unigram$5 \times 10^{4}$densely observed; estimates are reliable
Bigram$2.5 \times 10^{9}$already more parameters than tokens
Trigram$1.25 \times 10^{14}$$10^{5}$ times more parameters than data
5-gram$3 \times 10^{23}$hopeless — and this is the order people actually used

So the overwhelming majority of entries in the table are zero, and they are zero because of absence of evidence, not evidence of impossibility. the dog slept is a perfectly good English trigram; our corpus simply never used it. An unsmoothed model declares it impossible.

Sparsity also degrades the estimates that do exist. In the newswire model above, the context today the yields company and bank at $0.153$ each and price at $0.077$ — probabilities that are multiples of $1/13$, because the context was seen thirteen times. There is no granularity available; the distribution is as coarse as the count is small.

Why a single zero is catastrophic It is not that one probability is slightly too low. Because the chain rule multiplies, one zero factor makes the probability of the entire sequence zero, and $\log 0 = -\infty$. A model that predicted 499 of 500 words superbly and assigned zero to one of them scores infinitely badly. Type an unseen word into the widget and watch every perplexity go to $\infty$.

4Filling the zeros

Three families of fix, in increasing order of sophistication. All of them are moving probability mass from the things you saw to the things you did not.

4.1  Smoothing: pretend you saw a bit more

Add a constant $k$ to every count before normalizing (add-one smoothing is $k=1$, also called Laplace smoothing):

$$ \hat{p}_{\text{add-}k}(x_t \mid c) = \frac{C(c, x_t) + k}{C(c) + kV} $$

The $kV$ in the denominator is doing the accounting: we added $k$ to each of $V$ possible next words, so the total went up by $kV$. Now nothing is zero.

It is also a rather bad estimator, and it is worth being clear about why. With $V$ large and most counts zero, the $kV$ term dominates the denominator, so add-one smoothing takes a great deal of mass away from the words you actually observed and spreads it thinly over an enormous number of words you did not. It is the right first idea and the wrong final answer — which is roughly its role in this course too.

4.2  Interpolation: ask a shorter question too

A better instinct than add-$k$: if you have never seen the dog slept, you have probably seen dog slept, and you have certainly seen slept. The shorter the context, the more evidence you have for it — exactly what item 3 of the widget exercise showed. So rather than trusting one order, use them all at once.

Interpolation mixes the orders into a single estimate:

$$ \hat{p}(x_t \mid x_{t-2}, x_{t-1}) = \lambda_3\, p_3(x_t \mid x_{t-2}, x_{t-1}) + \lambda_2\, p_2(x_t \mid x_{t-1}) + \lambda_1\, p_1(x_t), \qquad \sum_i \lambda_i = 1. $$

The weights $\lambda_i$ are fit on held-out data. Because the $\lambda$'s sum to one and each $p_i$ is a distribution, the mixture is a valid distribution too — and because $\lambda_1 > 0$ and the unigram is non-zero for any word in the vocabulary, no estimate is ever exactly zero. The unseen-context problem is gone, and unlike add-$k$ the mass it moves is small and tuned rather than proportional to $V$.

There is a second benefit worth noticing: even a well-observed trigram gains from being pulled slightly toward the lower orders, because a ratio built from three observations is noisy. Interpolation shrinks confident-but-thinly-evidenced estimates toward more robust ones — which is the same complaint the check-yourself question about $\hat{p} = 1$ raises in §6.

The best-known refinement is Kneser–Ney smoothing, and its central idea is a genuinely clever one worth carrying with you. When you fall back on a lower order, do not ask "how frequent is this word?" — ask "in how many distinct contexts does this word appear?" The word Francisco is common, but almost exclusively after San. A frequency-based lower-order estimate will happily predict Francisco after anything; a diversity-based one will not. Kneser–Ney remained the best-performing n-gram model for two decades.

The pattern to notice Every one of these methods is a hand-designed rule for generalizing to unseen contexts. Someone had to decide that a trigram should fall back to a bigram, and by how much. The neural approach in Handout #3 does not smooth at all — it makes generalization the model's job rather than the modeller's. That is the shift, and it is the reason a two-decade smoothing literature stopped mattering rather abruptly.

5Measuring quality

We have models. Which is better? For a language model there is a natural answer: the one that assigns higher probability to text it has not seen. Train on one set of documents, evaluate on different, unseen ones. Evaluating on the training text measures memorization, not modelling.

5.1  Perplexity, two ways

Start from the obvious thing. Take a real sentence $w_1, \ldots, w_n$ from held-out data and look at $\mathbf{P}(w_1, \ldots, w_n)$. A good model gives it high probability. Two problems: the number is inconveniently tiny, and it shrinks with length, so you could not compare across test sets. Fix both — invert it, and take the $n$-th root:

$$ \text{ppl}(w_1, \ldots, w_n) = \mathbf{P}(w_1, w_2, \ldots, w_n)^{-\frac{1}{n}} $$

The negative exponent flips small probabilities into large scores; the $1/n$ normalizes for length. Lower is better. Now expand the joint with the chain rule:

$$ \text{ppl} = \left(\prod_{t=1}^{n} \mathbf{P}(w_t \mid w_{<t})\right)^{-\frac{1}{n}} = 2^{H}, \qquad H = -\frac{1}{n}\sum_{t=1}^{n} \log_2 \mathbf{P}(w_t \mid w_{<t}). $$

These are the same quantity. The first form says inverse probability, length normalized; the second says exponentiated average negative log-probability. The second is what you compute, because it is a sum of logs rather than a product of tiny numbers — Handout #1 §1.2's point about log space, arriving where it matters.

Three things that are easy to conflate All three appear in this section, and they are not the same object:
  • Logits — the raw, unnormalized scores a network emits, one per vocabulary item. Any real number, and they do not sum to anything.
  • Probabilities — logits after softmax. In $[0,1]$, summing to 1.
  • Log-probabilities — the log of those. Always $\leq 0$, and what we actually sum in $H$.

A log-probability of $-18$ and a logit of $-18$ mean entirely different things. When a paper says "we work in log space to avoid tiny numbers like $10^{-18}$", the quantity it means is the log-probability.

Bits and nats $H$ is the loss: the thing training minimizes. Its unit depends on the base of the logarithm — base 2 gives bits, base $e$ gives nats. Perplexity exponentiates with the matching base, $2^H$ or $e^H$. Both are units of information, both are in active use, and mixing them silently is a standard way to produce a number that is wrong by a factor of $\ln 2$.

5.2  Perplexity is a branching factor

The interpretation that makes perplexity intuitive: it is the effective number of equally likely words the model is choosing among at each step — its average branching factor. Three cases pin this down. Work each out before reading the answer; they are the fastest way to internalize the metric.

A completely confused model

The model has no idea what follows any context, so it predicts a uniformly random word: $\mathbf{P}(w \mid w_{<t}) = 1/V$ for every $w$. What is its perplexity?

Answer
$$H = -\frac{1}{n}\sum_{t=1}^{n} \log_2 \frac{1}{V} = \log_2 V \quad\Longrightarrow\quad \text{ppl} = 2^{\log_2 V} = V.$$

A uniform model has perplexity exactly $V$. This is the do-nothing baseline, and it is what makes perplexity readable: a model with $V = 50{,}000$ and perplexity $100$ has narrowed 50,000 options down to an effective 100.

A mildly confused model

The model always narrows the continuation down to 5 plausible words and splits its mass evenly among them, assigning $1/5$ to the word that actually occurs and $0$ to everything outside the five. Perplexity?

Answer
$$H = -\frac{1}{n}\left(\log_2 \tfrac{1}{5} + \cdots + \log_2 \tfrac{1}{5}\right) = -\log_2 \tfrac{1}{5} = \log_2 5 \quad\Longrightarrow\quad \text{ppl} = 5.$$

Perplexity 5 means "indecisive among 5 choices" — literally, here. Note that the answer does not depend on $V$ at all: what matters is how much mass the model put on the words that actually occurred, not how many words it ruled out.

A perfect model

The model always knows exactly what comes next: $\mathbf{P}(w_t \mid w_{<t}) = 1$ for the observed word. Perplexity?

Answer
$$H = -\frac{1}{n}\sum_t \log_2 1 = 0 \quad\Longrightarrow\quad \text{ppl} = 2^0 = 1.$$

Branching factor 1 — no choice at all, and a true floor: every probability is at most 1, so every surprisal is at least 0, so perplexity is never below 1.

$V$ is a baseline, not a ceiling It is tempting to read the first and third cases as bracketing the metric between 1 and $V$. The lower bound is real; the upper one is not. $V$ is the perplexity of the uniform model — the do-nothing reference point — and a model that is confidently wrong does worse. Suppose $V = 1000$, so the uniform baseline is a perplexity of 1000 and a surprisal of $\log_2 1000 \approx 10$ bits per token. A model that confidently puts $0.999$ on one word has only $0.001$ left to spread over the other 999; if the word that actually occurs is one of those, its surprisal is at least $\log_2 1000 \approx 10$ bits and typically far more. A test set full of such tokens averages above 10 bits, i.e. perplexity above $V$. In the limit, a model that assigns the observed word probability 0 has infinite perplexity — §3.3's catastrophic zero, seen as an unbounded metric.

So read $V$ as the score to beat, not as a worst case. Being confidently wrong is worse than being ignorant — an asymmetry that comes back in §5.5.

Two true/false claims Quiz 1, sp2025
  1. A bigram language model with vocabulary size $V$ can produce any sentence of length $n$ with non-zero probability, regardless of how it was trained.  True / False?
  2. Given any corpus with vocabulary size $V$, there always exists a language model for that corpus with perplexity exactly $V$.  True / False?
Answers

1. False — and this is the whole of §3.3 in one sentence. An unsmoothed bigram model assigns probability zero to any bigram it never counted, and one zero factor zeroes the sentence. "Regardless of how it was trained" is what makes the claim false: it would be true of a smoothed bigram model, since smoothing leaves no exact zeros. Notice what the claim gets right, though — nothing about the bigram architecture forbids any sentence; it is the estimation that does.

2. True, and you have already built the witness. The uniform model $p(w \mid \text{any context}) = 1/V$ has perplexity exactly $V$ on any corpus, as the first exercise above showed — the derivation never used a single property of the text. So a perplexity-$V$ model always exists, which is precisely what makes $V$ the meaningful baseline rather than an arbitrary reference point.

The comparison table in the §3 widget computes exactly this, and it is worth being precise about what it shows. On familiar text the trigram wins by a wide margin ($1.78$ against the unigram's $21.0$). On the dog slept on the mat — all known words, one unknown trigram — the ordering reverses: the unigram scores $25.2$ and the higher-order models score $\infty$. A model that hedges everywhere cannot be caught out; a model that is confident and wrong even once is, by this metric, infinitely bad.

Two different zeros Distinguish them, because they have different remedies.
  • An unseen n-gram of known words (the dog slept): lower orders still have an estimate, so smoothing and interpolation both rescue you. This is what §4 is about.
  • An unseen word (purred): no order helps — even the unigram probability is zero, so every model in the table gives $\infty$. Try it. The remedies here are different in kind: reserve an <UNK> token for everything rare, or stop modelling whole words at all and break text into subword pieces so that nothing is ever truly unseen. Modern models take the second route, which is why tokenization gets its own treatment later in the course.

5.3  What the numbers actually look like

The canonical demonstration that order helps — trained on 38 million words of the Wall Street Journal, evaluated on a held-out 1.5 million:

ModelPerplexity
Unigram962
Bigram170
Trigram109

Two things to read off this. Each extra word of context buys a large improvement, and the gains are shrinking — $962 \to 170$ is a factor of $5.7$, $170 \to 109$ only $1.6$. That deceleration is the sparsity wall arriving: a four-gram model would help less still, and eventually not at all. Note also that the evaluation is on text held out from the counting, which is the only honest way to do it.

Perplexity on standard benchmarks has fallen more or less monotonically for thirty years, which is why the field trusts it. An oversimplified but not unfair history of the last decade of AI: lower perplexity turned out to mean more capability, further than anyone expected it to.

5.4  A bigram model, end to end

This is the exercise that has appeared, in some form, on every Quiz 1 for the last three years. It uses only §3's counting and §5.1's definition, and it is entirely doable by hand. Do it by hand.

Worked exercise — counts to perplexity Quiz 1, sp2023 / sp2024 / sp2025

Vocabulary $V = \{\texttt{BOS}, \texttt{EOS}, \texttt{The}, \texttt{dog}, \texttt{cat}, \texttt{ran}, \texttt{barked}, \texttt{jumped}, \texttt{Tianjian}\}$, where BOS and EOS mark the start and end of a sentence. Training data:

BOS who EOS
BOS The dog ran EOS
BOS The cat ran EOS
BOS The dog barked EOS
BOS Tianjian ran EOS
  1. Estimate these bigram probabilities: $P(\texttt{The}\mid\texttt{BOS})$, $P(\texttt{Tianjian}\mid\texttt{BOS})$, $P(\texttt{cat}\mid\texttt{The})$, $P(\texttt{dog}\mid\texttt{The})$, $P(\texttt{ran}\mid\texttt{dog})$, $P(\texttt{ran}\mid\texttt{cat})$, $P(\texttt{EOS}\mid\texttt{ran})$, $P(\texttt{jumped}\mid\texttt{cat})$, $P(\texttt{EOS}\mid\texttt{jumped})$. Where you get $0/0$, or a zero numerator, substitute $\epsilon = 0.01$.
  2. Compute $P(s_1)$ and $P(s_2)$ for $s_1 = $ BOS The dog ran EOS and $s_2 = $ BOS The cat jumped EOS. Assume $P(\texttt{BOS}) = 1$.
  3. Compute the perplexity of each, using $\log_2$. Count only the bigrams when computing sentence length — i.e. ignore BOS in $n$.
  4. Which sentence has the higher probability, and which the higher perplexity? Why?
Answers

1. First the unigram counts (context counts): BOS: 5, The: 3, dog: 2, cat: 1, ran: 3, Tianjian: 1, barked: 1, who: 1, jumped: 0.

n-gramCount ratioProbability
$P(\texttt{The}\mid\texttt{BOS})$3/50.6
$P(\texttt{Tianjian}\mid\texttt{BOS})$1/50.2
$P(\texttt{cat}\mid\texttt{The})$1/30.333
$P(\texttt{dog}\mid\texttt{The})$2/30.667
$P(\texttt{ran}\mid\texttt{dog})$1/20.5
$P(\texttt{ran}\mid\texttt{cat})$1/11.0
$P(\texttt{EOS}\mid\texttt{ran})$3/31.0
$P(\texttt{jumped}\mid\texttt{cat})$0/1→ 0.01
$P(\texttt{EOS}\mid\texttt{jumped})$0/0→ 0.01

Note the two different failures in the last two rows. $P(\texttt{jumped}\mid\texttt{cat}) = 0/1$ is a well-defined zero: we saw cat, and jumped never followed it. $P(\texttt{EOS}\mid\texttt{jumped}) = 0/0$ is not even defined: we never saw jumped at all, so there is no distribution to speak of. This is §5.2's "two different zeros" showing up in arithmetic — and the $\epsilon$ convention is the crudest possible smoothing, papering over both.

2. Multiply along the chain rule:

$$ P(s_1) = \tfrac{3}{5}\cdot\tfrac{2}{3}\cdot\tfrac{1}{2}\cdot\tfrac{3}{3} = 0.2 $$ $$ P(s_2) = \tfrac{3}{5}\cdot\tfrac{1}{3}\cdot 0.01 \cdot 0.01 = 2\times 10^{-5} $$

3. With $n = 4$ bigrams each:

$$ H(s_1) = -\tfrac{1}{4}\left[\log_2\tfrac{3}{5} + \log_2\tfrac{2}{3} + \log_2\tfrac{1}{2} + \log_2 1\right] = 0.580 \;\Rightarrow\; \text{ppl}(s_1) = 2^{0.580} = \mathbf{1.50} $$ $$ H(s_2) = -\tfrac{1}{4}\left[\log_2\tfrac{3}{5} + \log_2\tfrac{1}{3} + \log_2 0.01 + \log_2 0.01\right] = 3.902 \;\Rightarrow\; \text{ppl}(s_2) = 2^{3.902} = \mathbf{14.95} $$

Sanity check without a calculator: $\text{ppl} = P^{-1/n}$ from §5.1, so $\text{ppl}(s_1) = 0.2^{-1/4} \approx 1.50$ and $\text{ppl}(s_2) = (2\times10^{-5})^{-1/4} \approx 14.95$. The two routes must agree — if they do not, you have made an arithmetic slip.

4. $s_1$ has the higher probability and $s_2$ the higher perplexity, and these are the same fact stated twice: perplexity is a decreasing function of probability. $s_1$ is built entirely from bigrams the corpus observed, so every factor is large. $s_2$ contains two the corpus never saw, each contributing $\epsilon = 0.01$, and those two factors dominate. Perplexity $1.50$ means the model was choosing among about one and a half options per word; $14.95$ means about fifteen.

And in code? One line — torch.exp(F.cross_entropy(logits, targets)) — plus three ways to get it wrong that are worth knowing before you write a training loop. That belongs with the PyTorch mechanics in Handout #5, not here.

5.5  What perplexity does not tell you

Perplexity is the field's workhorse and it is genuinely load-bearing. It is also narrower than it looks, in ways that matter for reading papers critically.

Where this goes next We now have a target and a way to score it: fit the conditionals $p_\theta(x_t \mid x_{<t})$, and measure the fit with perplexity. What we do not have is a way to build $f_\theta$ that generalizes — every fix in §4 was a hand-designed rule. Handout #3 reframes the whole problem as function fitting and introduces the machinery that makes generalization the model's job.

6Check yourself

Q1. The chain rule is exact. The Markov assumption is not. If you had unlimited data and unlimited storage, would a trigram model be a perfect language model?

Answer
No. Unlimited data removes the sparsity problem — every trigram context would be densely observed and its estimate accurate. It does not remove the Markov assumption itself, which is a claim about the language: that the next word is conditionally independent of everything before the previous two, given those two. That claim is false about English, and no amount of data makes it true. The computer … crashed sentence in §1.3 is a counterexample you can hold in your head. Separating "we lack data" from "our model is wrong" is a habit worth keeping.

Q2. Using the corpus in §3.1, compute $\hat{p}(\texttt{on} \mid \texttt{cat sat})$ and $\hat{p}(\texttt{the} \mid \texttt{sat on})$ as trigram MLEs, by hand.

Answer

cat sat occurs twice (the cat sat on the mat, the cat sat on the floor), and in both the next word is on. So $\hat{p}(\texttt{on} \mid \texttt{cat sat}) = 2/2 = 1$.

sat on occurs three times (twice after cat, once in the dog sat on the rug), and every time the next word is the. So $\hat{p}(\texttt{the} \mid \texttt{sat on}) = 3/3 = 1$.

Both are exactly 1, which should bother you: the model is certain on the evidence of two or three observations. Maximum likelihood is confidently wrong on small counts, and that — not just the zeros — is what smoothing addresses.

Q3. A model has vocabulary $V = 10{,}000$ and perplexity $80$ on a test set. Roughly what has it learned, and what is its cross-entropy loss in bits?

Answer

Perplexity $80$ against a uniform baseline of $V = 10{,}000$ means the model has narrowed ten thousand options down to an effective branching factor of eighty — it has captured most, but nowhere near all, of the structure.

Since $\text{ppl} = 2^H$, the loss is $H = \log_2 80 \approx 6.32$ bits per word. (In nats, $\ln 80 \approx 4.38$ — the same model, a different unit. Always check the base.)

Q4. §5.1 calls $H$ a cross-entropy. But cross-entropy is $\text{CE}(q, p) = -\sum_x q(x) \log p(x)$, an expectation under the true distribution $q$ — and we never have $q$. In what sense is $H$ a cross-entropy?

Answer

In the sense of a Monte Carlo estimate. We cannot evaluate $-\mathbb{E}_{x \sim q}[\log p_\theta(x)]$ because $q$ — the true distribution of language — is unknown. But the held-out test set is a sample drawn from $q$. So replace the expectation by the average over that sample:

$$ -\mathbb{E}_{x \sim q}\bigl[\log p_\theta(x)\bigr] \;\approx\; -\frac{1}{n}\sum_{t=1}^{n} \log p_\theta(w_t \mid w_{<t}) \;=\; H, $$

and by the law of large numbers this converges to the true cross-entropy as $n \to \infty$. So $H$ is an empirical estimate of the cross-entropy between the model and language itself. Two consequences: your test set must be a fair sample of the distribution you care about, and it must be large enough for the average to have converged — which is why perplexity on a few hundred tokens is not worth reporting.

Q5. Would you expect a longer sentence to have higher perplexity? Higher probability?

Answer

Probability: lower, always. The joint is a product of factors each below 1, so appending a word can only shrink it. This is exactly why raw probability is useless for comparing texts, and why perplexity normalizes by $n$.

Perplexity: typically lower, i.e. longer is easier. Perplexity is already length-normalized, so length as such does not push it either way. But the early tokens are the hard ones: with little or no context the model is close to uniform and its predictions are poor. As context accumulates, predictions sharpen. A long sentence averages those cheap later tokens against the expensive first few, so the mean improves. A very short sentence is nearly all first-few.

Q6. Model A has perplexity 100 on a test set. Model B has perplexity 20 on a different test set. Which is the better language model?

Answer
Unanswerable as stated. Perplexity depends on the test distribution — a model evaluated on formulaic newswire will look far better than the same model on conversational text — and on the tokenization and vocabulary, since these change both what counts as a "word" and the baseline $V$. Comparison requires the same corpus and the same tokenizer, which is why papers must report both, and why you should be suspicious when they do not.

Q7. §5.3's WSJ numbers go $962 \to 170 \to 109$ as order increases. Extrapolate: what would you predict for a four-gram model, and why should you not trust the extrapolation?

Answer
The improvements are decelerating sharply — a factor of $5.7$, then $1.6$ — so a four-gram might reach perhaps $95$–$105$, and a five-gram less again. You should not trust it because the mechanism that produces the deceleration is sparsity, and sparsity worsens exponentially in the order: at some point the additional context is so rarely observed that the higher-order estimates are noise, and measured perplexity gets worse. Where that turn happens depends on corpus size, not on the trend line. This is the same "more of the same input stops paying" pattern you will meet again in scaling laws.

Q8. In the §3.1 widget, the dog slept on the mat gives the unigram model a perplexity of $25.2$ and both higher-order models $\infty$. Does that make the unigram better? And why does the cat purred behave differently?

Answer

No. It shows that unsmoothed perplexity is determined entirely by its single worst prediction, since one zero factor makes the log $-\infty$ no matter how good the other five predictions were. The trigram is the better model of every context it has seen and unusable on the one it has not; the unigram is mediocre everywhere and therefore never catastrophic. The conclusion is not "prefer unigrams" but "never evaluate an unsmoothed model" — smoothing is a precondition for measurement, not only for performance.

the cat purred is a different failure. There the offending token is an unknown word, so its probability is zero at every order — the unigram cannot rescue it either, so every row gives $\infty$. Interpolation addresses unseen contexts; it does nothing for unseen vocabulary, because there is no order low enough to have seen the word. That needs <UNK> handling or subword tokenization instead.

7Optional further reading

Strictly optional — nothing here is assumed in class or on a quiz.