Top-P
By the Syncfusion DevTutorials team · Last updated
How top-p (nucleus) sampling keeps the smallest set of tokens whose chances add up to p, why it adapts to how sure the model is, and how all the settings work together.
Top-k keeps the same number of tokens at every step. That is too many when the model is sure, and too few when it is unsure. Top-p fixes this. Instead of a fixed number, it keeps a fixed amount of chance.
The main idea: top-p keeps the fewest tokens whose chances add up to at least p. When the model is sure, that is just one or two tokens. When it is unsure, it is many tokens.
A Real-World Example
Think about packing a suitcase for a trip, where you must pack "enough clothes for 90% of the weather you might get".
For a trip to a desert, one kind of weather covers almost everything: hot and dry. You can pack light. For a trip to a rainy mountain town, the weather could be anything. You need clothes for sun, rain, wind, and cold.
The rule never changes: cover 90%. But the size of the suitcase changes with how sure the forecast is.
Top-p works in the same way.
- "Cover 90% of the weather" is top-p with p = 0.9.
- The desert trip is a step where the model is sure: just a few tokens cover 90%.
- The mountain trip is a step where the model is unsure: many tokens are needed to reach 90%.
- The suitcase is the shortlist of tokens that may be picked.
In simple words: top-p keeps "enough tokens to cover p of the chance", however many that turns out to be.
What You Will Learn
In this lesson, you will learn:
- How to add up chances from the top of the list.
- How top-p picks the shortlist.
- Why top-p adapts to how sure the model is.
- How temperature, top-k, and top-p work together, and in what order.
- How to choose settings for common tasks.
Top-p is a real WebLLM setting, so it works in the AI sandbox's Chat tab (you set it in Settings). The Sampling tab applies it to the real model's scores while you drag the slider, so you can see exactly which tokens it keeps.
Adding Up the Chances
Top-p is also called nucleus sampling. The "nucleus" is the small core of tokens that holds most of the chance.
To find it, sort the tokens from most to least likely, and keep a running total.
A running total of chances
const sorted = [
[" blue", 0.32], [" green", 0.20], [" red", 0.15], [" purple", 0.10],
[" black", 0.08], [" the", 0.06], [" yellow", 0.05], [" probably", 0.04],
];
let total = 0;
for (const [token, chance] of sorted) {
total += chance;
console.log(JSON.stringify(token).padEnd(11), (chance * 100).toFixed(0).padStart(2) + "%", "running total", Math.round(total * 100) + "%");
}
Expected output:
" blue" 32% running total 32%
" green" 20% running total 52%
" red" 15% running total 67%
" purple" 10% running total 77%
" black" 8% running total 85%
" the" 6% running total 91%
" yellow" 5% running total 96%
" probably" 4% running total 100%
Top-p keeps tokens from the top until their running total reaches p. Here p = 0.8 keeps five tokens.
How Top-P Works
- Sort the tokens from most to least likely.
- Keep adding tokens until the running total reaches p.
- Drop everything after that.
- Renormalize the kept chances so they add up to 100% again.
Top-p with p = 0.8
const sorted = [
[" blue", 0.32], [" green", 0.20], [" red", 0.15], [" purple", 0.10],
[" black", 0.08], [" the", 0.06], [" yellow", 0.05], [" probably", 0.04],
];
function topP(sorted, p) {
const kept = [];
let total = 0;
for (const [token, chance] of sorted) {
if (total >= p) break;
kept.push([token, chance]);
total += chance;
}
return kept.map(([token, chance]) => [token, chance / total]);
}
for (const [token, chance] of topP(sorted, 0.8)) {
console.log(JSON.stringify(token).padEnd(9), (chance * 100).toFixed(1) + "%");
}
Expected output:
" blue" 37.6%
" green" 23.5%
" red" 17.6%
" purple" 11.8%
" black" 9.4%
After four tokens, the total is 77%, which is still below 80%. So " black" is added too, which brings the total to 85%. Then the loop stops.
In simple words: keep adding tokens until you have covered p of the chance, then stop.
Top-P Adapts
This is why top-p is so popular. The same p keeps a different number of tokens, depending on how sure the model is.
The same p on a sure step and an unsure step
function countKept(chances, p) {
const sorted = [...chances].sort((a, b) => b - a);
let total = 0;
let kept = 0;
for (const c of sorted) {
if (total >= p) break;
total += c;
kept++;
}
return kept;
}
const sure = [0.93, 0.04, 0.02, 0.01];
const unsure = [0.14, 0.13, 0.12, 0.11, 0.10, 0.10, 0.09, 0.08, 0.07, 0.06];
console.log("Sure step (The capital of France is):", countKept(sure, 0.9), "token kept");
console.log("Unsure step (My favourite food is): ", countKept(unsure, 0.9), "tokens kept");
Expected output:
Sure step (The capital of France is): 1 token kept
Unsure step (My favourite food is): 9 tokens kept
With p = 0.9:
- On the sure step, only the top token is kept. Nonsense cannot get in.
- On the unsure step, nine tokens are kept. Good variety is not cut.
A fixed top-k could not do both of these things at once.
Easy Way to Remember: top-k is a fixed number of seats. Top-p is a fixed share of the votes. Top-p's shortlist grows when the model is unsure and shrinks when it is sure.
All the Settings Together
When several settings are used at once, they run in this order:
- Temperature reshapes the logits.
- Softmax turns them into chances.
- Top-k keeps at most k tokens.
- Top-p keeps the smallest set that reaches p.
- The kept chances are renormalized, and one token is sampled.
The full sampling pipeline: temperature, softmax, top-k, top-p, then pick one token.
The full pipeline
function pipeline(tokens, logits, temperature, k, p) {
const exps = logits.map((l) => Math.exp(l / temperature));
const total = exps.reduce((a, b) => a + b, 0);
let list = tokens
.map((token, i) => [token, exps[i] / total])
.sort((a, b) => b[1] - a[1])
.slice(0, k);
const kept = [];
let sum = 0;
for (const [token, chance] of list) {
if (sum >= p) break;
kept.push([token, chance]);
sum += chance;
}
return kept.map(([token, chance]) => token + " " + Math.round(chance / sum * 100) + "%");
}
const tokens = [" blue", " green", " red", " purple", " black", " the"];
const logits = [3.0, 2.5, 2.2, 1.8, 1.6, 0.5];
console.log("T 0.7, k 40, p 0.9:", pipeline(tokens, logits, 0.7, 40, 0.9).join(", "));
console.log("T 1.2, k 40, p 0.9:", pipeline(tokens, logits, 1.2, 40, 0.9).join(", "));
console.log("T 1.2, k 3, p 0.9:", pipeline(tokens, logits, 1.2, 3, 0.9).join(", "));
Expected output:
T 0.7, k 40, p 0.9: blue 50%, green 25%, red 16%, purple 9%
T 1.2, k 40, p 0.9: blue 35%, green 23%, red 18%, purple 13%, black 11%
T 1.2, k 3, p 0.9: blue 46%, green 30%, red 24%
- At T 0.7, top-p keeps four tokens. " black" and " the" are cut.
- At T 1.2, the chances are flatter, so top-p needs five tokens to reach 90%.
- With k = 3, top-k cuts the list first, so only three tokens are left for top-p to look at.
Each line adds up to about 100%, give or take rounding.
Try It in the AI Sandbox
Press the button to open the Sampling tab. Set Top-k to off (0) and drag Top-p from 1.0 down to 0.5. Watch how many tokens stay. Then try a different prompt where the model is sure, like "The capital of France is", and compare the two.
Then try it for real in Chat: open Settings, set temperature to 1.0, and compare replies at top-p 1.0 and top-p 0.5.
Choosing Settings
These are common starting points. Always test with your own prompts.
| Task | Temperature | Top-p | Why |
|---|---|---|---|
| Data extraction, JSON, tests | 0 | 1.0 | Greedy and repeatable. Top-p does nothing at temperature 0. |
| Facts and code | 0.2 | 0.9 | A little room for variety, but no tail tokens. |
| Everyday chat | 0.7 | 0.9 | Natural variety, with a safe shortlist. |
| Stories and ideas | 1.0 | 0.95 | More variety, still no nonsense tail. |
The same top-p values, used on an unsure step, keep very different numbers of tokens:
How many tokens each preset keeps on an unsure step
function countKept(chances, p) {
let total = 0;
let kept = 0;
for (const c of chances) {
if (total >= p) break;
total += c;
kept++;
}
return kept;
}
const unsure = [0.14, 0.13, 0.12, 0.11, 0.10, 0.10, 0.09, 0.08, 0.07, 0.06];
const presets = { facts: 0.9, stories: 0.95, tight: 0.5 };
for (const name in presets) {
console.log(name.padEnd(8), "p =", presets[name], "->", countKept(unsure, presets[name]), "tokens");
}
Expected output:
facts p = 0.9 -> 9 tokens
stories p = 0.95 -> 10 tokens
tight p = 0.5 -> 4 tokens
A common tip from AI providers is to change either temperature or top-p, not both at once. They do similar jobs, and changing both at the same time makes results hard to understand.
A very low top-p, like 0.1, keeps only the top token on most steps. That is almost greedy decoding, and long replies can start to repeat themselves. A top-p of 1.0 keeps every token, which means top-p is switched off.
Common mistakes
| Mistake | Wrong idea | Correct idea | What goes wrong |
|---|---|---|---|
| Reading p as a share of tokens | "p = 0.9 keeps 90% of the tokens." | It keeps the fewest tokens that hold 90% of the chance. | You expect thousands of tokens, but often only a few are kept. |
| Very low p for stories | "p = 0.2 keeps it safe." | That is almost greedy. Text gets dull and may loop. | Stories repeat the same phrases. |
| Tuning temperature and p together | "Change both to get the best result." | They do similar jobs. Change one at a time. | You cannot tell which change helped. |
| Expecting p to matter at T = 0 | "Lower p makes temperature 0 safer." | At temperature 0, the top token always wins. Top-p changes nothing. | You tune a setting that has no effect. |
| Forgetting the order | "Top-p runs before temperature." | Temperature comes first, then top-k, then top-p. | Your own code gives different results from the library. |
| p = 1.0 as a filter | "p = 1.0 is the strictest." | p = 1.0 keeps everything. It switches top-p off. | The tail is not cut at all. |
Exercises
Each exercise ends with a value on the last line. Press Check to compare your answer with the expected one.
What to Remember
- Top-p, also called nucleus sampling, keeps the fewest top tokens whose chances add up to p.
- It works using a running total of chances from the top of the sorted list.
- The shortlist grows when the model is unsure and shrinks when it is sure.
- The order is temperature → softmax → top-k → top-p → sample.
- p = 1.0 switches top-p off. A very low p is almost greedy.
- Usually change temperature or top-p, not both.
- At temperature 0, top-k and top-p make no difference.
Next: Hallucinations, where you will learn why a model can sound sure and still be wrong.