Determinism

By the Syncfusion DevTutorials team · Last updated

Why an LLM can give a different answer each time, how greedy decoding and a fixed seed make it repeat, and when repeatable output matters.

Ask a chat assistant the same question twice, and you will often get two different answers. Sometimes that is great, like when you want new ideas. Other times it is a problem, like when you are testing an app and need the same result every time.

This lesson explains where that difference comes from, and how to turn it off when you need to.

The main idea: the model's chances are the same every time. The difference comes from how the next token is picked. If you always pick the top token, or if you fix the random seed, the output will repeat.

A Real-World Example

Think about choosing lunch from a menu with your three favourite dishes.

  • If you always order your top favourite, you eat the same lunch every day. Anyone can predict it.
  • If you roll a die to choose, your lunch changes from day to day.
  • If you roll the die but use the same lucky throw every time, you get the same lunch again, even though you "rolled".

Picking the next token works in the same way.

  • Always ordering the favourite is greedy decoding.
  • Rolling a die is sampling, which means picking at random based on the chances.
  • The same lucky throw is a fixed seed.

In simple words: a reply only changes if the picking step uses chance, and that chance can be made repeatable.

What You Will Learn

In this lesson, you will learn:

  1. Why the same prompt can give different replies.
  2. What sampling means.
  3. How greedy decoding makes the choice repeatable.
  4. What a random seed is, and how it makes random choices repeat.
  5. When repeatable output matters, and when it does not.

The code boxes on this page use a small random number maker that takes a seed, so you can see the same random choices every time you press Run. In the AI sandbox, the Settings tab has the real temperature and seed for the model.

Two Ways to Pick a Token

At every step, the model gives each token a chance. Then something must pick one of those tokens. There are two main ways to do this.

Greedy decoding always takes the top token. Sampling picks at random, using the chances as weights.

Greedy: Always the Top Token

Greedy decoding always takes the token with the highest chance. No chance is involved, so the result never changes.

Greedy picks the same token every time

const chances = { " blue": 0.5, " green": 0.3, " red": 0.2 };

function greedy(chances) {
  return Object.entries(chances).sort((a, b) => b[1] - a[1])[0][0];
}

for (let run = 1; run <= 3; run++) {
  console.log("Run " + run + ":", JSON.stringify(greedy(chances)));
}

Expected output:

Run 1: " blue"
Run 2: " blue"
Run 3: " blue"

Sampling: Pick at Random by the Chances

Sampling picks a token at random, but not evenly. A token with a 50% chance is picked about half the time. A token with 20% is picked about one time in five.

To pick, the code draws a random number between 0 and 1, then walks down the list, taking away each token's chance until the number runs out. The token it lands on is the one chosen.

Sampling with four different seeds

function seededRandom(seed) {
  let a = seed >>> 0;
  return () => {
    a = (a + 0x6d2b79f5) >>> 0;
    let t = a;
    t = Math.imul(t ^ (t >>> 15), t | 1);
    t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
  };
}

function sample(chances, random) {
  let r = random();
  for (const [token, chance] of Object.entries(chances)) {
    r -= chance;
    if (r <= 0) return token;
  }
}

const chances = { " blue": 0.5, " green": 0.3, " red": 0.2 };

for (const seed of [1, 4, 7, 9]) {
  const random = seededRandom(seed);
  console.log("Seed " + seed + ":", JSON.stringify(sample(chances, random)));
}

Expected output:

Seed 1: " green"
Seed 4: " red"
Seed 7: " blue"
Seed 9: " blue"

Different seeds give different picks, even though the chances never changed. That is exactly why a chat assistant can answer the same question in different ways.

Over many picks, each token is picked about as often as its chance says it should be. The next box samples 1,000 times to show this.

1,000 samples follow the chances

function seededRandom(seed) {
  let a = seed >>> 0;
  return () => {
    a = (a + 0x6d2b79f5) >>> 0;
    let t = a;
    t = Math.imul(t ^ (t >>> 15), t | 1);
    t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
  };
}

function sample(chances, random) {
  let r = random();
  for (const [token, chance] of Object.entries(chances)) {
    r -= chance;
    if (r <= 0) return token;
  }
}

const chances = { " blue": 0.5, " green": 0.3, " red": 0.2 };
const random = seededRandom(2026);
const counts = {};
for (let i = 0; i < 1000; i++) {
  const token = sample(chances, random);
  counts[token] = (counts[token] || 0) + 1;
}

for (const token in counts) {
  console.log(JSON.stringify(token).padEnd(8), counts[token], "times");
}

Expected output:

" blue"  501 times
" green" 289 times
" red"   210 times

About 50%, 30%, and 20%, just like the chances.

In simple words: the model's chances are fixed. The roll of the die is what changes.

Seeds Make Random Repeat

Computers do not really roll dice. They use a formula that creates a long list of numbers that look random. The starting point of that list is called the seed.

  • The same seed always gives the same list of numbers.
  • A different seed gives a different list.

