Text Generation & Sampling
A language model only ever predicts the next token. Temperature, top-k and top-p decide how that prediction becomes a choice. Adjust them and generate text one token at a time.
The next-token scores here are hand-crafted and illustrative: each prompt has a small tree of a dozen or so likely continuations instead of a real model's full vocabulary. The softmax, temperature, top-k, top-p, sampling and entropy calculations are all real.
Next-token distribution
Bar length is the probability after temperature. Hatched bars are removed by top-k or top-p; the right column is the renormalised probability actually used for sampling.
Decoding settings
Entropy
How to use this visualizer
- 1Choose a prompt. "The capital of France is" is confident; "My favourite colour is" is open-ended.
- 2Drag the temperature slider and watch the bars sharpen or flatten, and the orange dot move along the entropy curve.
- 3Turn on top-k or top-p: hatched bars are removed and the remaining probabilities are rescaled to sum to 1.
- 4Press Sample next token to draw a token using the seeded random number u, or Greedy next token to take the most likely one.
- 5Keep going until the branch ends. Use Undo to step back, or change the seed and reset to get a different sample.
How text generation works
Given the text so far, a language model produces one logit (a raw score) for every token in its vocabulary. Softmax turns the logits into probabilities. A decoding strategy then picks one token, appends it to the text, and runs the model again. Everything a chatbot writes is produced this way, one token at a time.
Always taking the most likely token (greedy decoding) tends to produce safe, repetitive text. Sampling adds variety, but sampling from the full distribution occasionally picks a very unlikely token and derails the sentence. Temperature, top-k and top-p are the standard dials for balancing the two.
One token at a time
Logits become probabilities
Entropy measures uncertainty
Seeds make sampling repeatable
Key formulas
Softmax with temperature
pᵢ = exp(zᵢ / T) / Σj exp(zj / T)
- zᵢ
- logit of token i
- T
- temperature (T > 0); T = 1 leaves the model distribution unchanged
Top-p (nucleus) set
Vp = smallest set of most likely tokens with Σi ∈ Vp pᵢ ≥ p, then pᵢ′ = pᵢ / Σj ∈ Vp pj
Entropy
H(p) = −Σi pᵢ log₂ pᵢ
- H = 0
- one token has probability 1
- H = log₂ n
- all n tokens are equally likely
| Strategy | How it works | Effect |
|---|---|---|
| Greedy | Always take the most likely token | Deterministic; can get repetitive or bland |
| Temperature | Divide logits by T before softmax | T < 1 sharper, T > 1 flatter, T → 0 is greedy |
| Top-k | Keep only the k most likely tokens | Removes the long tail, but k is the same for confident and uncertain steps |
| Top-p (nucleus) | Keep the smallest set whose probability sums to p | Adapts: few tokens when confident, many when uncertain |
Code
import numpy as np
def sample_next(logits, temperature=1.0, top_k=0, top_p=1.0, rng=np.random.default_rng(42)):
if temperature == 0:
return int(np.argmax(logits)) # greedy
z = np.asarray(logits) / temperature
probs = np.exp(z - z.max())
probs /= probs.sum()
order = np.argsort(-probs)
keep = np.ones_like(probs, dtype=bool)
if top_k > 0:
keep[order[top_k:]] = False
if top_p < 1.0:
cum = np.cumsum(probs[order] * keep[order]) / probs[keep].sum()
cutoff = np.searchsorted(cum, top_p) + 1 # smallest set reaching p
keep[order[cutoff:]] = False
probs = np.where(keep, probs, 0)
probs /= probs.sum()
return int(rng.choice(len(probs), p=probs))Practice problems
Problem 1: Temperature by hand
Three tokens have logits (2, 1, 0). Compute their probabilities at T = 1 and at T = 0.5.
Show solutionHide solution
T = 1: e² = 7.389, e¹ = 2.718, e⁰ = 1, sum = 11.107
p = (0.665, 0.245, 0.090)
T = 0.5: logits become (4, 2, 0). e⁴ = 54.598, e² = 7.389, e⁰ = 1, sum = 62.987
p = (0.867, 0.117, 0.016)
Halving the temperature doubled the gaps between logits, so the top token became much more likely.
Problem 2: Top-k versus top-p
Five tokens have probabilities (0.50, 0.20, 0.15, 0.10, 0.05). Which tokens survive top-p with p = 0.8, and what are their renormalised probabilities? Compare with top-k, k = 2.
Show solutionHide solution
Cumulative sums: 0.50, 0.70, 0.85. The third token is the first to reach 0.8, so three tokens are kept.
Kept mass = 0.85. Renormalised: 0.50/0.85, 0.20/0.85, 0.15/0.85
top-p: (0.588, 0.235, 0.176)
Top-k with k = 2 keeps the first two: mass 0.70, so 0.50/0.70 and 0.20/0.70.
top-k: (0.714, 0.286)
Discussion
Questions, ideas or a different approach? Join the conversation.