← All tutorials

Softmax, Temperature and Decoding

On this page

1 Softmax turns scores into probabilities 2 Greedy and beam search look for the likeliest reply 3 The likeliest text loops 4 Sampling draws words at random 5 Temperature sharpens or flattens the distribution 6 Top-k, top-p and min-p drop the unlikely words 7 Each job needs its own decoding method 8 How decoding runs in practice 9 References

A language model writes a reply one word at a time. At every step a decoder network like the one in The Transformer Block scores every word, or word piece called a token, in its vocabulary. How text is cut into tokens is in Tokenizers. Decoding is the rule that turns those scores into the one word written next. Softmax first turns the scores into probabilities. The rule then either chooses the likeliest words, which gives the same reply every time, or draws a word at random, which is why the same question can get two different answers. It runs once for every generated token, and only when the model writes text. Training on fixed text never decodes, because the loss reads the true next token from the data. The exception is RL fine-tuning in Aligning Language Models with RL, where the model samples its own replies during training.

repetition penaltyoptional, any methodscoressoftmaxprobabilitiesgreedytake thetop wordbeam searchkeep the bestfew repliessampleat randomtemperaturereshape the probabilitiescutdrop the unlikely wordsdrawa word
Figure 1. One pass per token. Temperature and the cut belong to sampling.

Every example uses one toy step. After the cat sat on the, a model scores ten candidate words.

1 Softmax turns scores into probabilities

Softmax is the first step of every decoding method. The raw scores are logits, any real numbers, and they do not add to anything. Softmax makes them a probability distribution, positive numbers that add to 1, while keeping their order.

Each word’s chance is its exponentiated logit as a share of the total over all words.

pi = exp(zi)Σj exp(zj)
zi is the logit of word i. pi is its probability. The top, e raised to the logit, is always positive, so even a negative logit gets a share. It also grows fast, and each extra 1 of logit multiplies the term by about 2.7. Σj adds the same term over every word j in the vocabulary. Dividing by that total makes the pi add to 1. Every word is divided by the same total, so the order of the logits is kept. Adding one number to every logit multiplies top and bottom by the same factor, so it changes nothing.
logitprobabilitymat0.43floor0.19sofa0.13bed0.10roof0.06chair0.04moon0.02piano0.010Tuesday0.006of0.0040
Figure 2. Negative logits still get a small positive share. The order never changes.

A logit like 1000 makes the exponential overflow to infinity, and infinity over infinity gives NaN, not a number. Subtracting the largest logit first divides the top and bottom by the same number, so every pi stays the same (Goodfellow et al. 2016, section 4.1), and the biggest term becomes 1.

The same softmax picks the weights in Attention and feeds the loss in Cross-Entropy Loss.

2 Greedy and beam search look for the likeliest reply

Greedy decoding and beam search both look for the likeliest reply, with no randomness. Greedy decoding writes the likeliest word and moves on, so a likely first word can force unlikely words after it. Beam search keeps the best few partial replies at every step, its beam width, and keeps the best reply at the end.

The beam width sets how many partial replies are kept at each step. In Hugging Face Transformers, a Python library for running models, it is num_beams, default 1, which is greedy. A wider beam compares more replies at that many times the cost, and a narrower one compares fewer; at the extreme, a beam that kept every possible reply would find the reply with the highest score, but there are far too many to keep. Even width 16 still loops on open-ended text (Figure 14).
step 1 of 5

Figure 3. Greedy against beam search with width 2 on a small reply tree.

Greedy picks the top word at each step. Beam search keeps the two best partial replies by summed log probability.

xt = argmaxi pi
s = Σt log P(xt | x<t)
A whole reply’s chance is the product of its word chances.
xt is the word written at step t. argmaxi returns the word i whose pi is largest, not the value itself. Greedy keeps only that word, so after sat it never looks at is.
s is a reply’s score, and P(xt | x<t) is the chance of xt given the words before it. A sum of logs is the log of the product, so ranking by s ranks whole replies by their chance. Each chance is at most 1, so each log is at most 0 and every word lowers s. Logs also keep long products from rounding to 0.

Every word adds a negative log, so the plain sum s favors short replies. The replies in Figure 3 all have two words, so it never shows this bias. To remove it, beam search divides the score by a power of the length.

The corrected score is the summed log probability divided by the reply length raised to a power.

