LABS · 03  /  SAMPLING

The Dice Loader.

A language model doesn't pick the next word — it rolls for it, from a probability over every token. Three dials load those dice: temperature sharpens or flattens the odds, top-k keeps only the best few, top-p keeps just enough to cover the mass. Drive them and watch the bars move.

THE GIST · 20 SECONDS

The model emits a logit for every token; a softmax turns them into probabilities that sum to 1. Then it samples. Temperature divides the logits — low = sharp & safe, high = flat & wild. Top-k keeps the k highest and zeroes the rest. Top-p keeps the smallest set covering probability p. Whatever survives is renormalized back to 1 and rolled.

  • Softmaxlogits → probabilities
  • Temperaturesharpen ↔ flatten
  • Top-kkeep k best tokens
  • Top-pkeep p of the mass
Prompt: “The cat sat on the ___”

Drag the dials on the right. Coloured bars survive the filters and get renormalized; faded bars are cut. Hit Sample to roll.

UNDER THE HOOD

What you just played, written down

Every dial reshapes the same softmax distribution before the roll. Together they trade one thing against another: coherence versus creativity.

The three dials — what each does

  1. Softmax first. Logits become probabilities: p_i = e^(z_i / T) / Σ e^(z_j / T). That divisor T is temperature.
  2. Temperature = sharpness. T < 1 concentrates mass on the top tokens (safe, repetitive); T > 1 spreads it out (diverse, risky); T → 0 is greedy.
  3. Top-k = a hard cap. Keep the k most likely tokens, zero the rest, renormalize. Fixed count, ignores the distribution's shape.
  4. Top-p = an adaptive cap. Keep the smallest set whose probabilities sum to p, renormalize. Few survivors when confident, many when unsure.
WHY RENORMALIZE?

Once you zero out the cut tokens, the survivors no longer sum to 1 — you can't sample from that. Dividing each survivor by their total restores a valid distribution over just the tokens you kept.

The whole thing in code

import numpy as np

def sample(logits, temp=1.0, k=None, p=None):
    z = logits / temp                       # temperature
    probs = np.exp(z - z.max())
    probs /= probs.sum()                    # softmax

    order = probs.argsort()[::-1]           # high → low
    keep = set()
    cum = 0.0
    for rank, i in enumerate(order):
        if k is not None and rank >= k:     # top-k cap
            break
        keep.add(i); cum += probs[i]
        if p is not None and cum >= p:      # top-p cap
            break

    masked = np.array([probs[i] if i in keep else 0
                       for i in range(len(probs))])
    masked /= masked.sum()                  # renormalize
    return np.random.choice(len(masked), p=masked)
LOW TEMP / TIGHT psafefocused, repetitive
HIGH TEMP / LOOSE pcreativediverse, risky
TOP-P USUALLY WINS

Because top-p's survivor count adapts to each distribution, it's the common default. Top-k is simpler and caps the candidates hard. They stack — apply top-k, then top-p — on top of temperature.

⚠ Greedy isn't always best

Temperature 0 (always the top token) sounds "safe" but produces flat, looping text and can miss better continuations that start with a slightly lower-probability word. A little randomness usually reads better.

↔ Other decoders

Greedy takes the argmax; beam search keeps several partial sequences and maximizes total likelihood (great for translation, dull for chat); sampling with these dials is the norm for open-ended text.

★ Where it matters

The temperature and top_p parameters in every LLM API are exactly these dials. Tuning them is how you make a model deterministic for code or playful for brainstorming.

QUICK CHECK

Did it stick?

FAQ

Sampling, answered

How does a model pick the next token?

It outputs a logit per token; a softmax turns those into probabilities summing to 1; then it samples. Temperature, top-k, and top-p shape that distribution before the roll.

What does temperature do?

It divides the logits. Low (<1) sharpens the distribution toward the top tokens (safe, repetitive); high (>1) flattens it (diverse, risky); near 0 it's greedy.

What is top-k?

Keep only the k most likely tokens, zero the rest, and renormalize. A hard cap on how far into the tail the model can reach — but fixed regardless of the distribution's shape.

What is top-p (nucleus)?

Keep the smallest set of top tokens whose probabilities reach p, then renormalize. The survivor count adapts — few when the model is confident, many when it's unsure.

top-k or top-p?

Top-p adapts to each distribution and is usually the better default; top-k is simpler. They combine, with temperature, to trade coherence against creativity.

RESULT

Next → every temperature and top_p value in an LLM API is one of these dials. You now know exactly what they do to the dice.

Finished this one? 0 / 12 Labs done

Explore the topic

See this alongside everything else on the same subject — handbooks, system designs, challenges and tools, in one place.

More Labs