
LLM sampling parameters look deceptively simple — a temperature slider, a top-p field, a few penalty knobs — yet most quality regressions in production LLM applications come from how those parameters are tuned, not from the parameters themselves. This article examines five anti-patterns that quietly degrade output quality: simultaneous adjustment of redundant knobs, premature tuning before the model or prompt is fixed, misuse of repetition penalties, assumptions carried over from standard generation into reasoning models, and stacking of overlapping penalty mechanisms. Each pattern includes the underlying mechanism, the failure mode it produces, and a safer alternative grounded in provider guidance and open-source inference defaults. The intended audience is engineers and prompt designers who already understand what temperature and top-p do and want to avoid the subtle ways those controls can work against them. This is a troubleshooting brief, not a parameter reference; readers seeking per-use-case settings should consult the related sampling cheat sheet.

Open the sampling panel of almost any LLM API and the two most prominent controls are temperature and top-p. They are presented as independent sliders, so it is natural to nudge both when output drifts off-target. That intuition is wrong: the two knobs act at different stages of the same pipeline, and stacking them produces non-linear effects that are difficult to attribute to any single change.
Temperature operates before normalization. The model's final linear layer emits raw logits, one per vocabulary token; temperature divides those logits by a factor T before the softmax converts them into a probability distribution. Lower values sharpen the distribution toward the top token (collapsing toward greedy decoding as T → 0), while higher values flatten it and surface long-tail candidates (Machine Learning Mastery; Prompt Engineering). Top-p, by contrast, operates after normalization: it sorts the post-softmax distribution in descending order, retains the smallest prefix whose cumulative probability exceeds p, and renormalizes the rest into a new distribution over that "nucleus" (Thearjun; Prompt Engineering). Crucially, temperature changes which tokens sit in the nucleus, and the nucleus then changes which tokens are eligible to be sampled — so adjusting both in the same iteration compounds their influence and can partially cancel, amplify, or invert one another depending on the underlying logit shape.
The practical failure mode is loss of diagnostic signal. If you raise temperature from 0.2 to 0.5 and lower top-p from 0.95 to 0.8 in the same change, a regression in the next evaluation could be caused by either move, by their interaction, or by a prompt shift you didn't notice. There is no clean experiment to isolate the cause. Provider guidance is consistent on the underlying point: OpenAI's documentation, Anthropic's sampling notes, and the Prompting Guide all recommend altering either temperature or top-p for a given task, but not both (Gradually.ai summarizes the same practice).
The safer workflow is mechanical:
generation_config.json: open-weight checkpoints ship with one of the two set to a non-default value, and overriding both clobbers whatever distribution the checkpoint was tuned against.This is a troubleshooting article, not a per-use-case cheat sheet, so the specific values to use are out of scope — the point here is that whatever value you do use, you should be able to name the single change that produced it.

When an answer is wrong, the cheapest-looking action is to move a slider. Temperature is one click away, top-p is right next to it, and the change is reversible. Sampling parameters are also the only knobs that are explicitly advertised as "quality controls," which makes them feel like the right place to start. They are not.
Sampling parameters act on the per-token probability distribution after the model has produced it. They sharpen, flatten, truncate, or penalize that distribution; they never inject new information into it. A 7B model and a 700B model expose exactly the same set of parameters, and changing them cannot close a knowledge gap that exists in the weights, in the context window, or in the prompt itself (ExplainX, 2026; Inferbase, LLM Sampling Parameters).
A consistent ordering produces better outcomes than parameter sweeps (Inferbase; Michele Di Pierri, 2026):
Three failure modes routinely get misdiagnosed as tuning problems:
A useful diagnostic rule: if a change in temperature moves the answer in the wrong direction or does nothing, the lever belongs to a different family of parameters, or to the prompt (Michele Di Pierri, 2026).
Treating sampling as the first lever delays the real fix. Teams end up with parameter values that appear tuned but are actually compensating for, or hiding, a prompt or model defect. When the underlying issue is later corrected, those values become inert or counterproductive, and the configuration that "worked" stops working for reasons no one can reconstruct. Reaching for sampling only after content, shape, and model are correct produces smaller, more interpretable parameter deltas and avoids the magic-number trap that makes a system unmaintainable.

