Decoding Strategies and Output Control

A language model does not write text directly. Instead, it returns logits for the next token. The decoding algorithm decides how to turn those logits into a token, and repeating this decision produces the output text.

The decoding algorithm affects the behavior of the model. Greedy decoding is deterministic and stable, but it can be dull. Sampling introduces some randomness, which can produce more diverse text but may also produce mistakes. Beam search can be useful for some constrained tasks but is usually not the best default for chat-style generation. Output constraints can make the model produce JSON or stop at a specific marker.

In this chapter, you will learn about:

  • Greedy decoding
  • Temperature sampling
  • Top-k and nucleus sampling
  • Repetition penalties
  • Stop conditions
  • Beam search
  • Structured output constraints

Let’s get started.

Decoding Strategies and Output Control
Photo by Claudio Testa. Some rights reserved.

Overview

This chapter is divided into nine parts; they are:

  • Reading Logits from a Model
  • Greedy Decoding
  • Temperature Sampling
  • Top-$k$ Sampling
  • Nucleus Sampling
  • Repetition Penalties
  • Beam Search
  • Stop Conditions
  • Structured Output Constraints

Reading Logits from a Model

The model returns a vector of logits for every position in the input sequence. For generation, you normally use only the last position because it predicts the next token.

The following example uses the Hugging Face transformers library with a small GPT-2 style model. The checkpoint is small enough for local experimentation, but the same logic applies to larger models.

The output shape is:

The logits are not probabilities. To turn logits into probabilities, use softmax:

However, you often do not need to compute probabilities explicitly. Greedy decoding only needs the index of the largest logit, which is the same as the token with the highest probability.

This is the simplest decoding strategy.

Greedy Decoding

Greedy decoding always chooses the token with the highest score. A complete greedy decoding function can be written as follows:

Greedy decoding is deterministic. Given the same model and prompt, it returns the same output. This is useful for debugging and for tasks where variation is undesirable.

The weakness is that the best local token is not always the best continuation. Greedy decoding can repeat itself, choose common phrases too often, and miss more interesting continuations.

Temperature Sampling

Temperature sampling draws from a probability distribution obtained by scaling the logits with a temperature parameter.
The figure below shows how temperature changes the probability distribution without changing the underlying logits. The same ten token scores are converted to probabilities three times: once with temperature 0.5, once with temperature 1, and once with temperature 2.

The same logits produce different token probabilities under different temperatures. A lower temperature concentrates probability on the highest-scoring token, while a higher temperature spreads probability across more tokens.

Sampling chooses the next token randomly from the model’s probability distribution. Temperature controls how sharp or flat that distribution is. Given logits $\mathbf{z}$ and temperature $T$, temperature sampling uses:

$$
\mathbf{p} = \operatorname{softmax}(\mathbf{z} / T)
$$

A low temperature makes the distribution $\mathbf{p}$ sharper. A high temperature makes it flatter. If the temperature approaches zero, sampling behaves like greedy decoding, provided one token has a uniquely highest logit. If the temperature is too high, differences between the logits become less important, and the model may choose unlikely tokens too often.

A sampling loop using temperature looks like this:

Temperature is not a quality knob by itself. It changes the amount of randomness. The right value depends on the task. A factual extraction task usually wants a lower temperature. Brainstorming and creative writing may benefit from a higher temperature.

Top-$k$ Sampling

In the figure above, a 10-token distribution is shown as an example. An actual model may have a vocabulary of hundreds of thousands of tokens, including many that have extremely low probability in a given context.

Top-$k$ sampling keeps only the $k$ highest-scoring tokens and removes all other tokens from consideration. Its primary purpose is to prevent the model from sampling extremely unlikely tokens. It does not avoid computing logits over the full vocabulary, but it does reduce the number of candidates you sample from.

Top-$k$ is easy to understand, but it uses a fixed number of candidates. Sometimes the model is very confident and only a few tokens matter. Sometimes many tokens are plausible, in which case a fixed top-$k$ cutoff may be inappropriate. This motivates nucleus sampling.

Nucleus Sampling

Nucleus sampling, also called top-$p$ sampling, keeps the smallest set of tokens whose cumulative probability is at least $p$. For example, with $p=0.9$, it keeps the most likely tokens that together account for 90 percent of the probability mass.

The function above combines temperature sampling, optional top-$k$ filtering, and top-$p$ filtering. Combining these techniques is common. Their order matters because temperature scaling and filtering affect the distribution from which the next token is sampled. Top-$p$ is adaptive: it may keep only a handful of tokens when the model is confident and many tokens when the distribution is broad.

Repetition Penalties

Autoregressive models can fall into loops in which a pattern of tokens repeats itself. Adding a repetition penalty reduces the scores of tokens that have already appeared so that those tokens are less likely to be chosen again.