snorm = sLα
s is the summed log probability, and L is the reply length in words. α (alpha) sets how hard to correct. Dividing a negative score by a larger number pulls it toward 0, so long replies lose less. With α = 0 the bottom is 1 and nothing changes. With α = 1 the score is the average log probability per word. Google’s translation system found 0.6 to 0.7 usually worked best for this form.
α is length_penalty in Hugging Face, default 1.0, so its beam search divides by the generated length unless told otherwise. A larger α favors longer replies, and a smaller one favors shorter replies.
summed ss / L, α = 1−1.0−1.8−0.50−0.302 words6 words0 is best0 is bestshort reply winslong reply wins
Figure 4. The sum favors the short reply, the average the long one.

Speech recognition uses the same two methods over alignments in CTC Loss.

3 The likeliest text loops

For open-ended writing, the likeliest reply turns out to loop. Holtzman et al. (2020), the paper that introduced nucleus sampling, gave GPT-2 Large, a 774-million-parameter language model from 2019, the opening of a story and let beam search continue it.

The openingIn a shocking finding, scientist discovered a herd of unicorns living in a remote, previously unexplored valley, in the Andes Mountains. Even more surprising to the researchers was the fact that the unicorns spoke perfect English.
Beam search, width 32… the Universidad Nacional Autónoma de México (UNAM) and the Universidad Nacional Autónoma de México (UNAM/Universidad Nacional Autónoma de México/Universidad Nacional Autónoma de México/Universidad Nacional Autónoma de México/Universidad Nacional Autónoma de…
Figure 5. Beam search loops on one name. From the nucleus sampling paper’s Figure 1.

Repetition feeds itself, because each repeat makes the next one likelier.

A repetition penalty from CTRL (Keskar et al. 2019), a 1.63-billion-parameter Salesforce language model, makes a repeat less likely by lowering the logit of every word already written.

A used word’s logit is divided by the penalty before the softmax.

zi ← ziθ
← means the logit is replaced by the new value. θ (theta) is the penalty, a number above 1. CTRL used about 1.2 with greedy decoding. Dividing a positive logit by θ moves it toward 0, which lowers that word’s share after the softmax, and a larger θ lowers it more. Unused words keep their logits, so they gain the share the used word loses. Dividing a negative logit would raise it. Hugging Face multiplies a negative logit by θ instead, so a used word always loses ground.
θ is repetition_penalty in Hugging Face, default 1.0, which is no penalty. A larger θ pushes harder away from used words, a smaller one pushes less, and a value below 1 would reward repeats.
beforeafter, θ = 1.2mat0.43 to 0.35floor0.19 to 0.22sofa0.13 to 0.15
Figure 6. With mat already written, its share drops and the other words gain.

The penalty lowers every used word alike, so it also lowers words that should repeat, such as a name or the.

4 Sampling draws words at random

Sampling draws the next word at random in proportion to its probability, so the output varies from run to run. Pure sampling draws each word with chance pi, straight from the softmax. The catch is the tail, the many words that each have a small chance. In the toy, moon, piano, Tuesday and of make no sense after the cat sat on the. These unlikely words hold about 4% together.

1002050100words in the replychance of nounlikely word0.420.120.014
Figure 7. With a 4% risk per word, a reply of L words has no unlikely word with chance 0.958L.

A small risk per word becomes a near certainty over a long reply, and one unlikely word pulls the words after it off topic.

Pure sampling, same openingThey were cattle called Bolivian Cavalleros; they live in a remote desert uninterrupted by town, and they speak huge, beautiful, paradisiacal Bolivian linguistic thing.
Figure 8. Fluent phrases, nonsense as a whole. From the nucleus sampling paper’s Figure 1.

5 Temperature sharpens or flattens the distribution

Temperature, τ, is one number that sets how random sampling is, by rescaling every logit.

Each logit is divided by τ before the softmax.

pi = exp(ziτ)Σj exp(zjτ)
τ (tau), the temperature, is a positive number, and τ = 1 gives the plain softmax of Section 1. The ratio of two words’ chances is e raised to the gap between their logits, and dividing by τ divides that gap too. Below 1 the gaps grow and the distribution sharpens. Above 1 they shrink and it flattens. The word order never changes.
τ → 0 ⇒ pmax → 1
→ means approaches and ⇒ means so. pmax is the top word’s probability. As τ nears 0, the gaps below the top logit become huge, so the top word takes all the probability and sampling is greedy.
τ is temperature in Hugging Face, default 1.0. Raising it flattens the distribution and lowering it sharpens it. Near 0, sampling acts like greedy. As τ grows, every gap between logits shrinks toward 0, so every word’s chance nears one over the number of words.
τ = 0.5mat0.2%unlikely wordsτ = 1mat4%unlikely wordsτ = 2mat15%unlikely words
Figure 9. Same ten logits. The unlikely words’ share, marked over each brace, grows with τ.

Neither a low nor a high τ solves the tail problem. A low τ drifts back toward greedy, and a high one gives the tail more probability. The same temperature softens a teacher’s probabilities in Knowledge Distillation, which writes it T, and sets how sharply similarities become probabilities in InfoNCE and CLIP. The Transformer Block has its own temperature slider.

6 Top-k, top-p and min-p drop the unlikely words

A cut, also called truncation, keeps only the likeliest words, sets the chance of the rest to 0 and rescales the kept ones before the draw. The simplest cut keeps a fixed number of words, and the cuts after it fix its weak spot.

6.1 Top-k keeps a fixed count

Top-k keeps a fixed number of the likeliest words at every step.

Top-k keeps a word only if it is among the k likeliest.

keep i if rank(i) ≤ k
rank(i) is the word’s place when the words are sorted from likeliest down, so the top word has rank 1. k is the number of words kept, such as 40. The count is the same at every step, whatever the distribution looks like. A larger k lets more of the tail in, and k = 1 is greedy.
k is top_k in Hugging Face, default 50. A smaller k drops good words at flat steps, and k = V, the vocabulary size, keeps every word, which is pure sampling. The nucleus sampling paper tests 40 and 640, and 10 is used for stories.

One fixed k cannot fit every step, because some steps have many good words and others have one. The nucleus sampling paper says it with probability mass, meaning total probability: “Flat distributions lead to many moderately probable tokens, while peaked distributions concentrate most probability mass into just a few tokens.”

1 She said, “I never … Bar chart of the next word after She said I never. The top words thought, knew, had, saw, said and more each hold a few percent.
2 I ate the pizza while it was still … Bar chart of the next word after I ate the pizza while it was still. Hot holds most of the probability, with cooling, warm and on far behind.
Figure 10. 1 At a flat step a small k drops good words. 2 At a peaked step a large k keeps unlikely words. Cropped from the nucleus sampling paper’s Figure 5.

6.2 Top-p keeps a fixed share

Top-p, also called nucleus sampling, fixes this by keeping a share of the total probability instead of a count.

Top-p keeps the fewest top words whose chances add up to a set share of the total probability.

Σkept pi ≥ ptop
ptop is the share of the total probability to keep, such as 0.9. Walk down the sorted words adding their probabilities and stop at the first word where the total reaches it. When the distribution is peaked one or two words reach the share, and when it is flat many words are needed. A larger ptop keeps more of the tail. The kept words are the nucleus.
ptop is top_p in Hugging Face, default 1.0, which keeps every word. A smaller ptop keeps a smaller nucleus and safer text, and near 0 only the top word stays, which is greedy. The nucleus sampling paper uses 0.95.

Top-p keeps many words when the distribution is flat and few when it is peaked. The captioner in From BLIP to the Q-Former uses top-p at 90%.

6.3 Min-p keeps words above a moving bar

Min-p (Nguyen et al. 2025) adapts in a different way. It keeps the words above a threshold, the bar, that moves with the top word’s probability.

Min-p keeps every word whose chance is at least a set fraction of the top word’s.

keep i if pi ≥ pbase · pmax
pbase is that fraction, such as 0.1. The bar is pbase times the top word’s pmax, so it rises when the model is confident and falls when the distribution is flat. A larger pbase cuts more of the tail.
pbase is min_p in Hugging Face, unset by default. A smaller pbase lowers the bar and keeps more words. 0 keeps every word, which is pure sampling, and 1 keeps only words tied with the top, which is greedy. The docs suggest 0.01 to 0.2. The min-p paper suggests 0.05 to 0.1, and 0.5 to 0.7 for very high τ.
Min-p at three settings1τ = 0.5pbase = 0.1keeps 2unlikely2τ = 2pbase = 0.1keeps 10unlikely3τ = 2pbase = 0.5keeps 3unlikely
Figure 11. 1 A confident step raises the bar. 2 At a high τ a low pbase lets every word in. 3 The paper’s higher pbase keeps the top 3.

All three cuts then renormalize, rescaling the kept words so they add to 1 again.

After any cut, each kept word’s chance is rescaled so the kept words add to 1.

p′i = piΣkept pj
p′ (p prime) is the new distribution. Σkept adds over the kept words only. That total is below 1 after a cut, so dividing by it scales the kept words up until they add to 1 again. Every kept word is divided by the same number, so the kept words keep their ratios. A cut word gets a new probability of 0 and is never drawn.

6.4 The order of the steps

Hugging Face, vLLM (a model-serving library) and the min-p paper apply temperature before the cut, while llama.cpp (a C/C++ library for running models locally) applies it last by default.

Hugging Facepenaltytemperature1cutdrawllama.cpp, by defaultpenaltycuttemperature2draw
Figure 12. 1 Temperature before the cut changes which words survive. 2 Temperature after the cut only reshapes the kept words.
sharperflatter

Figure 13. Bars show the renormalized p′. Top-k keeps a fixed count, top-p a fixed share of the probability.

7 Each job needs its own decoding method

A task with one right answer wants the likeliest reply, and open-ended writing wants text that is varied but stays on topic. The nucleus sampling paper measured both sides. It wrote 5,000 passages of up to 200 tokens with each method, each from a short opening of web text the model never trained on. Perplexity per token is how surprised the model is by the text, where higher means less predictable. Loops is the share of passages that end stuck repeating a phrase of two or more tokens at least three times.

perplexityloopshuman levelhuman text12.380.28%greedy1.5073.66%beam, width 161.4828.94%pure sampling22.730.22%top-k, k = 406.880.78%top-p, 95%13.130.36%
Figure 14. Of the rows shown, only top-p sits near human on both. From the nucleus sampling paper, Table 1.

8 How decoding runs in practice

8.1 The generate loop

In a real system the decoding rule sits inside a generate loop. Each pass runs the model on the text so far, takes the logits at the last position, applies the penalty, temperature and cut, picks one token, appends it and repeats until an end-of-text token or a length limit. A key-value cache stores the attention keys and values of every past token, so each pass computes only the new token instead of the whole text.

8.2 Code for each method

The toy sampling step in NumPy, from the ten logits to one drawn word.

import numpy as np

# the ten toy logits, 2.0 down to -2.6
z = np.array([20, 12, 8, 5, 1, -3, -10, -18, -22, -26]) / 10
rng = np.random.default_rng(0)

def softmax(z, tau=1.0):
    e = np.exp((z - z.max()) / tau)  # max first: no overflow
    return e / e.sum()

def top_p(p, p_top=0.9):
    order = np.argsort(p)[::-1]  # likeliest first
    n_keep = np.searchsorted(np.cumsum(p[order]), p_top) + 1
    p_prime = np.zeros_like(p)
    p_prime[order[:n_keep]] = p[order[:n_keep]]
    return p_prime / p_prime.sum()

def top_k(p, k=3):
    p_prime = np.where(p >= np.sort(p)[-k], p, 0)  # k likeliest
    return p_prime / p_prime.sum()

p = softmax(z, tau=1.0)
p_prime = top_p(p)
word_id = rng.choice(len(p), p=p_prime)
# prints [0.43 0.19 0.13] 5 3
print(p[:3].round(2), np.count_nonzero(p_prime), np.count_nonzero(top_k(p)))
  1. 1The ten toy logits z of Figure 2 and a seeded random generator.
  2. 2Softmax with temperature, the eq-card in Section 5, with the largest logit subtracted first.
  3. 3Top-p sorts, keeps the nucleus and renormalizes into p′, and top-k keeps the k likeliest, the eq-cards in Sections 6.1 to 6.3.
  4. 4Draws one word from p′, the default state of Figure 13.

Greedy and beam search on the tree of Figure 3, where width 1 is greedy.

from math import log

TREE = {(): {"sat": 0.5, "is": 0.4, "ran": 0.1},
        ("sat",): {"on": 0.4, "down": 0.3, "there": 0.3},
        ("is",): {"sleeping": 0.9, "here": 0.05, "fat": 0.05},
        ("ran",): {"away": 0.8, "off": 0.2}}

def beam_search(width, depth):
    beams = [(0.0, ())]  # (s, prefix)
    for _ in range(depth):
        pool = []
        for s, prefix in beams:
            for word, P in TREE[prefix].items():
                pool.append((s + log(P), prefix + (word,)))
        beams = sorted(pool, reverse=True)[:width]
    return beams[0]

s, words = beam_search(width=1, depth=2)
print(round(s, 2), words)  # -1.61 ('sat', 'on')
s, words = beam_search(width=2, depth=2)
print(round(s, 2), words)  # -1.02 ('is', 'sleeping')
  1. 1The reply tree of Figure 3, each prefix mapped to its next-word chances.
  2. 2Grows every kept reply by every next word and adds log P to s, line 2 of the eq-card in Section 2.
  3. 3Keeps the best replies up to the width, steps 3 to 5 of Figure 3.
  4. 4Width 1 gives greedy’s reply and width 2 finds the better one.

A hand-written PyTorch generate loop with temperature and a random draw is in The Transformer Block.

Hugging Face’s model.generate runs the loop of Section 8.1 with a key-value cache, and each call below is one method.

from functools import partial
from transformers import AutoModelForCausalLM, AutoTokenizer

tok = AutoTokenizer.from_pretrained("gpt2")
model = AutoModelForCausalLM.from_pretrained("gpt2")
inputs = tok("The cat sat on the", return_tensors="pt")
gen = partial(model.generate, **inputs, max_new_tokens=40)

greedy = gen()
beam = gen(num_beams=4)
sampled = gen(do_sample=True, temperature=0.7, top_k=0, top_p=0.9)
no_loops = gen(repetition_penalty=1.2)  # greedy, CTRL penalty
print(tok.decode(sampled[0], skip_special_tokens=True))
  1. 1Loads the model and fixes the prompt and a 40-token limit.
  2. 2Greedy, the argmax line of the Section 2 eq-card.
  3. 3Beam search with width 4, as in Figure 3.
  4. 4Sampling with temperature and top-p alone, Section 5 and Section 6.2.
  5. 5Greedy with the repetition penalty of Section 3.

8.3 What each method costs

MethodReadsKeepsWork per token
Greedylast logitsnothing extraone argmax over V
Beam search, width Blogits of B repliesB replies, their scores, the cache reshuffled to matchB rows per model pass, the top 2B of B × V, the length division at the end
Samplingfinal probabilitiesthe random stateone softmax and one draw over V
Repetition penaltylogits and all tokens so far, prompt toonothing extraa lookup and write-back of their logits
Temperature, top-k, top-p, min-plogitsnothing extratemperature divides each logit oncetop-k runs a partial sorttop-p runs a full sort and a running summin-p takes a max and compares
Figure 15. V is the vocabulary size. Every method also keeps the key-value cache. From the Hugging Face code.

8.4 Gotchas

The Hugging Face Generation docs list every argument, and the Generation strategies guide shows each method in use.

9 References

  1. Holtzman, A., et al. (2020). The Curious Case of Neural Text Degeneration. ICLR 2020. arXiv:1904.09751.
  2. Fan, A., et al. (2018). Hierarchical Neural Story Generation. ACL 2018. arXiv:1805.04833.
  3. Nguyen, M. N., et al. (2025). Turning Up the Heat: Min-p Sampling for Creative and Coherent LLM Outputs. ICLR 2025. arXiv:2407.01082 (first posted 2024).
  4. Keskar, N. S., et al. (2019). CTRL: A Conditional Transformer Language Model for Controllable Generation. arXiv:1909.05858.
  5. Wu, Y., et al. (2016). Google’s Neural Machine Translation System: Bridging the Gap between Human and Machine Translation. arXiv:1609.08144.
  6. Goodfellow, I., et al. (2016). Deep Learning, section 4.1. MIT Press. deeplearningbook.org.
  7. Hugging Face Transformers. Its generation code is in the files generation/utils.py and generation/logits_process.py, and it applies the repetition penalty, then temperature, before the top-k, top-p and min-p cuts, multiplies a negative logit by the penalty, and divides a finished beam’s score by its length to the power length_penalty. Argument names and defaults are in Generation, examples in Generation strategies, and output types in Utilities for Generation.
  8. vLLM. The LogitsProcessor interface of its V2 model runner states that custom processors run “before temperature, min_p and top-k/top-p”. docs.vllm.ai.
  9. llama.cpp. The --samplers option in its tools’ help text, default order ending in temperature. Debian manual page llama-perplexity(1). manpages.debian.org.