Decoding Methods for LLMs
LLMs are, at their core, completely deterministic. In a controlled environment—fixed parameters, identical input, and a known random seed—an LLM will generate the same output every time. There’s no “built-in” randomness. Yet, we often want more interesting and varied outputs, rather than the most probable, so we deliberately introduce methods that create the illusion of randomness / creativity. This article explains these methods and how they influence an LLM’s output distribution.
Note: confusion often arises because most users (and devs) encounter LLMs through proprietary APIs. Which are, surprisingly, impossible to make consistent even when all top-level hyper-parameters are exposed. The reality is this that this is due to other factors such as GPU thread scheduling, rounding behaviour in floating-point arithmetic, opaque model versioning etc. This warrants it’s own, separate discussion.
Setup
For this discussion I’ll assume a standard auto-regressive language modelling objective. Let: be our vocabulary of discrete tokens. Parameters () are static at inference time, so for any input sequence we produce a fixed probability distribution over our token vocabulary at each generation / decoding step :
Here, is a vector representing the model’s output logits for each token in . The Softmax for a token at index (corresponding to ) is given by:
Temperature
Temperature () is a parameter used to control the amount of randomness during generation. It simply scales the logits before they get converted to probabilities:
So for: • : the probability distribution is more uniform, leading to more “creative” sampling • : the probability distribution is sharper, meaning more confident generations. In production settings you’re typically pretty worried about hallucinations, so will likely set . However, in the equation above is undefined (division by 0). Practically, you can just sample greedily and bypass the Softmax calculation entirely.
Top K Sampling
Top K sampling restricts the next-token selection to only the top most probable tokens at each decoding step. Starting with the full distribution:
We first sort the tokens in according to their probabilities in descending order:
We then take the top tokens:
To form the final probability distribution after top truncation, we renormalise the probabilities of only these selected tokens:
Top P (nucleus) Sampling
Top P sampling selects the smallest set of of tokens whose cumulative probability exceeds the specified . So let S be the smallest set of tokens:
such that:
This set is constructed by starting from the most likely token and adding tokens in descending order of their probability until the cumulative probability surpasses . Once we have identified , we discard all tokens not in that set and renormalise the probabilities of the tokens in just as we did for top sampling:
The idea here is to choose a variable set of candidate tokens at each decoding step. Instead of a fixed-size truncation like top , top sampling adapts dynamically to the distribution of probabilities. If the model is very confident about a few tokens, might be small. If the probabilities are more spread out, grows larger. By adjusting , you control how “broad” the sampling distribution is—lower will make it more greedy, while higher yields more diverse outputs.
Stop Sequences
Stop sequences are predefined token patterns that, if generated, immediately stop the decoding process. Unlike the previous methods that adjust token probabilities, stop sequences do not affect the model’s distribution. Instead, they provide a deterministic cutoff: once a stop sequence appears, no further tokens are produced. This helps with enforcing strict output formats.
Final Remarks
I believe that having a precise mental model of these techniques is really important when you’re building with LLMs. We don’t have many tools to control proprietary LLMs but these few parameters do let us shape the model’s output distribution in meaningful ways and hopefully let us build more robust systems.