One simple version divides positive logits by the penalty and multiplies negative logits by the penalty:

This function is intentionally simple and assumes a batch size of one. For example, multiple occurrences of the same token do not increase the penalty. The caller also decides whether generated_ids includes prompt tokens, generated tokens, or both. If you use repetition penalties with top-$k$ or nucleus sampling, apply the penalties first. Production implementations usually handle larger batches and may also distinguish frequency penalties from presence penalties.

Repetition penalties can help, but they can also harm quality. Some words should repeat. Code, names, citations, and structured formats often require exact repetition. Use this control only when repetition is a real problem.

Beam Search

Greedy decoding keeps only one candidate sequence. Beam search keeps several candidates. At each step, it expands each candidate with possible next tokens and keeps the best-scoring sequences.

Beam search is useful when there is a well-defined sequence-level objective, such as translation in older sequence-to-sequence systems. For open-ended chat generation, beam search often produces generic text because it favors high-probability continuations.

A minimal beam search loop looks like this:

This implementation is deliberately small. A real implementation should normalize scores by sequence length, handle end-of-sequence tokens, and avoid recomputing the whole prefix by using a KV cache.

Beam search is expensive: the loops make generation slower, and the number of beams increases memory usage. If you use four beams, the model tracks four continuations. This increases compute and cache memory compared with ordinary sampling. Therefore, beam search is usually avoided in LLM services.

Stop Conditions

Generation must stop at some point. The simplest stop condition is a maximum number of new tokens. Another common condition is the model’s end-of-sequence token. Usually the vocabulary in a language model contains some special tokens. The end-of-sequence token is one of them.

The greedy decoding example above can be modified to accept an arbitrary stop token:

This function checks whether the next token is the stop token. If it is, the loop ends and the function returns the generated text before reaching the maximum number of new tokens. This implementation does not handle batched inputs; it assumes a single prompt. With batched inputs, different sequences may stop at different times, in which case more sophisticated handling is needed.

Structured Output Constraints

Some applications need the model to produce a format such as JSON, a SQL query, or a value from a fixed list. One approach is to prompt the model and *hope* that it follows the format. A stronger approach is constrained decoding.

The idea is to mask out tokens that would make the output invalid. For example, if the output must be one of three labels, you can score only those labels:

This example handles only labels that encode to one token after the prompt. Tokenization can depend on context, including preceding whitespace, so callers must construct the labels accordingly. Multi-token labels require scoring complete token sequences or constraining each decoding step. Structured decoding turns output requirements into token constraints. More advanced systems use grammars, tries, or finite-state machines to decide which tokens are valid at each step.

Constrained decoding can improve reliability, but it can also slow inference. The system must compute and apply token masks at each step. As with every inference technique, you should measure both quality and performance.

Further Reading

Below are some resources you may find useful:

  • Softmax function, on Wikipedia.
    This is a useful reference for how logits are converted into probabilities. Temperature sampling is a direct modification of the softmax input, replacing $\mathbf{z}$ with $\mathbf{z}/T$ before normalization.
  • Beam search, on Wikipedia.
    This page describes beam search as a general heuristic search algorithm. In language generation, beam search keeps several candidate continuations instead of only the single best next token.
  • The Curious Case of Neural Text Degeneration, by Holtzman et al.
    This paper explains why maximum-likelihood decoding methods such as greedy decoding and beam search can produce bland or repetitive text, and introduces nucleus sampling as a practical alternative for open-ended generation.
  • Contrastive Decoding: Open-ended Text Generation as Optimization, by Li et al.
    This paper proposes a decoding method that compares an expert language model with a smaller amateur model, using the difference between their scores to prefer fluent and informative continuations.
  • Grammar-Constrained Decoding for Structured NLP Tasks without Finetuning, by Geng et al.
    This paper discusses how formal grammars can constrain the token choices of a language model so that generated outputs follow a required structure.
  • Generating Structured Outputs from Language Models: Benchmark and Studies, by Geng et al.
    This paper studies constrained decoding for structured outputs such as JSON schemas, and is especially relevant when the goal is reliable machine-readable output rather than free-form text.

Summary

In this chapter, you learned that decoding is the process of choosing tokens from logits. Greedy decoding is deterministic and simple. Temperature sampling, top-$k$ sampling, and nucleus sampling introduce controlled randomness. Beam search tracks multiple candidates but increases inference cost. Repetition penalties and stop conditions help control output length and behavior. Structured output constraints can make model outputs easier to use in applications.

In the next chapter, you will learn how to measure inference performance so that these choices can be compared with real numbers instead of intuition.

Similar Posts

Leave a Reply