Temperature alone is powerful but has limitations. That’s why almost every production LLM (including Grok) combines it with Top-k or Top-p (nucleus) sampling.
This document explains the “why” and “how” behind these techniques, using the same spirit as the prototype: make the invisible mechanics visible and understandable.
Even with a well-chosen temperature, the model can still:
Top-k and Top-p solve this by restricting the set of tokens the model is allowed to sample from at each step.
They act as a filter after temperature has shaped the distribution.
Suppose after the context "Elara listened in wonder", the model’s top probabilities look like this:
| Token | Probability | Rank |
|---|---|---|
. | 41% | 1 |
, | 23% | 2 |
From | 18% | 3 |
and | 7% | 4 |
she | 4% | 5 |
the | 2% | 6 |
machinee | 0.8% | 7 |
| … | … | … |
machinee (and everything below) is thrown away, even if temperature is high.k is problematic in practice:
This rigidity is why Top-p (nucleus sampling) was invented.
Instead of taking a fixed number of tokens (k), we take the smallest set of tokens whose cumulative probability is at least p.
This dynamic set is called the nucleus.
p = 0.9)| Token | Prob | Cumulative |
|---|---|---|
. | 41% | 41% |
, | 23% | 64% |
From | 18% | 82% |
and | 7% | 89% |
she | 4% | 93% |
top_p = 0.9, we stop at "she" because the cumulative probability just crossed 90%.This is dynamic — it automatically adapts to how confident (or uncertain) the model is at each generation step.
top_p = 0.9 or 0.95 (very common)temperature = 0.7 ~ 1.0Most APIs let you use both together. The typical order of operations is:
logits = logits / temperature)This gives you two independent, intuitive controls:
| Control | Effect | Analogy |
|---|---|---|
| Temperature | How sharp or flat the distribution is | How “creative” vs “safe” |
| Top-p | How wide the allowed set of tokens is | How much “exploration room” |
Low Temp + Low Top-p → Very safe, almost deterministic
Low Temp + High Top-p → Safe but allows some exploration
High Temp + Low Top-p → Creative but still constrained (weirdness limited)
High Temp + High Top-p → Maximum creativity + chaos
| Model / API | Typical Temperature | Typical Top-p |
|---|---|---|
| Grok / xAI | 0.7 – 1.0 | 0.9 |
| GPT-4o | 0.7 | 0.9 |
| Claude 3.5 | 0.7 | — (uses different internal method) |
| Creative writing | 1.0 – 1.2 | 0.95 |
| Coding / structured | 0.2 – 0.4 | 0.8 |
Note: Some models (notably Claude) achieve similar effects through different techniques and may not expose
top_pdirectly.
Look at generate_text in simple_llm_prototype.py:
next_logits = logits[0, -1, :] / max(temperature, 1e-6)
probs = torch.softmax(next_logits, dim=-1)
next_id = torch.multinomial(probs, num_samples=1).item()
Currently it only uses temperature. Adding top-k or top-p would go between the softmax and the torch.multinomial call:
probs as above.torch.multinomial on the filtered set.The --show-probs flag already uses torch.topk internally to display the model’s beliefs — the same primitive used in top-k sampling.
Once top-p / top-k are added to the prototype (or if you implement them yourself):
--temp 1.1 and no top-p → watch weird tokens appear.--temp 1.1 --top_p 0.9 → creativity without the garbage.top_p (0.6) with medium temperature on a creative prompt → see how the model gets “stuck” in safe but boring continuations.For even more control, production systems often add:
These are usually combined with temperature + top-p.
Understanding these three knobs (and their interactions) removes a lot of the mystery around why models sometimes feel “inspired” and sometimes feel “drunk.”
This is document “2” in the sampling series for the prototype. The core generation loop remains the same: predict, filter, sample, append, repeat.
Reflect on why a tiny model makes these problems extremely visible