So with a fixed seed, even sampling will repeat.

Same seed, same reply

function seededRandom(seed) {
  let a = seed >>> 0;
  return () => {
    a = (a + 0x6d2b79f5) >>> 0;
    let t = a;
    t = Math.imul(t ^ (t >>> 15), t | 1);
    t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
  };
}

function sample(chances, random) {
  let r = random();
  for (const [token, chance] of Object.entries(chances)) {
    r -= chance;
    if (r <= 0) return token;
  }
}

const chances = { " blue": 0.5, " green": 0.3, " red": 0.2 };

function reply(seed) {
  const random = seededRandom(seed);
  const picks = [];
  for (let step = 0; step < 6; step++) picks.push(sample(chances, random).trim());
  return picks.join(" ");
}

console.log("Seed 42, first time: ", reply(42));
console.log("Seed 42, second time:", reply(42));
console.log("Seed 7:              ", reply(7));

Expected output:

Seed 42, first time:  green blue red green blue green
Seed 42, second time: green blue red green blue green
Seed 7:               blue blue red green green blue

Seed 42 gives the same six picks both times. Seed 7 gives a different set of picks.

Easy Way to Remember: greedy = always the same. Sampling = changes. Sampling + fixed seed = the same changes every time.

Temperature 0 Means Greedy

Most AI services control the picking step with a setting called temperature. You will learn about it properly in the next lesson. For now, one fact is enough: temperature 0 means greedy decoding. The top token always wins.

Temperature 0 picks the top token

function pick(chances, temperature, random) {
  const entries = Object.entries(chances);
  if (temperature === 0) {
    return entries.sort((a, b) => b[1] - a[1])[0][0];
  }
  let r = random();
  for (const [token, chance] of entries) {
    r -= chance;
    if (r <= 0) return token;
  }
}

const chances = { " blue": 0.5, " green": 0.3, " red": 0.2 };
const notRandom = () => 0.99;

console.log("Temperature 0:", JSON.stringify(pick(chances, 0, notRandom)));
console.log("Temperature 1:", JSON.stringify(pick(chances, 1, notRandom)));

Expected output:

Temperature 0: " blue"
Temperature 1: " red"

With temperature 1, a random number of 0.99 lands on the last token, " red". With temperature 0, the random number is ignored, and " blue" wins.

Try It in the AI Sandbox

In the sandbox, open Settings. Set temperature to 0, then ask the same question twice in the Chat tab, pressing Clear chat in between. Then set temperature to 1 and try again with different seeds.

Things to notice:

  • At temperature 0, the reply should be the same every time.
  • At temperature 1 with the same seed, the reply should repeat too.
  • At temperature 1 with a different seed, the reply changes.

Even with temperature 0 and a fixed seed, outputs can sometimes differ between computers, browsers, or model versions. Graphics chips do maths in slightly different orders, and a tiny difference can flip a close choice. Repeatable means "the same setup gives the same result", not "every setup in the world agrees".

When Repeatable Output Matters

Use temperature 0, or a fixed seed, when you need the same answer every time:

  • testing an app, so a test that passed yesterday still passes today
  • pulling data out of text, like names, dates, or JSON
  • grading exercises, as this course does
  • comparing two prompts fairly, where only the prompt should change

Allow randomness when variety helps:

  • brainstorming names, ideas, or stories
  • writing several different versions of a message
  • chat that should feel less robotic

Common mistakes

MistakeWrong ideaCorrect ideaWhat goes wrong
Blaming the model's mood"The model changed its mind."The chances are the same. Sampling just picked a different token.You chase a problem in the prompt that is really just randomness.
Testing with randomness on"My test passed once, so it works."With sampling, the next run can differ. Use temperature 0 or a fixed seed.Tests pass and fail at random.
Comparing prompts unfairly"Prompt B is better because its one answer was better."With randomness, one answer proves little. Fix the settings first.You pick the wrong prompt.
Thinking a seed fixes everything"Same seed means the same answer on every computer."Hardware and versions can still change close choices.Results differ between your laptop and a server.
Using temperature 0 for ideas"Temperature 0 is always best."Greedy output repeats and can loop. Creative tasks need some randomness.Every brainstorm gives the same few ideas.
Thinking greedy is always right"The top token is the correct token."Greedy is repeatable, not guaranteed correct.You trust a wrong answer because it never changes.

Exercises

Each exercise ends with a value on the last line. Press Check to compare your answer with the expected one.

What to Remember

  • The model's chances are the same every time. The picking step is what decides the token.
  • Greedy decoding always takes the top token, so it always repeats.
  • Sampling picks at random by the chances, so replies can differ.
  • A seed is the starting point for random numbers. The same seed gives the same picks.
  • Temperature 0 means greedy decoding.
  • Use repeatable settings for tests, data extraction, and grading. Allow randomness for creative work.
  • Different hardware or versions can still change close choices.

Next: Temperature, the setting that makes the model's choices sharper or more adventurous.