Evaluating Generative Models
A fluent answer or convincing picture is not enough to show that a model does its job well. We need evaluation examples and criteria that reflect the task, including failures an overall average might conceal.
14 sections · 10 questions · 3 coding challenges
The arrow keys move between sections too.
How Do We Judge an Answer When Several Answers Could Be Good?
BOTIE
Different fields developed different approximations. BLEU, introduced in 2002 for machine translation, compared candidate text with reference translations through n-gram overlap. The 2017 work introducing Fréchet Inception Distance compared distributions of image features, addressing a different problem from matching one generated image to one target.
Each measure asks a limited question. We need to decide whether we care about correctness, variety, instruction following, resemblance to a distribution, or some combination. Then we choose measurements and inspect representative outputs, including failures. A single improving score cannot establish that every quality we care about improved with it.
A Response Looks Convincing. How Do We Know the Model Improved?
Two models can both produce fluent responses while making different mistakes. One may predict ordinary text well but invent a source. Another may answer correctly but fail to follow the requested format. A single impression of quality cannot tell us which behavior improved.
Evaluation begins by deciding what success means for the task. Then we need examples the model was not trained or tuned on, a measurement that matches the question, and a way to inspect the failures hidden by an average.
Step 1 of 4
Turn a broad claim into a question we can measure
If we care about continuing text, we can measure probability assigned to held-out tokens. If we care about answering from documents, we need to check answer correctness and source support. The task determines which evidence is useful.
- Continuation
- Probability of observed next tokens
- Document answers
- Correctness
- Source support
- Instructions
- Requested behavior
- Format
Step 2 of 4
Keep the evaluation examples separate
A model can look successful by remembering examples it saw during training. Use a held-out test set, and avoid repeatedly choosing changes by its results. Near duplicates, shared documents, or benchmark material inside training data can weaken that separation.
- Training
- Learn parameters
- Validation
- Choose settings
- Test
- Estimate final performance
Step 3 of 4
Inspect confidence as well as the selected token
For next-token scoring, the probability of the observed token matters. Being confidently wrong should receive a larger penalty than being uncertain. Negative log likelihood provides that behavior; perplexity expresses the same average loss on another scale.
- More probability on target
- Lower token loss
- More probability on wrong token
- Higher token loss
Step 4 of 4
Read failures before interpreting a single average
Compare results by task, input length, topic, and difficulty. For open-ended answers, use a clear rubric and inspect disagreements between evaluators. A gain in token probability does not automatically imply better factual answers, and a few attractive samples do not establish broad improvement.
- Report
- Metric
- Test data
- Failure cases
- Evaluation procedure
Use perplexity for the question it actually answers
The numerical example contrasts confident correct and confident wrong token scores. The following sections explain what perplexity measures and what additional checks text and image generators need.
These assigned scores teach the metric. They are not a benchmark comparison between real models.
Can a good average score hide missing examples?
Raise the logit boost while it favors the observed target. Then enable Boost the wrong token and repeat. Compare both metrics. At zero boost, all three tokens are equally probable.
Calculating the example…
Part 1. Choose the Question Before the Metric
1. Separate predictive fit from task success
A response can read well and still give the wrong answer. Before comparing model versions, let's decide what we want the response to accomplish. Correctness on a factual question, following a format, and assigning probability to held-out text require different checks. We will choose a measurement for the job and inspect what it leaves out.
A language model can be evaluated by how much probability it assigns to text that it did not train on. That asks whether its continuation distribution fits held-out language. It does not directly ask whether an answer follows instructions, cites evidence correctly, or solves the user’s problem.
For a factual question with a known answer, correctness may be checked against a reference. Exact string matching can be useful for rigid outputs but rejects valid paraphrases. Open-ended responses need a rubric that states what counts as correct, complete, and useful.
| The question | A measurement that fits it | What it leaves unanswered |
|---|---|---|
| Does the model predict text it has not seen? | The probability it gave the observed next tokens | Whether any answer is correct or useful |
| Is a factual answer right? | Comparison with a reference answer | Whether a valid paraphrase was rejected |
| Is an open-ended response good? | A rubric applied to the response | Anything the rubric did not name |
Three questions about one model. A good result on one row says nothing about the other two.
The paraphrase problem is easy to meet. Take the previous lesson’s question about when the library opens on Saturday, with a reference answer of ten. A response of ten in the morning is right, and it does not match the reference character for character. Exact matching suits outputs that have one correct form, such as a date in a fixed format or a label from a short list.
The first row is the one this page calculates, and it is the one most easily mistaken for the others. A model can become better at predicting ordinary text without becoming more accurate, more obedient to instructions or more careful with sources. Part 2 measures predictive fit. Part 3 returns to the rest.
2. Keep the comparison fair
A comparison is a claim that one thing changed. If the model changed and the prompt changed with it, the difference in score belongs to both, and there is no way to divide it between them afterward. That is the reason for recording every setting, including the ones that seem incidental.
Use comparable test inputs and record the prompt, sampling settings, model version, and scoring procedure. A model that receives source passages is being tested under different conditions from one answering from its parameters alone.
Keep final test examples separate from training and model selection. Repeatedly tuning against the test set turns it into another selection set. Check for near duplicates and shared source material as well as exact overlap.
The usual arrangement gives each part of the data one job.
| Split | What it is used for | How often it is consulted |
|---|---|---|
| Training | Learning the parameters | Throughout training |
| Validation | Choosing settings and comparing versions | As often as needed |
| Test | Estimating final performance | As rarely as possible |
Three roles for three separate sets of examples.
A test set loses its value gradually, not all at once. Each time a change is kept because it scored better on the test examples, the choice has been fitted a little to those particular examples. After enough rounds a high test score partly reports how well the choices suit that set, and the set can no longer say how the model will do on examples nobody has looked at.
Overlap does the same damage from the other side. A test question that also appears in the training data, or appears there with a word changed, or is drawn from the same source document, can be answered from memory. It then measures recall of the training data where it was meant to measure ability on new inputs.
Part 2. Calculate Loss and Perplexity
3. Penalize confidence in the wrong continuation
Start with what the model hands us. At each position of a held-out text it produced a probability for every token in its vocabulary, and we know which token actually came next. The probability it gave that token is the whole of the raw material. A probability near one is a good prediction, and a probability near zero is a bad one.
For every held-out position, record the probability of the observed target. Take its negative natural logarithm and average over scored positions. Perplexity is the exponential of that mean.
The negative logarithm turns those probabilities into a cost. It is zero for a probability of one and grows without limit as the probability falls toward zero, so a confident miss costs far more than a hesitant one. Averaging gives a cost per token, and the exponential converts that average back to a scale that reads like a number of choices.
Mean negative log likelihood = −(1 / N) Σₜ ln pₜ(yₜ)
Perplexity = exp(Mean negative log likelihood)
For three equally probable vocabulary tokens:
p(target) = 1 / 3
Mean loss = −ln(1 / 3) = ln(3)
Perplexity = exp(ln(3)) = 3Lower values mean the model assigned more probability to the observed targets on this evaluation. Perplexity can be understood as an effective average uncertainty, not a literal count of choices considered at every position.
Raising the wrong token’s logit reduces the target probability and increases both metrics. A confidently wrong model can therefore score worse than a less certain one.
The live example makes these numbers by hand. It scores three positions over a vocabulary of three tokens, starts every logit at zero, and adds a boost to one logit in each row. With the boost on the target the model is confidently right. With the boost on another token it is confidently wrong. At a boost of 1 on the target, which is where the example starts, the calculation runs as follows.
p(target) = e¹ / (e¹ + 2) ≈ 0.576
Mean loss = −ln(0.576) ≈ 0.551
Perplexity = exp(0.551) ≈ 1.736| Boost | Placed on | Target probability | Mean loss | Perplexity |
|---|---|---|---|---|
| 0 | no token | 0.333 | 1.099 | 3.000 |
| 1 | the target | 0.576 | 0.551 | 1.736 |
| 2 | the target | 0.787 | 0.240 | 1.271 |
| 4 | the target | 0.965 | 0.036 | 1.037 |
| 1 | a wrong token | 0.212 | 1.551 | 4.718 |
| 2 | a wrong token | 0.107 | 2.240 | 9.389 |
| 4 | a wrong token | 0.018 | 4.036 | 56.598 |
Seven settings of the live example. All three positions receive the same boost, so every position has the same target probability.
Read the perplexity column against the vocabulary of three. A value of 3 is what spreading probability evenly over the three tokens earns. Confidence in the right token brings it down toward 1, which is the floor, reached only by giving the target all of the probability. Confidence in a wrong token sends it past 3, to 4.7, then 9.4, then 56.6.
That last figure is the reason for the warning about counts. There are three tokens, so no model is choosing among 56 of them. When every position has the same target probability, perplexity is one divided by that probability, and 56.6 is one divided by the 0.018 the target was left with. Perplexity reports how surprised the model was by what actually came next. A model can be more surprised than an even guess would have been, and the uniform row at 3 beats every row in which the confidence went to a wrong token.
4. Preserve the units of comparison
Perplexity is measured per token under a particular tokenizer and scoring protocol. Comparing values across different tokenizations or differently masked datasets can be misleading because the prediction units changed.
The dependence on units is arithmetic, and the three-token example shows it. Suppose a text is scored as three tokens at a probability of one third each. Suppose a second tokenizer cuts the same text into six pieces, and the text as a whole receives the same total probability. The total cost is unchanged. The cost per token is halved, because there are twice as many tokens to share it.
Total negative log likelihood = 3 × ln(3) ≈ 3.296
Scored as 3 tokens: exp(3.296 / 3) = 3
Scored as 6 tokens: exp(3.296 / 6) ≈ 1.732Nothing about the model’s grasp of the text differs between those two lines. Only the size of the pieces differs, so a comparison of 3 against 1.732 would be a comparison of tokenizers. The same thing happens when two evaluations score different positions, since a mean over the easy positions and a mean over all of them are different means.
A lower perplexity on one corpus does not establish a better assistant or image generator. Report the data and protocol beside the score, and use task-specific tests for the behaviors that matter.
import numpy as np
from oop_ml.numpy.modern import TokenCrossEntropy
result = TokenCrossEntropy().measure(
np.zeros((3, 3)), np.array([0, 1, 2]),
)
print(result.value)
print(result.perplexity)The snippet scores the uniform case. It prints a mean loss of about 1.0986, which is ln 3, and a perplexity of 3.
Check yourself
Questions on Parts 1 and 2
Question 1 of 5
With three equally probable vocabulary tokens, what is the perplexity at a scored position?
Part 3. Evaluate the Generated Output as Well
5. Check grounded answers and open-ended responses
Everything in Part 2 scored text that someone else wrote. The model was asked how probable it found a continuation, and it never produced one. Once a model generates, there is a new thing to judge, which is the output itself, and the quality of an output is not a probability.
For RAG, ask whether the necessary evidence was retrieved, whether the answer is correct, and whether each cited source supports its claim. These checks distinguish a retrieval miss from an answer-generation error.
Take the previous lesson’s question again, when the library opens on Saturday, and suppose the answer comes with a citation. The three checks are separate, and an answer can pass one and fail another. If the Saturday passage was never retrieved, the first check fails and the model had nothing to work from. If it was retrieved and the answer says nine, the second check fails. If the answer says ten and cites the weekday passage, the answer is correct and the third check fails, because the cited source says nine.
Human evaluators need concrete criteria and examples of how to apply them. Model-based judges also need validation: their preferences can depend on wording, answer order, and response length. Inspect disagreements and error categories instead of treating one judge’s score as ground truth.
A judge is a measuring instrument and can be tested like one. Show it the same two answers in both orders. If its preference follows the position and not the answer, then order is part of what it measures. Rewording the instructions, or padding one answer with empty sentences, tests the other two dependencies the same way. Where the judge and a careful human reader disagree, the disagreements show what the judge is really responding to.
For random generation, evaluate multiple samples and report variation when it matters. A cherry-picked response shows that a behavior is possible, not how reliably it occurs.
The remedy is to count. Draw several samples from the same prompt with the same settings, record how many show the behavior, and report that count beside any example. One good sample among many failures and one good sample among many successes look the same when only the sample is shown.
6. Inspect image quality and distribution coverage
For an image generator, individual realism and coverage of the data distribution are separate concerns. A generator that produces one convincing picture repeatedly has little diversity. Inspect random samples and look for memorization, missing categories, and repeated structures.
The lesson on adversarial networks met this as mode collapse. A generator that has learned to draw one convincing digit passes every inspection of a single picture and fails as a model of handwritten digits. Realism is a property of one picture. Coverage is a property of the whole set of pictures a generator produces, and it can only be judged on a set.
Fréchet Inception Distance, or FID, compares summary statistics of real and generated image features from a particular pretrained network. It is a distribution-level comparison, not a correctness score for one picture. Sample count, preprocessing, reference data, and feature extraction need to be consistent.
Unpacking that helps. A pretrained image network turns each picture into a list of numbers called features. Over many pictures those features have a mean and a spread. The distance compares the mean and spread of the real pictures’ features with the mean and spread of the generated pictures’ features, and a smaller distance says the two sets are distributed more alike. No single picture has a distance, so the measure cannot say which pictures are wrong.
It shares perplexity’s weakness about units. Change the number of samples, the resizing, the reference pictures or the network that extracts the features, and the value changes although the generator has not. Two distances can be compared only when all of those were held the same.
For a conditional generator, also evaluate whether the output matches the requested condition. Neither a low image-distribution distance nor attractive examples alone establishes that the model obeys a text prompt.
The page calculates language-model loss and perplexity only. It does not present FID results or benchmark claims for any trained generator.
Heusel and colleagues introduce FID for comparing generated and real image distributions. GANs Trained by a Two Time-Scale Update Rule Converge to a Local Nash Equilibrium.
Write the Evaluation Set before Looking for a Winner
Choose prompts that represent the intended users and include difficult cases, ambiguous requests and cases with insufficient evidence. Keep prompt sources and near-duplicates separate from model-development data where possible.
Specify the task rubric before comparing outputs. Factual support, completeness, formatting and usefulness are different properties. A single preference score can hide which one changed, especially if an evaluator favours longer answers.
Compare Models on the Same Prompts
Pair each candidate's result with the baseline result on the same prompt. Count improvements, regressions and ties before averaging a score. This retains the fact that some prompts are harder for both models.
The supplied binary task outcomes below demonstrate comparison bookkeeping, not a full evaluation rubric.
Keep wins and regressions visible
A one means the answer passed the declared task check.
import numpy as np
baseline = np.array([1,0,1,0,1,0])
candidate = np.array([1,1,0,1,1,0])
print(int((candidate > baseline).sum()))
print(int((candidate < baseline).sum()))
print(int((candidate == baseline).sum()))2
1
3The candidate improves two prompts and regresses on one. Review those prompts and their categories before treating the net gain as sufficient for release.
An Automatic Judge Is Another Measurement Procedure
A judge model can be sensitive to answer order, verbosity and wording. Human ratings can also vary. Use a clear rubric, blind model identity where practical, check agreement and inspect disagreement cases.
Keep enough labelled examples to compare automatic judging with the task's actual requirements. A judge's confident score is not a substitute for source verification on factual tasks or execution on programming tasks.
Image Quality and Distribution Coverage Need Separate Evidence
Sharp individual images can coexist with missing modes or repeated training examples. Compare representative sample collections, diversity and distribution-sensitive metrics under a stated feature representation and sample size.
No single score establishes that a generator covers every meaningful group or respects every constraint. Preserve failure examples and subgroup results, and repeat stochastic evaluations with declared settings rather than selecting only favourable samples.
Check yourself
Questions on Part 3
Question 1 of 5
What does Fréchet Inception Distance compare?
Try it with Botie
Build with Botie
Write and run Python