There are now at least four repetition mechanisms in common circulation, each with a distinct mathematical behaviour. Treating them as interchangeable — or reaching for an aggressive value before diagnosing what "repetition" actually means — is the typical source of silent quality regressions (InferBase, langcopilot).
frequency_penalty scales with how often a token has occurred. In llama.cpp it subtracts N × token_count from the logit, so the tenth appearance is punished far harder than the second.presence_penalty applies a flat, one-time deduction to any token that has appeared at least once — a softer nudge toward new vocabulary rather than a count-proportional punishment.repetition_penalty (Hugging Face / Transformers / llama.cpp style) divides positive logits of seen tokens by α and multiplies negative logits by α, making the token less likely regardless of sign. The default is 1.0 (disabled).DRY (Don't Repeat Yourself) evaluates sequences of tokens rather than isolated tokens. The penalty grows as a copied suffix gets longer, roughly multiplier × base^(ℓ − allowed length) (micheledpierri, oobabooga).Before raising any value, identify what repetition looks like in the output. The four controls are tuned to four different symptoms (micheledpierri):
| Visible problem | Most relevant control |
|---|---|
| Same word used too often | frequency_penalty |
| Output refuses to introduce new subjects | presence_penalty |
| Recently used tokens keep recurring | repetition_penalty |
| A phrase, sentence, or paragraph is copied | DRY |
Modern instruction-tuned models loop far less than their ancestors, so the correct default for frequency_penalty and presence_penalty is 0, and for repetition_penalty it is 1.0 (InferBase). Pushing them higher without diagnosis produces predictable damage:
user_id for appearing five times can cause the model to invent a synonym on the sixth occurrence.repetition_penalty can rewrite "mitral valve" as "the valvular structure" (micheledpierri).repeat_penalty multiplier "aggressively suppresses structural words ('the', 'a', punctuation) and easily breaks syntax" (alexewerlof).For Hugging Face-style generators, the safe operating range for repetition_penalty is roughly 1.1–1.3; values above 1.5 are commonly reported as producing "funky outputs" because the multiplier is a blunt instrument (dev.to).
The llama.cpp documentation now actively recommends disabling repeat_penalty in favour of DRY or presence/frequency penalties, because the multiplier cannot distinguish a useful repeat from a harmful one. When anti-looping is required:
dry_multiplier ≈ 0.8, dry_allowed_length = 2, and dry_base = 1.75 as sensible starting points (oobabooga).frequency_penalty0.1–0.3 to suppress a specific verbal tic, and presence_penalty 0.1–0.4 when the output needs more topical breadth (alexewerlof).The discipline is: pick the smallest viable adjustment, applied to the control that targets the actual failure mode, and never combine two repetition mechanisms that overlap.

Reasoning-tuned models — those that emit a chain-of-thought before the final answer — are trained against a specific sampling configuration that often ships in their generation_config.json. The weights have learned to explore, backtrack, and consolidate across a long trace under those exact conditions, so deviations move the model off the distribution it was optimized for. Several providers fix or ignore classical sampling parameters for reasoning endpoints entirely, replacing them with a reasoning_effort control that governs how much deliberation is purchased before answering, rather than how adventurous each token draw is (inferbase.ai). The lever is no longer token-level variance; it is the budget of thinking the model may consume.
Before attributing an output change to a slider, the first hygiene check is to confirm which parameters the specific model actually honors from the provider's documentation or its catalog entry. Some sliders may be silently ignored.
Applying the standard chat-tuned recipe — low temperature around 0.2, top-p near 0.9, modest presence penalty to "encourage variety" — to a reasoning endpoint commonly produces three failure modes:
When the reasoning trace is part of the deliverable:
generation_config.json before changing anything. Open-weight reasoning models such as Qwen3-Thinking ship recommended values that differ sharply from chat-mode defaults — for example, temperature 1.0, top_p 0.95, top_k 20, presence_penalty 0.0, and repetition_penalty 1.0 for thinking mode (huggingface.co/Qwen). The non-thinking preset for the same model uses a different configuration (temperature 0.7, top_p 0.80, presence_penalty 1.5), which makes the contrast explicit.frequency_penalty and presence_penalty on modern instruction-tuned models is zero; they earn their keep only in long generations that circle (inferbase.ai).
frequency_penalty and presence_penalty read like independent knobs because their documentation describes them separately. Mechanically they are not independent — both subtract from the logit of tokens that have already appeared, the only difference being whether the deduction scales with count or applies as a flat one-time hit. frequency_penalty subtracts roughly N × token_count from the logit, so the tenth occurrence of a token is punished harder than the second; presence_penalty subtracts a fixed amount regardless of how many times the token has shown up (llama.cpp reference; Prompting Guide). Because the two deductions are applied to the same logit for the same token, they compound rather than average — stacking them at strong values is the repetition-control analogue of stacking temperature and top-p.The failure is not "more diversity" — it is text that feels actively evasive of common words. Articles, pronouns, and transition phrases are exactly the tokens that occur many times in any fluent English generation, so they receive the largest combined penalty. The model is pushed into unnatural synonym choices to satisfy the combined penalty budget: "however" becomes "that said," "the" gets skipped, and sentences start to read like translated prose. The same effect appears in structured outputs where a legitimate identifier — user_id, an API name, a quoted term — is renamed mid-document because the model has been penalized for repeating it (Inferbase).
Provider and tooling guidance is consistent: alter one at a time, not both (Prompting Guide). The working sequence is:
0.0 and confirm repetition actually occurs at the target temperature — modern instruction-tuned models loop far less than their predecessors, so the default of zero is usually correct.0.1–0.3 for OpenAI-style frequency_penalty / presence_penalty (llama.cpp reference), or 1.1 as a starting point for Hugging Face / open-source repetition_penalty, incremented by 0.05 (langcopilot).0.0 / 1.0 — repetition of terms is required by the format.If a single low penalty does not solve it, the diagnosis is almost always wrong elsewhere: temperature is too low (which makes the locally most-probable continuation a repeated phrase), or the prompt itself is under-specified. Adding a second penalty on top will not fix that — it will just deepen the evasive-synonym problem and, on code or reasoning traces, can corrupt identifiers or break structured JSON (Micheledpierri).

The five anti-patterns above share a single root cause: parameters are tuned before the problem is diagnosed. When sampling knobs are reached for first, each "fix" tends to entangle with the underlying issue — a weak prompt, a wrong default, or an unsuitable model — making symptoms harder to look in immediately and harder to reverse later.
A safer order of operations, drawn from current inference and prompt-engineering practice, looks like this:
generation_config.json or the model card. Model-specific recommendations take priority over generic presets; reasoning and instruct modes on the same checkpoint can ship with very different defaults, as the Qwen3.8 release illustrates — thinking mode uses temperature=1.0, top_p=0.95; non-thinking mode uses temperature=0.7, top_p=0.80 (Unsloth docs).When that hierarchy is followed, most of the earlier mistakes stop occurring on their own. Temperature and top-p do not need to be stacked because the prompt is already right. Repetition penalties do not need to be aggressive because the model's default was already respected. Reasoning models do not receive the wrong preset because their recommended configuration was checked first. The remaining judgement call — which sampling parameter to tune, and in which direction — becomes a focused decision rather than a fishing expedition, and any single change can be safely reverted if it does not help.