Clémentine commited on
Commit
adc672a
·
1 Parent(s): ad0a935
Files changed (22) hide show
  1. app/src/content/article.mdx +79 -12
  2. app/src/content/chapters/2025-evaluations-for-useful-models.mdx +165 -0
  3. app/src/content/chapters/automated-benchmarks/basics.mdx +0 -21
  4. app/src/content/chapters/automated-benchmarks/designing-your-automatic-evaluation.mdx +34 -39
  5. app/src/content/chapters/automated-benchmarks/some-evaluation-datasets.mdx +11 -6
  6. app/src/content/chapters/automated-benchmarks/tips-and-tricks.mdx +24 -37
  7. app/src/content/chapters/general-knowledge/model-inference-and-evaluation.mdx +178 -25
  8. app/src/content/chapters/general-knowledge/tokenization.mdx +0 -76
  9. app/src/content/chapters/human-evaluation/basics.mdx +26 -2
  10. app/src/content/chapters/human-evaluation/tips-and-tricks.mdx +13 -0
  11. app/src/content/chapters/human-evaluation/using-human-annotators.mdx +19 -2
  12. app/src/content/chapters/intro.mdx +71 -57
  13. app/src/content/chapters/model-as-a-judge/basics.mdx +14 -0
  14. app/src/content/chapters/model-as-a-judge/designing-your-evaluation-prompt.mdx +45 -4
  15. app/src/content/chapters/model-as-a-judge/evaluating-your-evaluator.mdx +31 -3
  16. app/src/content/chapters/model-as-a-judge/getting-a-judge-llm.mdx +38 -2
  17. app/src/content/chapters/model-as-a-judge/tips-and-tricks.mdx +22 -3
  18. app/src/content/chapters/model-as-a-judge/what-about-reward-models.mdx +37 -4
  19. app/src/content/chapters/picking-your-evaluation.mdx +156 -85
  20. app/src/content/chapters/troubleshooting/troubleshooting-inference.mdx +29 -1
  21. app/src/content/chapters/troubleshooting/troubleshooting-reproducibility.mdx +43 -7
  22. app/src/content/embeds/d3-decision-tree.html +363 -0
app/src/content/article.mdx CHANGED
@@ -16,9 +16,14 @@ tags:
16
  tableOfContentsAutoCollapse: true
17
  ---
18
 
 
 
 
 
19
  import Intro from "./chapters/intro.mdx";
20
- import AutomatedBenchmarksBasics from "./chapters/automated-benchmarks/basics.mdx";
21
  import DesigningAutomaticEvaluation from "./chapters/automated-benchmarks/designing-your-automatic-evaluation.mdx";
 
 
22
  import AutomatedBenchmarksTips from "./chapters/automated-benchmarks/tips-and-tricks.mdx";
23
  import HumanEvaluationBasics from "./chapters/human-evaluation/basics.mdx";
24
  import UsingHumanAnnotators from "./chapters/human-evaluation/using-human-annotators.mdx";
@@ -32,28 +37,95 @@ import ModelAsJudgeTips from "./chapters/model-as-a-judge/tips-and-tricks.mdx";
32
  import TroubleshootingInference from "./chapters/troubleshooting/troubleshooting-inference.mdx";
33
  import TroubleshootingReproducibility from "./chapters/troubleshooting/troubleshooting-reproducibility.mdx";
34
  import ModelInferenceAndEvaluation from "./chapters/general-knowledge/model-inference-and-evaluation.mdx";
35
- import Tokenization from "./chapters/general-knowledge/tokenization.mdx";
36
 
37
- ## Introduction
 
 
38
  <Intro />
39
 
40
- ## Automated Benchmarks
41
- <AutomatedBenchmarksBasics />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
  <DesigningAutomaticEvaluation />
44
 
45
 
46
  <AutomatedBenchmarksTips />
47
 
48
- ## Human Evaluations
49
  <HumanEvaluationBasics />
50
 
51
  <UsingHumanAnnotators />
52
 
53
  <HumanEvaluationTips />
54
 
55
- ## Model judges
56
 
 
57
  <ModelAsJudgeBasics />
58
 
59
  <GettingJudgeLLM />
@@ -68,10 +140,5 @@ import Tokenization from "./chapters/general-knowledge/tokenization.mdx";
68
 
69
  <TroubleshootingInference />
70
 
71
- <TroubleshootingReproducibility />
72
-
73
- ## Appendix
74
- <ModelInferenceAndEvaluation />
75
 
76
- <Tokenization />
77
 
 
16
  tableOfContentsAutoCollapse: true
17
  ---
18
 
19
+ import Note from "../components/Note.astro";
20
+ import Sidenote from "../components/Sidenote.astro";
21
+ import HtmlEmbed from "../components/HtmlEmbed.astro";
22
+
23
  import Intro from "./chapters/intro.mdx";
 
24
  import DesigningAutomaticEvaluation from "./chapters/automated-benchmarks/designing-your-automatic-evaluation.mdx";
25
+ import PickingYourEval from "./chapters/picking-your-evaluation.mdx";
26
+ import EvalsIn2025 from "./chapters/2025-evaluations-for-useful-models.mdx"
27
  import AutomatedBenchmarksTips from "./chapters/automated-benchmarks/tips-and-tricks.mdx";
28
  import HumanEvaluationBasics from "./chapters/human-evaluation/basics.mdx";
29
  import UsingHumanAnnotators from "./chapters/human-evaluation/using-human-annotators.mdx";
 
37
  import TroubleshootingInference from "./chapters/troubleshooting/troubleshooting-inference.mdx";
38
  import TroubleshootingReproducibility from "./chapters/troubleshooting/troubleshooting-reproducibility.mdx";
39
  import ModelInferenceAndEvaluation from "./chapters/general-knowledge/model-inference-and-evaluation.mdx";
 
40
 
41
+ https://x.com/sasuke___420/status/1984168256568226286
42
+
43
+
44
  <Intro />
45
 
46
+ ## LLM basics to understand evaluation
47
+
48
+ Now that you have an idea of why evaluation is important, and how it's done, let's look at how we prompt models to get some answers out in order to evaluate them. It's very likely you can skim this section if you have already done evaluation.
49
+
50
+ <ModelInferenceAndEvaluation />
51
+
52
+ ## Doing evaluations with existing benchmarks
53
+
54
+ ### State of evaluations in 2025
55
+
56
+ <EvalsIn2025 />
57
+
58
+ ### Understanding what's in an eval
59
+
60
+ Ok, we made a list of benchmarks, now what? Well, now you need to check if these benchmarks are relevant for you and your specific use cases (unless you just want to compare your model to other models, in which case you can skim and go to the next section).
61
+
62
+ The first and most important step is, and always will be, to look at the data. You want to study the following.
63
+
64
+ #### Creation process
65
+ - **Who created the actual samples?**
66
+ Ideally, you want dataset created by experts, then next tier is paid annotators, then crowdsourced, then synthetic, then MTurked. You also want to look for a data card, where you'll find annotator demographics - this can be important to understand the dataset language diversity, or potential cultural bias.
67
+
68
+ - **Were they all examined by other annotators or by the authors?**
69
+ You want to know if the inter-annotator score on samples is high (= are annotators in agreement?) and/or if the full dataset has been examined by the authors.
70
+ This is especially important for datasets with the help of underpaid annotators who usually are not native speakers of your target language (think AWS Mechanical Turk), as you might otherwise find typos/grammatical errors/nonsensical answers.
71
+
72
+ - **Were the annotators provided with clear data creation guidelines?**
73
+ In other words, is your dataset consistent?
74
+
75
+ #### Samples
76
+ Take 50 random samples and manually inspect them; and I mean do it yourself, not "prompt an LLM to find unusual stuff in the data for you".
77
+
78
+ First, you want to check the content quality. Are the prompts clear and unambiguous? Are the answers correct? (*Eg: TriviaQA contains several gold answers (aliases field) per question, sometimes conflicting.*) Is information missing? (*Eg: MMLU misses reference schematics in a number of questions.*) It's important to keep in mind that it's not because a dataset is a standard that it's a good one - and this happens because most people skip this step.
79
+
80
+ Then, you want to check for relevance to your task. Are these questions the kind of questions you want to evaluate an LLM on? Are these examples relevant to your use case?
81
+
82
+ You might also want to check the samples consistency (especially if you're planning on using few shots or computing aggregated statistics): do all samples have the same number of choices if it's a multiple choice evaluation? Is the spacing consistent before and after the prompt? If your evaluation comes with an additional environment, ideally you want to use it to understand tool calls.
83
+
84
+ Lastly, you also want to quickly check how many samples are present there (to make sure results are statistically significant - 100 samples is usually a minimum for automatic benchmarks).
85
+
86
+ TODO: ADD A VIEWER
87
+
88
+ #### Task and metrics
89
+
90
+ You want to check what metrics are used: are they automatic, functional, or using a model judge? The answer will change the cost of running evaluations for you, as well as the reproducibility and bias type.
91
+
92
+ Best (but rarest) metrics are functional or based on rule based verifiers (though beware of pass/fail for coding models and code evaluations, as recent LLMs have become very good at overwriting globals to 'cheat' on such tests, especially in languages like Python where you can mess up variable scope).
93
+
94
+ ### Troubleshooting reproducibility
95
+
96
+ <TroubleshootingReproducibility />
97
+
98
+ ### Selecting good evaluations for ablations
99
+
100
+ <PickingYourEval />
101
+ For these ablations, it's good to focus on tasks that give good early signal and avoid noisy benchmarks. In [FineTasks](https://huggingface.co/spaces/HuggingFaceFW/blogpost-fine-tasks) and [FineWeb2](https://arxiv.org/pdf/2506.20920), reliable evaluation tasks are defined by four key principles:
102
+
103
+ - **Monotonicity:** The benchmark scores should consistently improve as models train longer.
104
+ - **Low noise:** When we train models with the same setup but different random seeds, the benchmark scores shouldn't vary wildly.
105
+ - **Above-random performance:** Many capabilities only emerge later in training, so tasks that show random-level performance for extended periods aren't useful for ablations. This is the case, for example, for MMLU in multiple choice format as we will explain later.
106
+ - **Ranking consistency:** If one approach outperforms another at early stages, this ordering should remain stable as training continues.
107
+
108
+
109
+
110
+ ## So you want to create your own evaluation
111
+
112
+ ### Automated Benchmarks
113
 
114
  <DesigningAutomaticEvaluation />
115
 
116
 
117
  <AutomatedBenchmarksTips />
118
 
119
+ ### Human Evaluations
120
  <HumanEvaluationBasics />
121
 
122
  <UsingHumanAnnotators />
123
 
124
  <HumanEvaluationTips />
125
 
126
+ ### Model judges
127
 
128
+ https://x.com/Kangwook_Lee/status/1993438649963164121
129
  <ModelAsJudgeBasics />
130
 
131
  <GettingJudgeLLM />
 
140
 
141
  <TroubleshootingInference />
142
 
 
 
 
 
143
 
 
144
 
app/src/content/chapters/2025-evaluations-for-useful-models.mdx ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: "2025 evaluations"
3
+ ---
4
+
5
+ import Note from "../../components/Note.astro";
6
+ import Sidenote from "../../components/Sidenote.astro";
7
+
8
+ You can evaluate **specific capabilities** on their own - it's usually quite interesting to get signal when training, or when comparing base/pretrained models. (However, if you select and validate your training methods with the following evaluations, reporting on them on the final model is slightly biased as you have already oriented your training method towards good results on them).
9
+
10
+ #### Reasoning and commonsense
11
+
12
+ Reasoning and commonsense datasets are often “historic” datasets, built in the age of BERT and embeddings model, before the LLM craze. They were quite challenging at the time (especially because they were often adversarially built for models of the time), but now they are 1) too easy 2) contaminated/saturated, and should only be used for ablations or as pretraining evaluations. The bigger datasets also sometimes contain errors or low quality questions as they tend to have been built through Amazon Mechanical Turk in order to scale up fast and at low cost (what is now done by using LLMs to generate evaluation questions).
13
+
14
+ [ARC]([https://arxiv.org/abs/1803.05457](https://arxiv.org/abs/1803.05457)) (2018) (not to confuse with ARC-AGI) is a grade school science MCQA dataset built from human tests. The choices were selected adversarially for word co-occurence systems at the time. It has several subsets, the higher quality `challenge` one is still in use today for pretraining. [WinoGrande]([https://arxiv.org/pdf/1907.10641](https://arxiv.org/pdf/1907.10641)) (2019) is a crowdsourced (mechanical turk + validation) pronoun resolution/fill in the blank dataset, using adversarial pairs of items to trick models. Both these datasets have been quite hard for models until 2022 to 2023.
15
+
16
+ A number of historic datasets are looking specifically at reasoning requiring some sort of commonsense understanding and grounding. [HellaSwag]([https://arxiv.org/abs/1905.07830](https://arxiv.org/abs/1905.07830)) (2019) requires LLMs to select the correct next sentence in a list of adversarial choices, where the text comes from captions in ActivityNet and from tutorials in Wikihow. (It’s the follow up of a dataset called Swag). As most sentences come from tutorials or descriptions of activities, they often require physical commonsense grounding to solve. In the same vein, [CommonsenseQA]([https://arxiv.org/abs/1811.00937](https://arxiv.org/abs/1811.00937)) (2018) is a dataset of commonsense MCQA built from ConceptNet - annotators write questions, then use conceptually close distractors as options. [PIQA]([https://arxiv.org/abs/1911.11641](https://arxiv.org/abs/1911.11641)) (2019) is specifically looking at physical commonsense questions (created from examples from [Instructables.com](http://Instructables.com), with again adversarial choices from semantic perturbations or rewriting). [OpenBookQA]([https://arxiv.org/abs/1809.02789](https://arxiv.org/abs/1809.02789)) (2018) provides open book facts to help answer MCQA questions - however, these questions also require latent common sense knowledge.
17
+
18
+ #### Knowledge
19
+ The main evaluation dataset for knowledge has been [MMLU](https://arxiv.org/abs/2009.03300) (2020). It reached saturation/contamination, and after more in depth examination, a number of issues were identified: incomplete questions referring absent documents, incorrect ground truths, ambiguous questions, and blatant americano-centrism in the topics chosen. It was therefore cleaned in [MMLU-Redux](https://arxiv.org/abs/2406.04127) (2024), extended with more complex questions and more answers in [**MMLU-Pro**](https://arxiv.org/abs/2406.01574) (2024, the main replacement used by the community at the moment), and translated/annotated for cultural bias in [Global-MMLU](https://arxiv.org/abs/2412.03304) (2024). These are used mostly for pretraining evaluations and ablations.
20
+
21
+ For post training, people look at harder high quality knowledge dataset. [**GPQA**](https://arxiv.org/abs/2311.12022) (2023), custom PhD level questions in biology/chemistry/physics, made to be answerable by PhD students in the correct domain and not otherwise. The most used subset is the `diamond` one, but since its publication in 2023 it has also started reaching contamination.
22
+
23
+ Last but not least, the pompously named but very high quality [**Humanity's Last Exam**](https://agi.safe.ai/) (2024) contains 2.5K crowdsourced questions by experts in their field, across domains. It is mostly private, and questions require both complex knowledge and reasoning. It has not been broken yet, and it's imo a cool dataset. The only issue is that since there is no way to get a model scored fast, people now evaluate against it by using an LLM judge to assess their answers, insted of checking against ground truth, so it's one of these evaluations where you'll get really uncomparable results in the wild.
24
+
25
+ However, though testing models for the raw quality of their latent knowledge made a lot of sense a couple years back (and is still interesting while training to test model quality, with evals like MMLU-Pro during pretraining and GPQA/HLE for post training), I think we will slowly phase out of benchmarks such as this in the next years, for 2 reasons.
26
+
27
+ 1. They are becoming more and more indecipherable for humans: questions are becoming so complex that it's almost impossible for non experts to understand what performance on each question means (and to make sure the datasets themselves do not contain mistakes)
28
+ 2. Now that our models are connected to tools, such as internet access, latent knowledge evaluations are increasingly becoming web search and retrieval evaluations, so they make less sense as such. In short, we're moving from closed book to open book evaluations. As a comparison, in the French school system, you get closed books examinations in high school, but as you enter university, it's often assumed that you will get access to databases, internet, and scoring becomes less about what you learnt by heart, and more about how you reason given free access to information. I believe this is also a change we will see in LLM evaluation with the increase of model capabilities.
29
+
30
+ #### Math
31
+ Math evaluation datasets have been used as proxies for reasoning and logic benchmarking, independently of, obviously, also checking if models can solve math problems.
32
+
33
+ The two reference math evaluation datasets were [GSM8K](https://arxiv.org/abs/2110.14168) (2021), containing grade school math problems and [MATH](https://arxiv.org/abs/2103.03874) (2021), an aggregation of Olympiad problems present on the web, which reached saturation/contamination in the last years. The former was extended by [GSM1K](https://arxiv.org/abs/2405.00332) (2024), a recreation with 1K new problems, to test which models were contaminated on the former, [GSM-Plus](https://arxiv.org/pdf/2402.19255), a rewriting of models with adversarial changes (distractors, numerical variations, and so forth) and [GSM-Symbolic](https://arxiv.org/abs/2410.05229) (2024), less used, but a very interesting re-writing of GSM8K as problem templates, to prevent contamination: problems can be regenerated ad infinitum.
34
+
35
+ Community has now been focusing on using:
36
+ - The follow ups to MATH, either [**MATH-500**](https://huggingface.co/datasets/HuggingFaceH4/MATH-500) (a representative subset of 500 problems sampled to avoid overfitting) and MATH-Hard (only the 500 hardest questions)
37
+ - **AIME** ([24](https://huggingface.co/datasets/HuggingFaceH4/aime_2024), [25](https://huggingface.co/datasets/math-ai/aime25)), american olympiad datasets for high schoolers, taken as is at publication. These datasets are interesting because, since they are made of problems renewed every year with equivalent difficulty, they allow testing for contamination by comparing results at publication with results on the previous year's dataset
38
+ - [**Math-Arena**](https://matharena.ai/), an up to date compilation of competitions and olympiads actualised regularly (it contains AIME25, but a lot of other competitions too!)
39
+
40
+ Most of these datasets are actually no longer "that hard", since they stop at grade school level (even though GSM-Symbolic allows to generate problems with more recursion levels, making them synthetically harder). On the other side of the spectrum, [FrontierMath](https://arxiv.org/abs/2411.04872) (2024) was an attempt at providing considerably harder math problems, written individually by mathematicians for the occasion. The dataset was theoretically private (but it appeared OpenAI has had access to parts of the dataset - such a shame). [Humanity's Last Exam](https://agi.safe.ai/) (2025) (introduced in the knowledge section) also contains interesting “made for the occasion” math problems requiring complex reasoning (notably some theorem proving).
41
+
42
+ I would personally use AIME25 and MATH-500 for pretraining evaluations, and the Math-Arena for post training.
43
+
44
+ #### Code
45
+ Since agents need to interact with tools, they need coding abilities, either to call tools directly if they are code agents, or understand how to debug tool output in case of problems (for code and json agents both, see the difference [here](https://huggingface.co/learn/agents-course/en/unit2/smolagents/tool_calling_agents)). Coding evaluation sets are also good proxies for reasoning.
46
+
47
+ Historically in 2021, code evaluation sets were [MBPP](https://arxiv.org/abs/2108.07732), 1K crowdsourced Python only entry-level programming problems, [APPS](https://arxiv.org/abs/2105.09938), 10K code generation problems curated from programming interviews and sharing websites, and [HumanEval](https://arxiv.org/abs/2107.03374), introduced with the Codex model, which contrary to the previous is made of "specifically made for the release" problems, which was super neat then! It also came with a sandbox to avoid problematic code execution on the evaluator's machine. (Last thing this paper introduced was an estimator for `pass@k`, which before that was computed with a literal check on whether an evaluation was a success more than k times on n).
48
+
49
+
50
+ The [EvalPlus](https://openreview.net/pdf?id=1qvx610Cu7) (2023) team made HumanEval+ and MBPP+, extensions of the former, by adding more test cases and fixing bugs in the original datasets as well as adding more inputs. [EvoEval](https://arxiv.org/abs/2403.19114) (2024) also introduced a variation on HumanEval by semantically rewriting the problems and adding difficulty labeling.
51
+
52
+ For final models, you might want harder or uncontaminated problems.
53
+
54
+ [**LiveCodeBench**](https://arxiv.org/abs/2403.07974) (2024) follows a similar "grabbing from leetcode websites" approach, but is very interesting because it stores the problem date, to compare model performance on problems created before and after they finished training. This was an excellent contamination free benchmark, and I'm looking forward to an update!
55
+
56
+ [**AiderBench**](https://aider.chat/docs/leaderboards/) (online since end of 2024 I think?) also uses data from existing coding websites (Exercism to be specific), but goes beyond problem solving by testing specifically code editing and refactoring.
57
+
58
+ For post training, you want more holistic evaluations, and a couple benchmarks moved beyond evaluation on standalone problems, which were not evaluating complex coding abilities. [RepoBench](https://arxiv.org/abs/2306.03091) (2023) tests repository level auto completion systems in Python or Java, using code from Github as source. It was built by masking random lines in code bases and asking for completions, either a cross file or in file function, and defines several tests level (retrieval, completion, a combination).
59
+
60
+ [**SweBench**](https://openreview.net/pdf?id=VTF8yNQM66) (2024) is a more well known and complete version of this, also using github, but this time testing if models can solve existing issues, so logic understanding, cross file editing and execution, long context reasoning, etc.
61
+
62
+ At this time, I would recommend following LiveCodeBench, AiderBench and the higher quality subset of SWE-Bench (SWE-Bench verified), and reading the [METR report](https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/) on actual code assistant usefulness.
63
+
64
+ #### Long context
65
+ To correctly interact with users over a long discussion, without losing track, you need good long context management. (Funny to think that 3 years ago, maximum context lengths for models were 2048 tokens, when now we're largely at 128K and beyond).
66
+
67
+ The evaluation which started testing this in 2023 is probably [NIAH](https://github.com/gkamradt/LLMTest_NeedleInAHaystack), (Needle in a Haystack), where you place a random fact in a long unrelated text and ask the model to retrieve it. It provides a neat framework to evaluate where in the context a model is most likely to forget stuff, and from which context length. In 2023 models were really bad at it, in 2025 it's close to solved.
68
+
69
+ More complex long context extensions have emerged since. [RULER](https://arxiv.org/pdf/2404.06654) (2024) adds multi-hop tracing (requiring the model to follow chains of variables to get the correct value), word frequency changes, and adds a QA variation of NIAH. it's also close to solved now. [Michelangelo](https://arxiv.org/pdf/2409.12640v2) (2024, also sometimes called MRCR for multi round co reference) is also using synthetic long context data: tasks (of varying length) test whether models can reproduce precisely unique portions of the context (as well as identify if relevant information is present) and understand sequence of modifications to a text. It was then extended in the [OpenAI MRCR](https://huggingface.co/datasets/openai/mrcr) (2025). [InfinityBench](https://arxiv.org/abs/2402.13718) (2024) is multilingual (En and Zh), and provides 100K tokens synthetic data tasks, across a variety of objectives (QA, retrieval as in NIAH, computations over very long context, ...). InfinityBench still provides some signal.
70
+
71
+ [**HELMET**](https://arxiv.org/abs/2410.02694) (2024) combines tasks and existing benchmarks to get a big single dataset with more signal: RAG and QA datasets (Natural questions, TriviaQA, PopQA, HotpotQA, Narrative QA and InfinityBench), recall (RULER and JSONKV), generation with citation (subsets of ALCE), summarisation, reranking passages (MS MARCO), in context learning (TREC, NLU, Banking77, CLINIC150). Benchmark aggregations are exhaustive but present the risk of measuring things two times : don't go testing your model against both HELMET and InfinityBench, then aggregating the results, for example, as you would run the same evaluation twice! In 2025, it still has enough discriminative power to compare models.
72
+
73
+ My favorite long context evaluations ideas are the [Novel Challenge](https://arxiv.org/abs/2406.16264) (2024), 1K true/false claims about fictional books published in the last year (by readers of said books!) requiring having read and understood the full text to answer properly, and the [**Kalamang translation dataset**](https://arxiv.org/abs/2309.16575) (2024), where models need to properly translate from English to Kalamang from reading a grammar book (Kalamang is such a low resource language that it has no online presence - only 200 speakers). The Kalamang translation set could notably be expanded to other low resource languages (but it would be cool to expand to use a rule based grammar checker to test generation validity to get strict accuracy instead of relying on BLEU...).
74
+
75
+ #### Instruction Following
76
+ The two main instruction following datasets are [**IFEval**](https://arxiv.org/abs/2311.07911) (2023) and its extension [**IFBench**](https://arxiv.org/abs/2507.02833) (2025). IFEval is one of the smartest evaluation ideas in the last years, in my opinion: models are asked to follow formatting instructions (about keywords, punctuation, number of words/sentences, file type formatting such as markdown or html, etc). Each of these conditions can be checked with a specific parsing test: this means that this evaluation is one of the rare free form generative evaluation where you can get a strict score without relying on a model judge.
77
+
78
+ More generally, it falls into the functional correctness/unit test evaluation type, which is my personal favorite way to evaluate models. It's also very easy to regenerate or extend to prevent contamination.
79
+
80
+ Side note, but some benchmarks also test "non instruction following" (non compliance): [CoCoNot](https://www.arxiv.org/pdf/2407.12043) (2024) notably tests if models will or won't comply with incomplete (underspecified/unclear), unanswerable (by lack of information or AI-humanizing, often hallucinations triggering), or unsafe requests. It used manual queries writing, models to write non compliants requests, then filtered to create an eval set presented as a classification problem.
81
+
82
+ #### Tool-calling
83
+ The emergence of tools is one of the features which started moving LLMs into the agentic realm.
84
+
85
+ [**TauBench**](https://arxiv.org/pdf/2406.12045) (2024) evaluates a model on its ability to answer a user's query in the retail and airline domains (order/book/look for products/etc). The database mimics real domain data with synthetic samples, and the model is considered correct when 1) its actions updated the database correctly and 2) it answered the user appropriately. To make this benchmark automatic, the user is mocked up by an LLM, which makes this evaluation quite costly to run and prone to errors. Despite these limitations, it's quite used, notably because it reflects real use cases well.
86
+
87
+ [ToolBench](https://arxiv.org/pdf/2305.16504) (2023) require calling APIs (OpenWeather, Cat, HomeSearch, TripBooking, GoogleSheets, WebShop, Tabletop, etc) to solve 100 test cases across dataset, requiring between one and 10 tool calls to solve. Some of these APIs are mock ups and some of them are real, which makes the dataset susceptible to accidental failure. It was therefore fixed and extended in [StableToolBench](https://arxiv.org/pdf/2403.07714) (2025), which introduces a general VirtualAPIServer mocking up everything to ensure evaluation stability, however relying on an LLM judge for evaluation, introducing another layer of bias.
88
+
89
+ [**BFCL**](https://openreview.net/pdf?id=2GmDdhBdDk) (2025, but the benchmark actually has a couple years) evolved considerably over the year, and in its current version contains 4 subset: single turn (simple tool calls), crowdsourced real life function calls from users, multiturn conversations (to test accuracy in long context and query answering with tool calls) and agentic (web search, memory, sql data interaction). It's using a combination of Abstract Syntax Trees, execution response and state matching (is the final state the expected one) to evaluate if calls are correct. People are focusing on the v3 to test tool calling specifically, and the v4 tests web and search tool use.
90
+
91
+ Lastly, with the creation of MCPs, some benchmarks arose to test MCP oriented tool calling - however all mostly relying on model judges, and using real world APIs, which can introduce potential failure cases/lack of reproducibility due to network issues (seems like added load for website creators is not too much of an issue as the userbase of most MCP covered is big enough).
92
+
93
+ [MCPBench](https://arxiv.org/abs/2508.20453) (2025) connects LLMs to live, real world MCP servers (Wikipedia, HF, Reddit, Steam, arxiv, ...) with tasks requiring multiple turns to solve (created synthetically). The evaluation combines rule based checks on tool call validity and success with an LLM judge to assess if queries were properly answered.
94
+
95
+ [**MCP-Universe**](https://arxiv.org/abs/2508.14704) (2025) uses 11 MCP servers across varied real world topics (IRL navigation, 3D design, web search, etc). What’s cool in this one is that evaluation relies on several strict evaluators, one for format correctness, and two for answer correctness: as tasks can be static (asking things that do not change) or dynamic (github stars in a repo, weather, …), in the latter case answer correctness uses a task-dependant execution based evaluation framework which grabs the latest correct answer from the relevant source automatically and compares the model output to it. This is way neater than relying on LLM judge!
96
+
97
+ [**LiveMCPBench**](https://arxiv.org/abs/2508.01780) (2025) provides a large locally deployable collection of MCP servers to test how good models are at discriminating between tools to accomplish tasks. Best models are already reaching 80% - so we're close to saturation. However, testing if models can select proper tools in very long lists is a good use case which will be increasingly important as the web goes mcp.
98
+
99
+ (By the way, here's a cool [doc](https://www.anthropic.com/engineering/writing-tools-for-agents) on how to write good tools.)
100
+
101
+ While testing individual capabilities provides valuable signal, real-world assistant performance comes from how these capabilities combine. A model might excel at reasoning but fail when that reasoning must be integrated with tool calling and long context management simultaneously, so we need evaluations requiring the orchestration of multiple capabilities together.
102
+
103
+ #### Assistant tasks
104
+ I believe that **assistant tasks** are going to be one of the main ways to do next level evaluations: solving them requires a combination of many capabilities (long context, reasoning, tool calling, ...), while the benchmarks themselves provide insight on specific domains performance in a useful real world setup. They also tend to be more understandable (by the general public) than specific capabilities benchmarks. If the benchmarks are general enough, they do not check which precise tools were used, but instead if the end result is correct, as complex tasks allow several paths to success.
105
+
106
+ **Real life information retrieval**
107
+
108
+ [**GAIA**](https://arxiv.org/abs/2311.12983) (2023) kickstarted modern agentic evaluation by requiring models to use a combination of tools, reasoning and retrieval to solve real life queries (sometimes including documents). Questions were split in 3 levels, the first one now saturated and the third one still hard for models. It's also one of these benchs were numbers you find will be spread out against evaluation methods, because people are either reporting on the public validation set or using llm judges to evaluate against the private test set (when there is a public leaderboard [here](https://huggingface.co/spaces/gaia-benchmark/leaderboard)).
109
+
110
+ It was later replicated in [BrowseComp](https://cdn.openai.com/pdf/5e10f4ab-d6f7-442e-9508-59515c65e35d/browsecomp.pdf) (2025) which tests the same thing (can a model find the adequate answer to a specific query using tools and online information) but does not guarantee uniqueness of result, as questions were constructed by starting from the result and building a question from it, with varying levels of difficulty: for example, from a specific paper to retrieve, a question will be created by combining information about metadata, for example "which paper about Topic was published at Conference with one Nationality author and two people from Entity?" However, the benchmark is probably also harder at the moment.
111
+
112
+ Lastly, [GAIA2](https://huggingface.co/blog/gaia2) went beyond simple information retrieval, using a mock up mobile environment to test how assistants are able to answer correctly answer queries relying on chains of events and tool calls. As of now, time sensitive and deliberately noisy subsets (mocking up failing API calls) are the hardest for models, when search and execution seem extremely easy for SOTA models.
113
+
114
+ **Science assistants**
115
+
116
+ [SciCode](https://arxiv.org/abs/2407.13168) (2024) tests if models can solve real life scientific problems by writing appropriate scientific code, across stem fields (from biology to math/chem/...). Problems are drawn from real life workflows, and each core issue is decomposed in easier subproblems. For the first version, evaluation was done by scientists and a model judge - models were quite bad at it at publication (less than 5% scores) but I'm unsure where up to date results can be found.
117
+
118
+ [PaperBench](https://arxiv.org/abs/2504.01848) (2025) similarly tests if models can replicate ML research, but this time with a harder setup: given ICML high quality papers, models must reconstruct the matching code base (8K individually graded tasks have been contributed by the authors of said papers, grouped as rubric trees with weighting for the final grades). Benchmark is evaluated with an LLM judge (though I suspect some of it could be done automatically by constraining a bit the shape of the code asked for).
119
+
120
+ [DSBench](https://arxiv.org/pdf/2409.07703) (2025) is a multimodal data analysis benchmark using Kaggle and ModelOff (financial data) samples. From the examples in Appendix it seems that questions from ModelOff are provided in a multiple choice setup, which likely makes the task easier, where the Kaggle tasks each have their own metric.
121
+
122
+ [**DABStep**](https://arxiv.org/abs/2506.23719) (2025) evaluates model on previously private (therefore uncontaminated) operational data analysis workloads using real life questions and data. All problems require multi step reasoning and varied document parsing, as well of course as specific data manipulation skills. It's a neat eval because it's hard and replicates actually useful real world use cases, and because each problem has a ground truth, so evaluation is unbiased and not too costly.
123
+
124
+ Assistant tasks test integrated capabilities in realistic scenarios, but they're either dynamic and read only, or static in environment which doesn't change. To evaluate adaptability and dynamic decision-making, we need environments that can "surprise" the model.
125
+
126
+ #### Game based evaluations
127
+ **Game-based** benchmarks are very interesting for several reasons: they usually evaluate adaptability to a changing environment (contrary to most assistant tasks which are static), require long context reasoning, and last but not least, are **understandable** by most people. However, they are not grounded in real life nor necessary reflecting good performance on actually useful use cases.
128
+
129
+ The most famous formal evaluation among these is probably [ARC-AGI](https://arcprize.org/arc-agi). The first version (2019) was made of puzzles grids in a sequence, where models had to find the last item of said sequence without explicit rules being provided. This benchmark is to me very reminiscent of logic-oriented IQ tests, and it was almost solved in 2024. A similar benchmark (extrapolation of rules) is [Baba is AI](https://arxiv.org/abs/2407.13729) (2024). The latest version of the bench, ARC-AGI3 (2025, ongoing), is still in development, and contains entire new games (requiring exploration, complex planning, memory management, ...) made specifically for the benchmark. It is still ongoing, and current best solutions on available problems are bruteforcing the games.
130
+
131
+ The community and model providers have explored a number of existing games with LLMs. Single player adventure games/RPGs like [TextQuests](https://huggingface.co/blog/textquests) (2025) or [Pokemon](https://github.com/benchflow-ai/benchflow/tree/main/libs/pokemon-gym) (2024) (Twitch for [Claude](https://www.twitch.tv/claudeplayspokemon) and [Gemini](https://www.twitch.tv/gemini_plays_pokemon) for ex) require a combination of very long range planning to get objectives, which require adequante long context memory management, reasoning, and backtracking abilities. Same abilities are needed for single player survival games like [Crafter](https://arxiv.org/abs/2109.06780) (2021, Minecraft inspired). A number of single player game environments have been integrated into the [Balrog](https://arxiv.org/pdf/2411.13543) (2024) benchmark.
132
+
133
+ Competitive bluffing games like [Poker](https://arxiv.org/html/2501.08328v1) (2025) or Mafia variations like [Town of Salem](https://github.com/summersonnn/Town-Of-Salem-with-LLMs) (2025) and Werewolf (2025, [here](https://arxiv.org/abs/2407.13943)/[there](https://werewolf.foaster.ai/)) are very interesting to test logic, reasoning, as well as deception abilities. Claude Opus 4 is for example incapable of winning Town of Salem as a vampire (deceptive role) but does well as a peasant (non deceptive role). Cooperative games like Hanabi can also be used to test adaptability and communication ability in a constrained environment.
134
+
135
+ What's also very neat about these is that they have a single and unambiguous pass/fail metric: did the LLM win the game or not? At the moment, if I were to use these to evaluate models I would probably look at TextQuests for abilities and Town of Salem for safety.
136
+
137
+ Beyond testing capabilities in controlled environments, there's one type of evaluation that's inherently impossible to game: predicting the future. (Ok it's a tangent but I find these super fun and they could be relevant!)
138
+
139
+ #### Forecasters
140
+ In the last year, a new category of impossible to contaminate tasks emerged: forecasting. (I guess technically forecasting on the stock markets can be cheated on by some manipulation but hopefully we're not there yet in terms of financial incentives to mess up evals). They should require a combination of reasoning across sources to try to solve questions about not yet occuring events, but it's uncertain that these benchmarks are discriminative enough to have strong value, and they likely reinforce the "slot machine success" vibe of LLMs. (Is the performance on some events close to random because they are impossible to predict or because models are bad at it? In the other direction, if models are able to predict the event correctly, is the question too easy or too formulaic?)
141
+
142
+ [FutureBench](https://huggingface.co/blog/futurebench) tests if models can predict future news-worthy events. It uses 2 sources: browsing and an LLM generating questions with a weekly time horizon, and user predictions from betting markets. All data is heavily filtered and cleaned before use. For now, models are barely better than random on human created bets, and succeed 3/4th of the time on model generated questions (likely easier).
143
+
144
+ [FutureX](https://arxiv.org/abs/2508.11987) is similar, but uses an array of specific websites (prediction parkets, government websites, general ranking websites and real time data platforms), then uses templates to generate questions about potential future events (`when will STOCK reach POINT?`). 500 questions are generated daily, with filtering of accidentally irrelevant questions.
145
+
146
+ A similar approach is used to generate questions in [Arbitrage](https://arxiv.org/pdf/2412.18544), the core difference being the time horizon: events there should be resolved in 2028.
147
+
148
+ In a similar vein, you'll also find arenas where LLMs are provided with money to actively trade on financial markets - these experiments are less likely to give meaningful results, as, because of their costs, they tend to be run once per model only, so you get no statistical significance there.
149
+
150
+ <Note title="TLDR" emoji="🎯">
151
+ The landscape of evaluation has evolved with the jumps in capabilities, from testing isolated skills to measuring integrated performance in more realistic scenarios.
152
+
153
+ As of Nov 2025, I recommend using:
154
+
155
+ - **Core capabilities** (for model builders): Old capabilities evals for training, and for post training MATH500/AIME24, GPQA, IFEval, SWE-Bench, a long range eval of your choice like HELMET, TauBench or BFCL if you're targetting tool use
156
+ - **Core capabilities** (for comparing models at inference): IFBench, HLE, MathArena, AiderBench and LiveCodeBench, MCP-Universe
157
+ - **Long horizon tasks** (for real-world performance): GAIA, DABStep, SciCode, or domain specific evaluations for your use cases
158
+ - **Games** (for some extra fun in measuring robustness and adaptability): ARC-AGI3 when it's out, TextQuests, Town of Salem if you're interested in safety, or any other game you like which goes beyond Poker/Chess/Go.
159
+
160
+ The field is moving toward evaluations that test capability orchestration rather than isolated skills for actual use. This matches our goal of building models that "work well"—systems that can reliably combine core capabilities, tool use, with a good orchestration to solve actual problems.
161
+
162
+ <Sidenote>
163
+ I hope the field moves towards putting more emphasis on functional testing rather than model judges, and generally understandable datasets and tasks.
164
+ </Sidenote>
165
+ </Note>
app/src/content/chapters/automated-benchmarks/basics.mdx DELETED
@@ -1,21 +0,0 @@
1
- ---
2
- title: "Automated Benchmarks: Basics"
3
- ---
4
-
5
- Automated benchmarks usually works the following way: you'd like to know how well your model performs on something. This something can be a well-defined concrete **task**, such as `How well can my model classify spam from non spam emails?`, or a more abstract and general **capability**, such as `How good is my model at math?`.
6
-
7
- From this, you construct an evaluation, using:
8
- - a **dataset**, made of **samples**.
9
- - These samples contain an input for the model, sometimes coupled with a reference (called gold) to compare the model's output with.
10
- - Samples are usually designed to try to emulate what you want to test the model on: for example, if you are looking at email classification, you create a dataset of spam and non spam emails, try to include some hard edge cases, etc.
11
- - a **metric**.
12
- - The metric is a way to score your model.
13
- Example: how accurately can your model classify spam (score of well classified sample = 1, badly classified = 0).
14
- - Metrics use your model's outputs to do this scoring. In the case of LLMs, people mostly consider two kind of outputs:
15
- - the text generated by the model following the input (*generative evaluation*)
16
- - the log-probability of one or several sequences provided to the model (*multiple-choice evaluations*, sometimes called MCQA, or *perplexity evaluations*)
17
- - For more info on this, you should check out the [Model inference and evaluation](https://github.com/huggingface/evaluation-guidebook/blob/main/contents/general-knowledge/model-inference-and-evaluation.md) page.
18
-
19
- This is more interesting to do on data that the model has never been exposed to before (data absent from the model training set), because you want to test if it **generalizes** well. For example, if it can classify spam emails about 'health' products after having seen only spam emails about fake banks.
20
-
21
- Note: *A model which can only predict well on its training data (and has not latently learnt more high-level general patterns) is said to be **overfitting**. Similarly to a student who learned test questions by heart without understanding the topic, evaluating LLMs on data that was already present in their training set is scoring them on capabilities they do not possess.*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/src/content/chapters/automated-benchmarks/designing-your-automatic-evaluation.mdx CHANGED
@@ -2,48 +2,24 @@
2
  title: "Designing your automatic evaluation"
3
  ---
4
 
 
 
 
5
  ### Designing your automatic evaluation
6
 
7
 
8
  #### Selecting or creating a dataset
9
  For your evaluation, you can either select an existing dataset or design your own. Through this process, it's very important to keep in mind that **your evaluation result will only be as good as your evaluation dataset**.
10
 
11
- ##### Inspecting an existing dataset.
12
-
13
- You want to study the following.
14
-
15
- 1. Creation process
16
- - **Who created the actual samples?**
17
- Imo, expert created dataset > paid annotator dataset ~ crowdsourced dataset > MTurked dataset.
18
- You also want to look for a data card, where you'll find annotator demographics - this can be important to understand the dataset language diversity.
19
-
20
- - **Were they all examined by other annotators or by the authors?**
21
- You want to know:
22
- - if the inter-annotator score on samples is high (= are annotators in agreement?)
23
- - and/or if the full dataset has been examined by the authors.
24
- This is especially important for datasets with the help of underpaid annotators who usually are not native speakers of your target language (think AWS Mechanical Turk), as you might otherwise find typos/grammatical errors/nonsensical answers.
25
-
26
- - **Were the annotators provided with clear data creation guidelines?**
27
- In other words, is your dataset consistent?
28
-
29
- 2. Samples
30
- Take 50 random samples and manually inspect them:
31
- - *For quality*:
32
- - are the prompts clear and unambiguous?
33
- - are the answers correct? (*Eg: TriviaQA contains several gold answers (aliases field) per question, sometimes conflicting.*)
34
- - is information missing? (*Eg: MMLU misses reference schematics in a number of questions.*)
35
- - *For relevance to your task*:
36
- - are these
37
- questions the kind of questions you want to evaluate an LLM on?
38
- - are these examples relevant to your use case?
39
-
40
- 3. Quantity
41
- You also want to know how many samples are present there (to make sure results are statistically significant - 100 samples is usually a minimum for automatic benchmarks).
42
-
43
  ##### Designing your own
44
- You can go 3 ways when designing your own dataset.
45
  - **Aggregating existing data**: You can aggregate existing data from different sources, evaluating a relevant capability for your task. A number of evaluation datasets are for example constructed from aggregating human evaluation datasets (such as MATH, LSAT, etc). In this case, follow the steps above.
46
  - **Using human annotators**: There's a whole section on using human annotators in `Human evaluation`, see [Using human annotators](https://github.com/huggingface/evaluation-guidebook/blob/main/contents/human-evaluation/using-human-annotators.md).
 
 
 
 
 
47
  - **Using synthetic data from models**: On this, you can check the very cool [Cosmopedia](https://huggingface.co/blog/cosmopedia) blog by cool HF colleagues! It's mostly studying how to create a synthetic training dataset, but similar techniques can be used for evaluation. Make sure to manually check/filter/inspect your dataset afterwards (following the above steps).
48
  - **Using rule-based techniques**: If your task allows, this is a very good way to get a virtually infinite supply of samples and avoid contamination! For some examples, you can look at [NPHardEval](https://arxiv.org/abs/2312.14890), [DyVal](https://arxiv.org/abs/2309.17167), [MuSR](https://arxiv.org/abs/2310.16049), [BabiQA](https://arxiv.org/abs/1502.05698), etc.
49
 
@@ -56,7 +32,7 @@ Using log-probabilities (MCQA, multi-choice question answer) is very good for mu
56
  - Provides a proxy for model "confidence" (and calibration)
57
  - Fast to evaluate, especially when we ask the model to predict only one token (A/B/C/D the indices of the choices, or Yes/No, etc).
58
  - Allow to get signal on small models' task performance
59
- - Cons:
60
  - Slightly over-scores small models which would have generated something outside of the range of available choices if given free rein.
61
  - Some models [favor specific choices based on the order in which they have been presented](https://arxiv.org/abs/2309.03882), which could lead to unrepresentative evaluations
62
 
@@ -86,19 +62,29 @@ When defining your prompt, you need to be aware that:
86
  - A costly way is to re-run the evaluation several times with prompt variations
87
  - A less costly way is to run your evaluation once using a range of prompt formats allocated to different samples of equivalent difficulty
88
  - you can provide examples to your model to help it follow the expected format (using few-shot examples), and adding connector words helps this overall
89
- - but models now tend to overfit specific prompt formats.
90
  - [This paper](https://arxiv.org/abs/2407.07890) is great on the topic, showing notably how some models can be over-evaluated because they have overfitted the test set **format**
91
  - On the Open LLM Leaderboard 2, we've notably observed that Llama 3.2 and Qwen 2.5 are no longer following the format of the prompt provided in a few-shot setup for this reason.
 
 
 
 
 
92
  - for a number of metrics, you want a very constrained generation or output.
93
  *You can learn more about this in the `Constraining model outputs` section of the [Model inference and evaluation](https://github.com/huggingface/evaluation-guidebook/blob/main/contents/general-knowledge/model-inference-and-evaluation.md) page.*
94
 
95
  #### Choosing a metric
96
  If you are looking at **log-probabilities**, your metrics are going to be easy: you'll want to look at accuracy (how often the most likely choice is the best choice). It's important to normalize it by length (either character, token, or pmi). You could also look at perplexity, recall, or f1 score.
97
 
98
- For **generative** evaluations, your range of metrics is going to be wider.
99
- You'll need to
100
- 1. decide if you compare generations as they are, or first normalize them with something.
101
  - Normalizations can easily [be unfair if not designed well](https://huggingface.co/blog/open-llm-leaderboard-drop), but overall they still provide signal at the task level.
 
 
 
 
 
102
  - They are very important for specific tasks, such as math evaluations, where you might want to extract your result from formatted outputs.
103
  - They will also be important if you want to evaluate with added mechanisms for accuracy, such as Chain of Thought, as you'll need to remove the reasoning trace from the actual result
104
  2. decide how you compare the generation with the reference.
@@ -109,11 +95,20 @@ More generally, when picking your metric, you need to keep in mind what your tas
109
  #### Smart new tasks: what about functional testing?
110
  In the field of code, you want to evaluate generated programs not only on their semantics, but on their actual function. A good way to do so is therefore to check if code generated to follow a prompt passes correctly a suite of unit-tests designed to fit the task.
111
 
112
- This functionality approach is extremely promising, as it
113
  - allows to generate test cases more easily (in many cases, you can generate rule-based test cases)
114
  - therefore reducing overfitting
115
  - tests models on specific active capabilities
116
 
 
 
 
 
 
 
 
 
 
117
  It's however an approach which requires creativity to be translated to text!
118
 
119
  A good example of this is IFEval, an evaluation benchmark which tests if models can follow instructions. It works by creating a number of formatting instructions (*Add this number of bullet points. Capitalize only one sentence.* etc), and strictly testing if the format is followed. More work is clearly needed to extend this idea to other features of text to analyze!
 
2
  title: "Designing your automatic evaluation"
3
  ---
4
 
5
+ import Note from "../../../components/Note.astro";
6
+ import Sidenote from "../../../components/Sidenote.astro";
7
+
8
  ### Designing your automatic evaluation
9
 
10
 
11
  #### Selecting or creating a dataset
12
  For your evaluation, you can either select an existing dataset or design your own. Through this process, it's very important to keep in mind that **your evaluation result will only be as good as your evaluation dataset**.
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  ##### Designing your own
15
+ You can go 3 ways when designing your own dataset.
16
  - **Aggregating existing data**: You can aggregate existing data from different sources, evaluating a relevant capability for your task. A number of evaluation datasets are for example constructed from aggregating human evaluation datasets (such as MATH, LSAT, etc). In this case, follow the steps above.
17
  - **Using human annotators**: There's a whole section on using human annotators in `Human evaluation`, see [Using human annotators](https://github.com/huggingface/evaluation-guidebook/blob/main/contents/human-evaluation/using-human-annotators.md).
18
+
19
+ <Note title="See also" emoji="👥" variant="info">
20
+
21
+ For detailed guidance on using human annotators to create evaluation datasets, see the [Using human annotators](/human-evaluation/using-human-annotators) section.
22
+ </Note>
23
  - **Using synthetic data from models**: On this, you can check the very cool [Cosmopedia](https://huggingface.co/blog/cosmopedia) blog by cool HF colleagues! It's mostly studying how to create a synthetic training dataset, but similar techniques can be used for evaluation. Make sure to manually check/filter/inspect your dataset afterwards (following the above steps).
24
  - **Using rule-based techniques**: If your task allows, this is a very good way to get a virtually infinite supply of samples and avoid contamination! For some examples, you can look at [NPHardEval](https://arxiv.org/abs/2312.14890), [DyVal](https://arxiv.org/abs/2309.17167), [MuSR](https://arxiv.org/abs/2310.16049), [BabiQA](https://arxiv.org/abs/1502.05698), etc.
25
 
 
32
  - Provides a proxy for model "confidence" (and calibration)
33
  - Fast to evaluate, especially when we ask the model to predict only one token (A/B/C/D the indices of the choices, or Yes/No, etc).
34
  - Allow to get signal on small models' task performance
35
+ - Cons:
36
  - Slightly over-scores small models which would have generated something outside of the range of available choices if given free rein.
37
  - Some models [favor specific choices based on the order in which they have been presented](https://arxiv.org/abs/2309.03882), which could lead to unrepresentative evaluations
38
 
 
62
  - A costly way is to re-run the evaluation several times with prompt variations
63
  - A less costly way is to run your evaluation once using a range of prompt formats allocated to different samples of equivalent difficulty
64
  - you can provide examples to your model to help it follow the expected format (using few-shot examples), and adding connector words helps this overall
65
+ - but models now tend to overfit specific prompt formats.
66
  - [This paper](https://arxiv.org/abs/2407.07890) is great on the topic, showing notably how some models can be over-evaluated because they have overfitted the test set **format**
67
  - On the Open LLM Leaderboard 2, we've notably observed that Llama 3.2 and Qwen 2.5 are no longer following the format of the prompt provided in a few-shot setup for this reason.
68
+
69
+ <Note title="Models can overfit prompt formats" emoji="⚠️" variant="warning">
70
+
71
+ Recent research shows models can overfit specific prompt formats rather than learning the underlying task. [This paper](https://arxiv.org/abs/2407.07890) demonstrates how some models are over-evaluated because they've memorized test set formats. We've observed Llama 3.2 and Qwen 2.5 no longer following few-shot prompt formats for this reason.
72
+ </Note>
73
  - for a number of metrics, you want a very constrained generation or output.
74
  *You can learn more about this in the `Constraining model outputs` section of the [Model inference and evaluation](https://github.com/huggingface/evaluation-guidebook/blob/main/contents/general-knowledge/model-inference-and-evaluation.md) page.*
75
 
76
  #### Choosing a metric
77
  If you are looking at **log-probabilities**, your metrics are going to be easy: you'll want to look at accuracy (how often the most likely choice is the best choice). It's important to normalize it by length (either character, token, or pmi). You could also look at perplexity, recall, or f1 score.
78
 
79
+ For **generative** evaluations, your range of metrics is going to be wider.
80
+ You'll need to
81
+ 1. decide if you compare generations as they are, or first normalize them with something.
82
  - Normalizations can easily [be unfair if not designed well](https://huggingface.co/blog/open-llm-leaderboard-drop), but overall they still provide signal at the task level.
83
+
84
+ <Sidenote>
85
+
86
+ Normalizations can [be unfair if not designed well](https://huggingface.co/blog/open-llm-leaderboard-drop), though they generally provide useful signal. Design normalization rules carefully and test them across diverse model outputs.
87
+ </Sidenote>
88
  - They are very important for specific tasks, such as math evaluations, where you might want to extract your result from formatted outputs.
89
  - They will also be important if you want to evaluate with added mechanisms for accuracy, such as Chain of Thought, as you'll need to remove the reasoning trace from the actual result
90
  2. decide how you compare the generation with the reference.
 
95
  #### Smart new tasks: what about functional testing?
96
  In the field of code, you want to evaluate generated programs not only on their semantics, but on their actual function. A good way to do so is therefore to check if code generated to follow a prompt passes correctly a suite of unit-tests designed to fit the task.
97
 
98
+ This functionality approach is extremely promising, as it
99
  - allows to generate test cases more easily (in many cases, you can generate rule-based test cases)
100
  - therefore reducing overfitting
101
  - tests models on specific active capabilities
102
 
103
+ <Note title="The promise of functional testing" emoji="✨" variant="success">
104
+
105
+ Functional testing (like unit tests for code) offers major advantages:
106
+ - Easier test case generation (often rule-based)
107
+ - Reduces overfitting risk
108
+ - Tests specific active capabilities
109
+ - Extends beyond code to other domains (e.g., IFEval for instruction following)
110
+ </Note>
111
+
112
  It's however an approach which requires creativity to be translated to text!
113
 
114
  A good example of this is IFEval, an evaluation benchmark which tests if models can follow instructions. It works by creating a number of formatting instructions (*Add this number of bullet points. Capitalize only one sentence.* etc), and strictly testing if the format is followed. More work is clearly needed to extend this idea to other features of text to analyze!
app/src/content/chapters/automated-benchmarks/some-evaluation-datasets.mdx CHANGED
@@ -2,17 +2,22 @@
2
  title: "Some evaluation datasets"
3
  ---
4
 
 
 
5
  ### Some evaluation datasets
6
 
7
  If the task you are interested is already well studied, chances are that a dataset exists for it.
8
 
9
- Below are a number of evaluation datasets which were developed in the last few years.
 
 
 
 
 
 
10
 
11
- However, careful:
12
- - Some of them can be obsolete, as they were designed pre-LLM and are now easily solved: they aimed to investigate one specific property of text (translation, summarization) which is no longer really how we evaluate models (evaluations are now more general/holistic).
13
- (*If you've got some bandwidth, this could really benefit from adding the publication dates!*)
14
- (*This will also be updated with post LLM evals at some point*)
15
- - They are likely contaminated, as they have been publicly on the web for a number of years. However, it doesn't mean they won't hold signal for your task!
16
 
17
  ### Math specific datasets
18
 
 
2
  title: "Some evaluation datasets"
3
  ---
4
 
5
+ import Note from "../../../components/Note.astro";
6
+
7
  ### Some evaluation datasets
8
 
9
  If the task you are interested is already well studied, chances are that a dataset exists for it.
10
 
11
+ Below are a number of evaluation datasets which were developed in the last few years.
12
+
13
+ <Note title="Caveat: Dataset age and contamination" emoji="⚠️" variant="warning">
14
+
15
+ Many datasets listed here may be:
16
+ - **Obsolete**: Designed pre-LLM for specific properties (translation, summarization) no longer central to model evaluation
17
+ - **Contaminated**: Publicly available for years, likely in training data
18
 
19
+ However, contamination doesn't mean these datasets have no signal for your task!
20
+ </Note>
 
 
 
21
 
22
  ### Math specific datasets
23
 
app/src/content/chapters/automated-benchmarks/tips-and-tricks.mdx CHANGED
@@ -2,6 +2,9 @@
2
  title: "Automated Benchmarks: Tips and tricks"
3
  ---
4
 
 
 
 
5
 
6
  ### Pros and cons of using automated benchmarks
7
  Automated benchmarks have the following advantages:
@@ -11,6 +14,11 @@ Automated benchmarks have the following advantages:
11
  *Eg: an exact match will tell you if the generated text matches perfectly with the reference, and an accuracy score will tell you in how many cases the selected choice was the correct one (this will be a bit less the case for metrics such as `BLEU` or `ROUGE` for example).*
12
  - **Dataset quality**: A number of automated benchmarks are using expert generated datasets or pre-existing high quality data (like MMLU or MATH). However, this does not mean these datasets are perfect: for MMLU, several errors have been identified in samples afterwards, from parsing issues to actually non-sensical questions, leading to the creation of several follow-up datasets, like MMLU-Pro and MMLU-Redux.
13
 
 
 
 
 
 
14
  However, they also present the following limitations:
15
  - **Reduced use on more complex tasks**: Automated benchmarks are working well for tasks where performance is easy to define and assess (for example, classification). More complex capabilities, on the other hand, are harder to decompose into well-defined and precise tasks.
16
  *Eg: what does "good at math" mean? Is it being good at arithmetic? - at logic? - able to reason on new mathematical concepts?*
@@ -21,7 +29,12 @@ However, they also present the following limitations:
21
  ### Tips and tricks
22
 
23
  #### Managing contamination
24
- In general, you should assume that a dataset publicly available on the internet is or will be contaminated.
 
 
 
 
 
25
 
26
  Solutions to mitigate this include:
27
  - providing a **canary string** in the evaluation set (like in [BigBench](https://github.com/google/BIG-bench)): it is a specific character combination that model creators can look for in their training sets, which would indicate that it contains an evaluation
@@ -29,48 +42,22 @@ Solutions to mitigate this include:
29
  - running [dynamic benchmarks](https://arxiv.org/abs/2104.14337): benchmarks regularly updated through time so that models can't "learn the answers by heart" (but it makes datasets more costly)
30
  - if you are running a benchmark, trying to [detect contamination](https://arxiv.org/abs/2311.06233) post-hoc (for example, by looking at the generation perplexity or designing adversarial versions of the prompts - however, no method is a foolproof contamination detection method)
31
 
32
- However, it's not because a dataset is contaminated that it won't still be interesting and have signal during training.
33
-
34
- #### Managing fine-tuned models, system prompts and chat templates
35
- Pre-2022, models used to simply be pretrained: text in, text out, nothing else. Then, we got instruction tuning and chat models in 2023, and in 2025 reasoning models. This means that we went from using text "as is" to using chat templates (= providing models with json) to using reasoning tags (= mixing up the json chat template with xml tags for reasoning).
36
-
37
- This means a number of models are going to perform terribly if you do not make sure to:
38
- - add their system prompt at the very beginning of inference
39
- - prompt them using a chat template if they require it (usually adding `Assistant` and `User` prefixes to the dialogue turns - learn more about this in [this cool guide](https://huggingface.co/docs/transformers/main/en/chat_templating))
40
- - remove the thinking trace from the model answer before processing it (you can usually regex to remove what's between the `<think>` tags)
41
-
42
- It's also very important to not assume that different tokenizers will behave the same,as you can see in this cool picture about tokenization spacing and chat templates, from [this tweet](https://x.com/danielhanchen/status/1796952220619157694).
43
-
44
- ![Spacing, tokenization and template](https://pbs.twimg.com/media/GPANfpiasAA9b6F?format=png&name=medium)
45
-
46
- #### Beware of tokenization
47
-
48
- 1. **Tokenizing the context and choices together or separately**
49
 
50
- When looking at an MCQA evaluation, in general, you want to tokenize the context together with the choices, as it creates a succession of tokens which is likely/natural for the model.
 
51
 
52
- However, some tokenizers (like the [Llama one](https://github.com/EleutherAI/lm-evaluation-harness/pull/531#issuecomment-1595586257)) do not satisfy `enc(context + choice) = enc(context) + enc(choice)` (and add or remove spacing). This means that comparing the logprobabilities of the choices is not easy, as the context tokens can "bleed out" into them, messing up the comparison.
53
-
54
- So if this is the case for your model, you might want to compute the tokens of context and choice separately and then concatenate them after removing the special start/end of sentence tokens which might have been added.
55
-
56
- 2. **Paying attention to start and end of sentence tokens**
57
-
58
- Some models, like the `Gemma` ones, are extremely sensitive to the [inclusion of start of sentence tokens](https://github.com/EleutherAI/lm-evaluation-harness/pull/1465) at inference. You might need to do a couple of experiments to see if that happens for you, and add these tokens manually when evaluating.
59
-
60
- You can also encounter some issues where your model won't stop on an end of sentence token like you would expect (for example, on `\n`), because your model will not predict this token alone but included in an higher level token (for example, `\n\n`, which can be a single token, especially for code models). In this case, you might need to add a specific check to "backtrack" on generated text to make sure you're cutting your generated sentence at the proper spot before computing metrics.
61
-
62
- 3. **Multilinguality and tokenization**
63
-
64
- When looking at multilingual evaluations, you'll also need to see how to tokenize your text, depending on your evaluation task and metrics. As some languages do not always use spacing as a word separator (Korean, Thai, Japanese, Chinese, to cite a few), they will require language specific tokenizers to be split properly, else it will affect their scores on metrics such as [BLEU](https://github.com/EleutherAI/lm-evaluation-harness/issues/212), F1 scores, etc.
65
-
66
- 4. **Code evaluations and end of sentence tokens**
67
-
68
- Code models usually have been trained with `\n\t` as a single token. This means that when generating text, they will often generate `\n\t` in one step. A task which defines `\n` as an end of sentence token (= to stop the generation) will let the model continue generating after a `\n\t`, if predicted as one token, since it's not the same as `\n`. But you would actually still want the model to stop. In these cases, you either need to update your end of sentence tokens, or define a mechanism to backtrack on the character representation of the latest tokens to stop (and cut) the generation a posteriori.
69
 
70
  #### Tip: an easy speed up for MCQA evaluations
71
  You can speed up your MCQA predictions by a lot if you make sure your model needs to predict only one token for the task.
72
 
73
- This way, instead of running your `number_of_choices` predictions (`context + choice 1`, `context + choice 2`, etc), you can simply run inference on `context` and compute the probability distribution on the full vocabulary (which will include all your one token choices) to get your logprobabilities of interest, and do this step in one pass.
 
 
 
 
 
74
 
75
  (That's how we do it in `lighteval`).
76
 
 
2
  title: "Automated Benchmarks: Tips and tricks"
3
  ---
4
 
5
+ import Note from "../../../components/Note.astro";
6
+ import Sidenote from "../../../components/Sidenote.astro";
7
+
8
 
9
  ### Pros and cons of using automated benchmarks
10
  Automated benchmarks have the following advantages:
 
14
  *Eg: an exact match will tell you if the generated text matches perfectly with the reference, and an accuracy score will tell you in how many cases the selected choice was the correct one (this will be a bit less the case for metrics such as `BLEU` or `ROUGE` for example).*
15
  - **Dataset quality**: A number of automated benchmarks are using expert generated datasets or pre-existing high quality data (like MMLU or MATH). However, this does not mean these datasets are perfect: for MMLU, several errors have been identified in samples afterwards, from parsing issues to actually non-sensical questions, leading to the creation of several follow-up datasets, like MMLU-Pro and MMLU-Redux.
16
 
17
+ <Sidenote>
18
+
19
+ Several errors in MMLU (parsing issues, nonsensical questions) led to improved versions like MMLU-Pro and MMLU-Redux. Always inspect benchmark samples manually before relying on them for evaluation.
20
+ </Sidenote>
21
+
22
  However, they also present the following limitations:
23
  - **Reduced use on more complex tasks**: Automated benchmarks are working well for tasks where performance is easy to define and assess (for example, classification). More complex capabilities, on the other hand, are harder to decompose into well-defined and precise tasks.
24
  *Eg: what does "good at math" mean? Is it being good at arithmetic? - at logic? - able to reason on new mathematical concepts?*
 
29
  ### Tips and tricks
30
 
31
  #### Managing contamination
32
+ In general, you should assume that a dataset publicly available on the internet is or will be contaminated.
33
+
34
+ <Note title="Assume contamination" emoji="🔍" variant="warning">
35
+
36
+ You should assume that any dataset publicly available on the internet is or will be contaminated in model training data. Design your evaluation strategy with this assumption in mind.
37
+ </Note>
38
 
39
  Solutions to mitigate this include:
40
  - providing a **canary string** in the evaluation set (like in [BigBench](https://github.com/google/BIG-bench)): it is a specific character combination that model creators can look for in their training sets, which would indicate that it contains an evaluation
 
42
  - running [dynamic benchmarks](https://arxiv.org/abs/2104.14337): benchmarks regularly updated through time so that models can't "learn the answers by heart" (but it makes datasets more costly)
43
  - if you are running a benchmark, trying to [detect contamination](https://arxiv.org/abs/2311.06233) post-hoc (for example, by looking at the generation perplexity or designing adversarial versions of the prompts - however, no method is a foolproof contamination detection method)
44
 
45
+ <Sidenote>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
+ Even contaminated datasets can provide useful signal during training. Performance improvements on contaminated benchmarks often correlate with genuine capability improvements, though the absolute scores may be inflated.
48
+ </Sidenote>
49
 
50
+ However, it's not because a dataset is contaminated that it won't still be interesting and have signal during training.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
  #### Tip: an easy speed up for MCQA evaluations
53
  You can speed up your MCQA predictions by a lot if you make sure your model needs to predict only one token for the task.
54
 
55
+ This way, instead of running your `number_of_choices` predictions (`context + choice 1`, `context + choice 2`, etc), you can simply run inference on `context` and compute the probability distribution on the full vocabulary (which will include all your one token choices) to get your logprobabilities of interest, and do this step in one pass.
56
+
57
+ <Note title="Speed optimization for MCQA" emoji="⚡" variant="success">
58
+
59
+ Speed up MCQA evaluations by using single-token choices. Instead of running N predictions for N choices, run inference once on the context and examine the probability distribution over all vocabulary tokens (which includes your choices). This is how `lighteval` achieves fast MCQA evaluation.
60
+ </Note>
61
 
62
  (That's how we do it in `lighteval`).
63
 
app/src/content/chapters/general-knowledge/model-inference-and-evaluation.mdx CHANGED
@@ -6,27 +6,150 @@ import llmTk1 from '../../assets/image/llm_tk_1.png';
6
  import llmLogprob from '../../assets/image/llm_logprob.png';
7
  import llmGen from '../../assets/image/llm_gen.png';
8
  import Image from '../../../components/Image.astro';
 
 
 
9
 
10
- ### Model inference and evaluation
11
-
12
- ### Introduction
13
  Current large language model work in a simple way: given some text as input, they have learned to predict plausible follow up.
14
 
15
  This is done in two steps.
16
  ### Tokenization
17
- The input text (called a *prompt* at inference) is first split into *tokens*, small units of texts (which can be one or several characters, up to the word level) each associated with a number. The whole range of tokens a model can parse is called its *vocabulary*. *(To understand this more in depth, go read the [Tokenization](https://github.com/huggingface/evaluation-guidebook/blob/main/contents/general-knowledge/tokenization.md) page)*.
18
 
19
- ### Prediction
 
20
 
21
- <Image src={llmTk1} alt="LLM tokenization and prediction process" />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
  From this input text, the LLM generates a probability distribution of the most likely next tokens over all the vocabulary. To get a continued generation, we can take the most probable token (give or take some added randomness to get more interesting outputs) as the next one, then repeat the operation, using the new token as the end of the prompt, etc.
24
 
25
- ### What do you want to predict?
26
- LLM evaluations mostly fall into 2 categories:
27
- - Given a prompt and one (or several) answers, what is probability of said answer(s) for my model?
28
- - Given a prompt, what text does my model generate?
29
- ### Log-likelihood evaluations
 
 
 
 
 
 
 
 
 
30
  For log-likelihood evaluations, we want the conditional probability of one or several choices given a prompt - in other terms, what is the likelihood to get a specific continuation given an input?
31
  So:
32
  - we concatenate each choice with the prompt, and pass them to our LLM, which outputs the logits of each token depending on the previous ones
@@ -40,41 +163,71 @@ This allows us to apply one of the following metrics:
40
  - get the preferred answer of a model among several choice, like in the above picture. (*However, this can advantage scores of models which would have, freely, generated something else, like `Zygote` in the picture.*)
41
  - test if a single choice has a probability above 0.5
42
  - study model calibration. A well calibrated model is a model for which the correct answers have the highest probabilities.
43
- *(To learn more about calibration, you can check [this paper](https://arxiv.org/abs/2207.05221) from Anthropic, on what it is, how to detect it, and how to train models to be well calibrated, and [this paper](https://arxiv.org/abs/2311.14648) on some possible limits of calibration).*
 
 
 
 
 
 
 
 
 
 
44
 
45
- ### Generative evaluations
 
 
 
 
 
 
 
 
 
 
46
  For a generative evaluation, we want the text generated by the model given an input prompt.
47
 
48
  It is obtained in an auto-regressive way: we pass the prompt to the model, look at the most likely next token, select it as being the model's "choice first token", then repeat until we reach an end of generation condition (maximum length, special token to stop the generation, etc). All the tokens generated by the model are consider its answer to the prompt.
49
 
50
  <Image src={llmGen} alt="LLM generative evaluation process" />
51
 
52
-
53
-
54
  We can then compare this generation with references and score the distance between both (using either simple metrics like exact match, more complex metrics like BLEU, or models as judges).
55
 
56
- ### Going further
57
- - ⭐ [Blog on several ways to evaluate MMLU](https://huggingface.co/blog/open-llm-leaderboard-mmlu) , by my team at Hugging Face. I recommend reading it if you want to delve deeper into the differences between multi choice log-likelihood evaluations and generative ones, including what it can mean with respect to score changes
58
- - The above illustrations come from the blog and have been made by Thom Wolf
59
  - ⭐ [A beautiful mathematical formalization of the above inference methods](https://arxiv.org/abs/2405.14782v2), from EleutherAI. Go to the Appendix directly.
 
 
 
60
  ### Constraining model outputs
61
  In a number of cases, we want the model output to follow a specific format, for example to compare them to a reference.
62
- ### Using a prompt
 
63
  The easiest way to do this is to add a task prompt which contains very specific instructions as to how the model should answer (`Provide numerical answers in digits.`,`Use no abbreviation.`, etc).
64
 
65
- It won't necessarily work all the time but should be good enough for high capability models. That's the approach we followed in the [GAIA](https://huggingface.co/papers/2311.12983) paper, and you can find our task prompt in the Submission tab of the [leaderboard](https://huggingface.co/spaces/gaia-benchmark/leaderboard) if you want some inspiration.
66
- ### Few shots and in context learning
 
67
  The next way to do so is to constrain the model through what is called "in context learning". By providing examples in the prompt (what is called `few-shot prompting`), the model is implicitly biased towards following the repeated prompt shape for the actual sample.
68
 
69
- It's a method which was overall working quite well until end of 2023! However, the widespread adoption of instruction-tuning methods and the addition of instruction data in later stages of model pre-training (continuous pre-training) seem to have biased more recent models towards specific output formats (what is being called [here](https://arxiv.org/abs/2407.07890) `Training on the test task`, and what I would call `overfitting the prompt format`). It's also a method which can be limited for older models with smaller context sizes, as some few-shot examples can not fit into the context window.
70
- ### Structured text generation
 
 
 
 
 
 
 
71
  Structured text generation constrains the outputs to follow a given path, defined by a grammar or by regular expressions, for example. The `outlines` library implements this using finite state machines, which is very neat. (Other approaches exist, such as using interleaved generation for json generation, but the FSM one is my favorite).
72
 
73
- To understand more about what happens when using structured generation, you can check the [blog](https://huggingface.co/blog/evaluation-structured-outputs) we wrote together: structured generation reduce prompt variance in evaluation, and make results and rankings more stable. You can also check the overall `outlines` [blog](https://blog.dottxt.co/) for interesting implementations and observations linked to structured generation.
74
 
75
  However, some recent [research](https://arxiv.org/abs/2408.02442) seems to show that structured generation can lower model performance on some tasks (like reasoning), by moving the prior too far away from the expected probability distribution.
76
 
77
- ### Going further
78
  - ⭐ [Understanding how Finite State Machine when using structured generation](https://blog.dottxt.co/coalescence.html), by Outlines. Super clear guide on how their method works!
79
  - [The outlines method paper](https://arxiv.org/abs/2307.09702), a more academic explanation of the above
80
  - [Interleaved generation](https://github.com/guidance-ai/guidance?tab=readme-ov-file#guidance-acceleration), another method to constrain generations for some specific output formats
 
 
6
  import llmLogprob from '../../assets/image/llm_logprob.png';
7
  import llmGen from '../../assets/image/llm_gen.png';
8
  import Image from '../../../components/Image.astro';
9
+ import Note from "../../../components/Note.astro";
10
+ import Sidenote from "../../../components/Sidenote.astro";
11
+ import Accordion from "../../../components/Accordion.astro";
12
 
 
 
 
13
  Current large language model work in a simple way: given some text as input, they have learned to predict plausible follow up.
14
 
15
  This is done in two steps.
16
  ### Tokenization
17
+ The input text (called a *prompt* at inference) is first split into *tokens*, small units of texts (which can be one or several characters, up to the word level) each associated with a number. The whole range of tokens a model can parse is called its *vocabulary*. If any of these concept is unclear, please open the relevant accordion, else skip to the next section.
18
 
19
+ <Accordion title="Basics of tokenization: Why and how do we tokenize text?">
20
+ Since large language models are actually big mathematical functions, they eat numbers, not text.
21
 
22
+ Say you want to transform a sentence to numbers. You first need to decide how to cut your sentence into small pieces, then map every small piece to a number; this is *tokenization*.
23
+
24
+ In the past, people would try to map each character of a text with its index in a alphabet (`a` -> 1, `b` -> 2, etc) which is called *character based tokenization* (you split between characters). On the other end of the spectrum, people also tried to map each word with its index in a dictionary (`a` -> 1, `aardvark` -> 2, `ab` -> 3, etc) which is called *word based tokenization* (you split on spaces, if your language has spaces - if not, it's a bit harder).
25
+
26
+ Both these methods share a strong limitation: they remove information from the input text. They erase semantic connections that you can see from word shape (ex: `dis similar`, `similar`, `similar ity`, `similar ly`), information we would like our model to retain, so it connects related words together.
27
+ (Plus, what happens if you suddenly have a completely new word in input? It gets no number, and your model can't process it 😔 )
28
+
29
+ Some people therefore had the idea to cut words into sub-words, and assign index to these sub-words (`dis`, `similar`, `ity`, `ly`)!
30
+
31
+ This was initially done using morpho-syntactic rules (*morpho-syntax* is like the grammar of word creation). Now most people use byte pair encoding (BPE), a smart statistical method to create the sub-words automatically depending on their frequency in a reference text.
32
+
33
+ So as a summary: tokenization is a way to map small units of texts (which can be one or several characters, up to the word level) to numbers (similar to an index). When you want to process text, your input text (called a *prompt* at inference) is split into these *tokens* by a tokenizer. The whole range of tokens a model or tokenizer can parse is called its *vocabulary*.
34
+
35
+ <Note title="Going further: Understanding tokenization" emoji="📚" variant="warning">
36
+ - ⭐ [Explanation of different tokenization methods in the 🤗 NLP Course](https://huggingface.co/learn/nlp-course/en/chapter2/4)
37
+ - ⭐ [Conceptual guide about tokenization in the 🤗 doc](https://huggingface.co/docs/transformers/en/tokenizer_summary)
38
+ - [Course by Jurafsky on tokenization (and other things)](https://web.stanford.edu/~jurafsky/slp3/2.pdf) - academic approach, skip to 2.5 and 2.6 (the rest is interesting too but too broad)
39
+ </Note>
40
+
41
+ <Note title="Going further: Byte Pair Encoding" emoji="📚" variant="warning">
42
+ - ⭐ [Explanation of BPE in the 🤗 NLP Course](https://huggingface.co/learn/nlp-course/en/chapter6/5)
43
+ - [Paper introducing BPE to NLP](https://aclanthology.org/P16-1162/)
44
+ </Note>
45
+ </Accordion>
46
+
47
+ <Accordion title="Using your own tokenizer? Don't forget to consider the following">
48
+ I recommend making sure you understand BPE before this section, see above for some references!
49
+
50
+ **Choosing the correct vocabulary size**
51
+
52
+ The size of the vocabulary indicates how many individual tokens (for example, sub-words) the model will have to learn. A vocabulary which is **too big** might contain some very rare words as full tokens (for example: `aardvark`), which can lead to 2 problems. If such a rare word almost never appears in the training data, it can be hard to connect to other concepts, and the model might be unable to infer what it is about. On the other hand, if it appears rarely and only in specific contexts, it can be linked to some very specific other words: for example, if you train on forum data, and your tokenizer mapped a username as one single token in its vocabulary, your model might then associate this token to the specific user's content.
53
+
54
+ A vocabulary which is **too small** will present 2 other problems: worst representation capabilities, and increased cost at inference.
55
+
56
+ Let's go back to our above example, where we tokenized words derived from `similar`. Using a pseudo BPE approach (large vocabulary) to tokenize `similarly` has split the word into 2 tokens (`similar`, `ly`). If we had used instead character level tokenization (therefore with a very small vocabulary, the size of an alphabet), the same word would be cut into 9 tokens (`s`, `i`, `m`, `i`, `l`, `a`, `r`, `l`, `y`). Where the first method splits `similarly` into tokens which have an individual semantic meaning, it's not the case in the second method: with too small a vocabulary, we lost some semantic representation. The difference in representations length also means that it's many times as costly to generate our word with a smaller vocabulary (takes 9 tokens instead of 2, so 5 times more costly!).
57
+
58
+ At the moment, most people seem to use heuristics for vocabulary size, which seems correlated to number of languages covered and model size, so it's likely that using a number of tokens close to the reference models of a similar size could work for you.
59
+
60
+ <Note title="Going further: Rare tokens effect" emoji="📚">
61
+ - [SolidGoldMagikarp post on Less Wrong](https://www.lesswrong.com/posts/aPeJE8bSo6rAFoLqg/solidgoldmagikarp-plus-prompt-generation): Very interesting read on how some people identified very rare tokens in Open AI's vocabulary - this is quite cool because it's done without access to the model's internals (we don't know what the training data contains for example)
62
+ - [Fishing for Magikarp, paper by Cohere](https://arxiv.org/abs/2405.05417): Follow up work on to detect these tokens
63
+ </Note>
64
+
65
+ **Managing several languages**
66
+
67
+ When building or choosing your tokenizer, you construct your vocabulary from reference text. This means that your tokenizer will know vocabulary words and characters from this reference text. Usually, it means using data in English, with a Latin script.
68
+
69
+ If you want to add new language, and your new language uses the same script and share some roots, you could theoretically hope that some of your original language semantics transfer to the new language.
70
+
71
+ However, if you want to allow your tokenizer to correctly split text in other languages (especially languages written in other scripts) you'd better include data from these languages when building said tokenizer. Most of the time, though, this data will contain an unbalanced proportion of the initial language (ex: English) to the new language (ex: Thai, or Burmese), the initial language being much more present. Since most efficient tokenizer methods used nowadays (like BPE) create their complex vocabulary tokens based on the most frequent words seen, most of the long tokens will be English words - and most of the words from the less frequent languages will only be split at the character level.
72
+
73
+ This effect leads to an unfairness in multilingual tokenization: some (less frequent, or *lower-resourced*) languages require orders of magnitude more tokens to generate a sentence of equivalent length as English.
74
+
75
+ <Note title="Going further: Language and tokenization" emoji="📚" variant="warning">
76
+ - ⭐ [A beautiful breakdown and demo by Yennie Jun on tokenization issues across languages](https://www.artfish.ai/p/all-languages-are-not-created-tokenized): The breakdown in itself is very clear, and it's worth playing around with the [demo space](https://huggingface.co/spaces/yenniejun/tokenizers-languages)
77
+ - ⭐ [A demo by Aleksandar Petrov on unfairness of tokenization](https://aleksandarpetrov.github.io/tokenization-fairness/): I recommend looking at `Compare tokenization of sentences` to get a feel for the differences in cost of inference depending on languages
78
+ </Note>
79
+
80
+ **What about numbers?**
81
+
82
+ When building your tokenizer, you need to decide what to do about numbers. Do you only index 0 to 9, and assume all other numbers will be compositions of digits, or do you want to store numbers up to, say, one billion, individually? Current well known models display a range of approaches to this, but it's unclear what works better to allow mathematical reasoning. Maybe new approaches to tokenization, such as hierarchical tokenization, might be needed for this.
83
+ <Note title="Going further: Number tokenization" emoji="📚" variant="warning">
84
+ - ⭐ [A nice visual demo by Yennie Jun of how tokenizers of Anthropic, Meta, OpenAI, and Mistral models split numbers](https://www.artfish.ai/p/how-would-you-tokenize-or-break-down)
85
+ - [Small history by Beren Millidge of the evolution of number tokenization through the years](https://www.beren.io/2024-05-11-Integer-tokenization-is-now-much-less-insane/)
86
+ </Note>
87
+ </Accordion>
88
+
89
+ <Accordion title="How tokenization can mess up your evaluation">
90
+ **Managing fine-tuned models, system prompts and chat templates**
91
+
92
+ Pre-2022, models used to simply be pretrained: text in, text out, nothing else. Then, we got instruction tuning and chat models in 2023, and in 2025 reasoning models. This means that we went from using text "as is" to using chat templates (= providing models with json) to using reasoning tags (= mixing up the json chat template with xml tags for reasoning).
93
+
94
+ This means a number of models are going to perform terribly if you do not make sure to:
95
+ 1. add their system prompt at the very beginning of inference
96
+ 2. prompt them using a chat template if they require it (usually adding `Assistant` and `User` prefixes to the dialogue turns - learn more about this in [this cool guide](https://huggingface.co/docs/transformers/main/en/chat_templating))
97
+ 3. remove the thinking trace from the model answer before processing it (you can usually regex to remove what's between the `<think>` tags)
98
+
99
+
100
+ <Note title="Critical: Chat templates and tokenization" emoji="⚡" variant="danger">
101
+
102
+ ![Spacing, tokenization and template](https://pbs.twimg.com/media/GPANfpiasAA9b6F?format=png&name=medium)
103
+
104
+ Different tokenizers behave differently with spacing and special tokens. See this [visualization](https://x.com/danielhanchen/status/1796952220619157694) showing how spacing, tokenization, and templates interact. Never assume tokenizers behave identically!
105
+ </Note>
106
+
107
+ **Tokenizing the context and choices together or separately**
108
+
109
+ When looking at an MCQA evaluation, in general, you want to tokenize the context together with the choices, as it creates a succession of tokens which is likely/natural for the model.
110
+
111
+ However, some tokenizers (like the [Llama one](https://github.com/EleutherAI/lm-evaluation-harness/pull/531#issuecomment-1595586257)) do not satisfy `enc(context + choice) = enc(context) + enc(choice)` (and add or remove spacing). This means that comparing the logprobabilities of the choices is not easy, as the context tokens can "bleed out" into them, messing up the comparison.
112
+
113
+ <Sidenote>
114
+
115
+ The [Llama tokenizer](https://github.com/EleutherAI/lm-evaluation-harness/pull/531#issuecomment-1595586257) doesn't satisfy `enc(context + choice) = enc(context) + enc(choice)`, making log probability comparisons tricky. Tokenize separately and concatenate, removing special tokens.
116
+ </Sidenote>
117
+
118
+ So if this is the case for your model, you might want to compute the tokens of context and choice separately and then concatenate them after removing the special start/end of sentence tokens which might have been added.
119
+
120
+ **Paying attention to start and end of sentence tokens**
121
+
122
+ Some models, like the `Gemma` ones, are extremely sensitive to the [inclusion of start of sentence tokens](https://github.com/EleutherAI/lm-evaluation-harness/pull/1465) at inference. You might need to do a couple of experiments to see if that happens for you, and add these tokens manually when evaluating.
123
+
124
+ You can also encounter some issues where your model won't stop on an end of sentence token like you would expect (for example, on `\n`), because your model will not predict this token alone but included in an higher level token (for example, `\n\n`, which can be a single token, especially for code models). In this case, you might need to add a specific check to "backtrack" on generated text to make sure you're cutting your generated sentence at the proper spot before computing metrics.
125
+
126
+ **Multilinguality and tokenization**
127
+
128
+ When looking at multilingual evaluations, you'll also need to see how to tokenize your text, depending on your evaluation task and metrics. As some languages do not always use spacing as a word separator (Korean, Thai, Japanese, Chinese, to cite a few), they will require language specific tokenizers to be split properly, else it will affect their scores on metrics such as [BLEU](https://github.com/EleutherAI/lm-evaluation-harness/issues/212), F1 scores, etc.
129
+
130
+ **Code evaluations and end of sentence tokens**
131
+
132
+ Code models usually have been trained with `\n\t` as a single token. This means that when generating text, they will often generate `\n\t` in one step. A task which defines `\n` as an end of sentence token (= to stop the generation) will let the model continue generating after a `\n\t`, if predicted as one token, since it's not the same as `\n`. But you would actually still want the model to stop. In these cases, you either need to update your end of sentence tokens, or define a mechanism to backtrack on the character representation of the latest tokens to stop (and cut) the generation a posteriori.
133
+ </Accordion>
134
+
135
+ ### Inference
136
 
137
  From this input text, the LLM generates a probability distribution of the most likely next tokens over all the vocabulary. To get a continued generation, we can take the most probable token (give or take some added randomness to get more interesting outputs) as the next one, then repeat the operation, using the new token as the end of the prompt, etc.
138
 
139
+ <Image src={llmTk1} alt="LLM tokenization and prediction process" />
140
+
141
+
142
+ <Note title="Two main evaluation approaches" emoji="🎯" variant="info">
143
+
144
+ **Log-likelihood evaluations**: Given a prompt and one (or several) answers, what is probability of said answer(s) for my model?
145
+
146
+ **Generative evaluations**: Given a prompt, what text does my model generate?
147
+
148
+ Choice depends on your task: multiple-choice questions use log-likelihood, while open-ended tasks require generative evaluation.
149
+
150
+ </Note>
151
+
152
+ #### Log-likelihood evaluations
153
  For log-likelihood evaluations, we want the conditional probability of one or several choices given a prompt - in other terms, what is the likelihood to get a specific continuation given an input?
154
  So:
155
  - we concatenate each choice with the prompt, and pass them to our LLM, which outputs the logits of each token depending on the previous ones
 
163
  - get the preferred answer of a model among several choice, like in the above picture. (*However, this can advantage scores of models which would have, freely, generated something else, like `Zygote` in the picture.*)
164
  - test if a single choice has a probability above 0.5
165
  - study model calibration. A well calibrated model is a model for which the correct answers have the highest probabilities.
166
+ <Sidenote>
167
+ To learn more about calibration, you can check [this paper](https://arxiv.org/abs/2207.05221) from Anthropic, on what it is, how to detect it, and how to train models to be well calibrated, and [this paper](https://arxiv.org/abs/2311.14648) on some possible limits of calibration).
168
+ </Sidenote>
169
+
170
+ <Note>
171
+ A multiple choice question answer can be expressed as a free form generative evaluation too! For this reason, you'll sometimes see a mention of the task **formulation**.
172
+
173
+ There are three common task formulations:
174
+ - **Multiple choice format (MCF)**: we compare the likelihood of choices indices, where choices are explicitly presented in the prompt and prefixed with A/B/C/D (as in MMLU)
175
+ - **Cloze formulation (CF)**: we compare the likelihood of different choices without providing them in the prompt
176
+ - **Freeform generation (FG)**: we evaluate the accuracy of greedy generation for a given prompt
177
 
178
+ FG requires substantial latent knowledge and is usually too difficult for models during short pre-training ablations. For this reason, we typically focus on multiple choice formulations (MCF or CF) when running small-scale ablations. However, for post-trained models, FG becomes the primary formulation since we're evaluating whether the model can actually generate useful responses.
179
+ However, research has also shown that models struggle with MCF early in training, only learning this skill after extensive training, making CF better for early signal. We thus recommend using CF for small ablations, and integrate MCF in the main run as it gives better mid-training signal once a model has passed a threshold to get sufficiently high signal-over-noise ratio for MCF.
180
+ A quick note also that, to score a model's answer in sequence likelihood evaluations like CF, we compute accuracy as the percentage of questions where the the correct answer has the highest log probability normalised by character/token count. This normalisation prevents a bias toward shorter answers.
181
+
182
+ <Sidenote>
183
+ The point at which MMLU MCF becomes non-random depends on the model size and training data. For a 7B transformer, the OLMES paper found the model starts showing non-random performance after 500B tokens. For 1.7B model, we found this happens after 6T tokens in SmolLM2.
184
+ </Sidenote>
185
+
186
+ </Note>
187
+
188
+ #### Generative evaluations
189
  For a generative evaluation, we want the text generated by the model given an input prompt.
190
 
191
  It is obtained in an auto-regressive way: we pass the prompt to the model, look at the most likely next token, select it as being the model's "choice first token", then repeat until we reach an end of generation condition (maximum length, special token to stop the generation, etc). All the tokens generated by the model are consider its answer to the prompt.
192
 
193
  <Image src={llmGen} alt="LLM generative evaluation process" />
194
 
 
 
195
  We can then compare this generation with references and score the distance between both (using either simple metrics like exact match, more complex metrics like BLEU, or models as judges).
196
 
197
+ <Note title="Going further" emoji="📚" variant="warning">
198
+ - ⭐ [Blog on several ways to evaluate MMLU](https://huggingface.co/blog/open-llm-leaderboard-mmlu) , by my team at Hugging Face. I recommend reading it if you want to delve deeper into the differences between multi choice log-likelihood evaluations and generative ones, including what it can mean with respect to score changes (The above illustrations come from the blog and have been made by Thom Wolf)
 
199
  - ⭐ [A beautiful mathematical formalization of the above inference methods](https://arxiv.org/abs/2405.14782v2), from EleutherAI. Go to the Appendix directly.
200
+ </Note>
201
+
202
+
203
  ### Constraining model outputs
204
  In a number of cases, we want the model output to follow a specific format, for example to compare them to a reference.
205
+
206
+ #### Using a prompt
207
  The easiest way to do this is to add a task prompt which contains very specific instructions as to how the model should answer (`Provide numerical answers in digits.`,`Use no abbreviation.`, etc).
208
 
209
+ It won't necessarily work all the time but should be good enough for high capability models. That's the approach we followed in the [GAIA](https://huggingface.co/papers/2311.12983) paper for example.
210
+
211
+ #### Few shots and in context learning
212
  The next way to do so is to constrain the model through what is called "in context learning". By providing examples in the prompt (what is called `few-shot prompting`), the model is implicitly biased towards following the repeated prompt shape for the actual sample.
213
 
214
+ <Note>
215
+ It's a method which was overall working quite well until end of 2023!
216
+
217
+ However, the widespread adoption of instruction-tuning methods and the addition of instruction data in later stages of model pre-training (continuous pre-training) has biased more recent models towards specific output formats (what is being called [here](https://arxiv.org/abs/2407.07890) *Training on the test task*, and what I would call *overfitting the prompt format*). Reasoning models are also not playing that well with few shot examples because of the reasoning trace.
218
+
219
+ It's also a method which can be limited for older models with smaller context sizes, as some few-shot examples can not fit into the context window.
220
+ </Note>
221
+
222
+ #### Structured text generation
223
  Structured text generation constrains the outputs to follow a given path, defined by a grammar or by regular expressions, for example. The `outlines` library implements this using finite state machines, which is very neat. (Other approaches exist, such as using interleaved generation for json generation, but the FSM one is my favorite).
224
 
225
+ To understand more about what happens when using structured generation, you can check the [blog](https://huggingface.co/blog/evaluation-structured-outputs) we wrote together: structured generation reduce prompt variance in evaluation, and make results and rankings more stable. You can also check the overall `outlines` [blog](https://blog.dottxt.co/) for interesting implementations and observations linked to structured generation.
226
 
227
  However, some recent [research](https://arxiv.org/abs/2408.02442) seems to show that structured generation can lower model performance on some tasks (like reasoning), by moving the prior too far away from the expected probability distribution.
228
 
229
+ <Note title="Going further" emoji="📚" variant="warning">
230
  - ⭐ [Understanding how Finite State Machine when using structured generation](https://blog.dottxt.co/coalescence.html), by Outlines. Super clear guide on how their method works!
231
  - [The outlines method paper](https://arxiv.org/abs/2307.09702), a more academic explanation of the above
232
  - [Interleaved generation](https://github.com/guidance-ai/guidance?tab=readme-ov-file#guidance-acceleration), another method to constrain generations for some specific output formats
233
+ </Note>
app/src/content/chapters/general-knowledge/tokenization.mdx DELETED
@@ -1,76 +0,0 @@
1
- ---
2
- title: "Tokenization"
3
- ---
4
-
5
- ### Tokenization
6
-
7
- ### Why and how do we tokenize text?
8
- Since large language models are actually big mathematical functions, they eat numbers, not text.
9
-
10
- Say you want to transform a sentence to numbers. You first need to decide how to cut your sentence into small pieces, then map every small piece to a number; this is *tokenization*.
11
-
12
- In the past, people would try to map each character of a text with its index in a alphabet (`a` -> 1, `b` -> 2, etc) which is called *character based tokenization* (you split between characters). On the other end of the spectrum, people also tried to map each word with its index in a dictionary (`a` -> 1, `aardvark` -> 2, `ab` -> 3, etc) which is called *word based tokenization* (you split on spaces, if your language has spaces - if not, it's a bit harder).
13
-
14
- Both these methods share a strong limitation: they remove information from the input text. They erase semantic connections that you can see from word shape (ex: `dis similar`, `similar`, `similar ity`, `similar ly`), information we would like our model to retain, so it connects related words together.
15
- (Plus, what happens if you suddenly have a completely new word in input? It gets no number, and your model can't process it 😔 )
16
-
17
- Some people therefore had the idea to cut words into sub-words, and assign index to these sub-words (`dis`, `similar`, `ity`, `ly`)!
18
-
19
- This was initially done using morpho-syntactic rules ("morpho-syntax" is like the grammar of word creation). Now most people use byte pair encoding (BPE), a smart statistical method to create the sub-words automatically depending on their frequency in a reference text.
20
-
21
- So as a summary: tokenization is a way to map small units of texts (which can be one or several characters, up to the word level) to numbers (similar to an index). When you want to process text, your input text (called a *prompt* at inference) is split into these *tokens* by a tokenizer. The whole range of tokens a model or tokenizer can parse is called its *vocabulary*.
22
- ### Going further: Understanding tokenization
23
- I advise reading one of the first 2 links in depth.
24
- - ⭐ [Explanation of different tokenization methods in the 🤗 NLP Course](https://huggingface.co/learn/nlp-course/en/chapter2/4)
25
- - ⭐ [Conceptual guide about tokenization in the 🤗 doc](https://huggingface.co/docs/transformers/en/tokenizer_summary)
26
- - [Course by Jurafsky on tokenization (and other things)](https://web.stanford.edu/~jurafsky/slp3/2.pdf) - more academical in its approach, skip to 2.5 and 2.6 (the rest is interesting too but too broad)
27
-
28
- ### Going further: Byte Pair Encoding
29
- - ⭐ [Explanation of BPE in the 🤗 NLP Course](https://huggingface.co/learn/nlp-course/en/chapter6/5)
30
- - [Paper introducing BPE to NLP](https://aclanthology.org/P16-1162/)
31
-
32
-
33
- ### Some of the many problems of tokenizations
34
- ### Choosing the correct vocabulary size
35
- The size of the vocabulary indicates how many individual tokens (for example, sub-words) the model will have to learn.
36
-
37
- A vocabulary which is **too big** might contain some very rare words as full tokens (for example: `aardvark`), which can lead to 2 problems.
38
-
39
- If such a rare word almost never appears in the training data, it can be hard to connect to other concepts, and the model might be unable to infer what it is about.
40
-
41
- On the other hand, if it appears rarely and only in specific contexts, it can be linked to some very specific other words: for example, if you train on forum data, and your tokenizer mapped a username as one single token in its vocabulary, your model might then associate this token to the specific user's content.
42
-
43
- A vocabulary which is **too small** will present 2 other problems: worst representation capabilities, and increased cost at inference.
44
-
45
- Let's go back to our above example, where we tokenized words derived from `similar`. Using a pseudo BPE approach (large vocabulary) to tokenize `similarly` has split the word into 2 tokens (`similar`, `ly`). If we had used instead character level tokenization (therefore with a very small vocabulary, the size of an alphabet), the same word would be cut into 9 tokens (`s`, `i`, `m`, `i`, `l`, `a`, `r`, `l`, `y`).
46
-
47
- Where the first method splits `similarly` into tokens which have an individual semantic meaning, it's not the case in the second method: with too small a vocabulary, we lost some semantic representation. The difference in representations length also means that it's many times as costly to generate our word with a smaller vocabulary (takes 9 tokens instead of 2, so 5 times more costly!).
48
-
49
- At the moment, most people seem to use heuristics for vocabulary size, which seems correlated to number of languages covered and model size, so it's likely that using a number of tokens close to the reference models of a similar size could work for you.
50
- ### Going further: Rare tokens effect
51
- - [SolidGoldMagikarp post on Less Wrong](https://www.lesswrong.com/posts/aPeJE8bSo6rAFoLqg/solidgoldmagikarp-plus-prompt-generation)
52
- - Very interesting read on how some people identified very rare tokens in Open AI's vocabulary - this is quite cool because it's done without access to the model's internals (we don't know what the training data contains for example)
53
- - [Fishing for Magikarp, paper by Cohere](https://arxiv.org/abs/2405.05417)
54
- - Follow up work on to detect these tokens
55
-
56
- ### Managing several languages
57
- (Recommended: read an explanation of BPE before this section)
58
- When building or choosing your tokenizer, you construct your vocabulary from reference text. This means that your tokenizer will know vocabulary words and characters from this reference text. Usually, it means using data in English, with a Latin script.
59
-
60
- If you want to add new language, and your new language uses the same script and share some roots, you could theoretically hope that some of your original language semantics transfer to the new language.
61
-
62
- However, if you want to allow your tokenizer to correctly split text in other languages (especially languages written in other scripts) you'd better include data from these languages when building said tokenizer. Most of the time, though, this data will contain an unbalanced proportion of the initial language (ex: English) to the new language (ex: Thai, or Burmese), the initial language being much more present. Since most efficient tokenizer methods used nowadays (like BPE) create their complex vocabulary tokens based on the most frequent words seen, most of the long tokens will be English words - and most of the words from the less frequent languages will only be split at the character level.
63
-
64
- This effect leads to an unfairness in multilingual tokenization: some (less frequent, or *lower-resourced*) languages require orders of magnitude more tokens to generate a sentence of equivalent length as English.
65
-
66
- ### Going further: Language and tokenization
67
- - ⭐ [A beautiful breakdown and demo by Yennie Jun on tokenization issues across languages](https://www.artfish.ai/p/all-languages-are-not-created-tokenized)
68
- - The breakdown in itself is very clear, and it's worth playing around with the [demo space](https://huggingface.co/spaces/yenniejun/tokenizers-languages)
69
- - ⭐ [A demo by Aleksandar Petrov on unfairness of tokenization](https://aleksandarpetrov.github.io/tokenization-fairness/)
70
- - I recommend looking at `Compare tokenization of sentences` to get a feel for the differences in cost of inference depending on languages
71
-
72
- ### What about numbers?
73
- When building your tokenizer, you need to decide what to do about numbers. Do you only index 0 to 9, and assume all other numbers will be compositions of digits, or do you want to store numbers up to, say, one billion, individually? Current well known models display a range of approaches to this, but it's unclear what works better to allow mathematical reasoning. Maybe new approaches to tokenization, such as hierarchical tokenization, might be needed for this.
74
- ### Going further: Number tokenization
75
- - ⭐ [A nice visual demo by Yennie Jun of how tokenizers of Anthropic, Meta, OpenAI, and Mistral models split numbers](https://www.artfish.ai/p/how-would-you-tokenize-or-break-down)
76
- - [Small history by Beren Millidge of the evolution of number tokenization through the years](https://www.beren.io/2024-05-11-Integer-tokenization-is-now-much-less-insane/)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/src/content/chapters/human-evaluation/basics.mdx CHANGED
@@ -2,6 +2,9 @@
2
  title: "Human Evaluation: Basics"
3
  ---
4
 
 
 
 
5
  Human evaluation is simply asking humans to evaluate models. In this document, we'll look at post-hoc evaluation: your model has been trained, you have a given task in mind, and humans are providing scores.
6
 
7
  ### Systematic evaluation
@@ -26,6 +29,11 @@ Two other approaches exist to do human-based evaluation, in a more casual way.
26
 
27
  **Vibes-checks** are manual evaluations done by individuals, usually on undisclosed prompts, to get an overall feeling of how well models perform on many use cases (from coding to quality of smut written). Often shared on Twitter and Reddit, results mostly constitute anecdotal evidence, and tend to be highly sensitive to confirmation bias (in other words, people tend to find what they look for). However, they can be [good starting point for your own use cases](https://olshansky.substack.com/p/vibe-checks-are-all-you-need).
28
 
 
 
 
 
 
29
  **Arenas** are crowdsourced human evaluation to rank models.
30
  A well known example of this is the [LMSYS chatbot arena](https://huggingface.co/spaces/lmsys/chatbot-arena-leaderboard), where community users are asked to chat with models until they find one is better than the other. Votes are then aggregated in an Elo ranking (a ranking of matches) to select which model is "the best".
31
  ### Pros and cons of human evaluation
@@ -37,10 +45,21 @@ Human evaluation is very interesting for the following reasons:
37
  *Note: However, when doing evaluation with humans, you need to make sure your annotators are diverse enough that your results generalizes.*
38
 
39
  However, it also present a number of limitations:
40
- - **First impressions bias**: Human evaluators tend to estimate the quality of answers [based on first impressions](https://arxiv.org/abs/2309.16349), instead of actual factuality or faithfulness.
41
- - **Tone bias**: Crowdsourced annotators are notably very sensitive to tone, and underestimate the number of factual or logical errors in an assertive answer. In other terms, if a model says wrong things in a confident tone, human evaluators are much less likely to notice it, which could skew ratings towards the more assertive models. (Expert annotators are less likely to fall prey to these biases.)
42
  - **Self-preference bias**: Humans are [most likely to prefer answers which appeal to their views or align with their opinions or errors](https://arxiv.org/abs/2310.13548), rather than answers which are factually correct.
43
  - **Identity bias**: People with different identities tend to have different values, and rate model answers very differently (for example on [toxicity](https://arxiv.org/abs/2205.00501))
 
 
 
 
 
 
 
 
 
 
 
44
  ### Systematic human evaluation
45
  Pros of systematic human evaluations, especially with paid annotators, are
46
  - **Getting high quality data** adapted to your use case, that you will be able to build on later (if you need to develop preference models for example)
@@ -60,5 +79,10 @@ Pros of casual human evaluations are:
60
 
61
  The obvious problems of casual approaches (without annotator selection) are:
62
  - **High subjectivity**: it's hard to enforce a consistent grading from many community members using broad guidelines, especially since annotators preferences tend to be [culturally bound](https://arxiv.org/abs/2404.16019v1). One can hope that these effect is smoothed over by the sheer scale of the votes, through a "wisdom of the crowd" effect (see Galton's wikipedia page).
 
 
 
 
 
63
  - **Unrepresentative preference ranking**: since young western men are over re-represented on tech-sides of the internet, it can lead to very skewed preferences, mismatched to those of the general population, both in terms of topics explored and overall rankings.
64
  - **Easy to game**: if you're using unfiltered crowdsourced annotators, it's quite easy for a 3rd party to game your evaluation, for example to raise the score of a given model (since a number of models have a distinctive writing style)
 
2
  title: "Human Evaluation: Basics"
3
  ---
4
 
5
+ import Note from "../../../components/Note.astro";
6
+ import Sidenote from "../../../components/Sidenote.astro";
7
+
8
  Human evaluation is simply asking humans to evaluate models. In this document, we'll look at post-hoc evaluation: your model has been trained, you have a given task in mind, and humans are providing scores.
9
 
10
  ### Systematic evaluation
 
29
 
30
  **Vibes-checks** are manual evaluations done by individuals, usually on undisclosed prompts, to get an overall feeling of how well models perform on many use cases (from coding to quality of smut written). Often shared on Twitter and Reddit, results mostly constitute anecdotal evidence, and tend to be highly sensitive to confirmation bias (in other words, people tend to find what they look for). However, they can be [good starting point for your own use cases](https://olshansky.substack.com/p/vibe-checks-are-all-you-need).
31
 
32
+ <Sidenote>
33
+
34
+ While vibe-checks are anecdotal and subject to confirmation bias, systematic approaches like [Wolfram Ravenwolf's comparisons](https://olshansky.substack.com/p/vibe-checks-are-all-you-need) can provide useful starting points for identifying use cases to evaluate formally.
35
+ </Sidenote>
36
+
37
  **Arenas** are crowdsourced human evaluation to rank models.
38
  A well known example of this is the [LMSYS chatbot arena](https://huggingface.co/spaces/lmsys/chatbot-arena-leaderboard), where community users are asked to chat with models until they find one is better than the other. Votes are then aggregated in an Elo ranking (a ranking of matches) to select which model is "the best".
39
  ### Pros and cons of human evaluation
 
45
  *Note: However, when doing evaluation with humans, you need to make sure your annotators are diverse enough that your results generalizes.*
46
 
47
  However, it also present a number of limitations:
48
+ - **First impressions bias**: Human evaluators tend to estimate the quality of answers [based on first impressions](https://arxiv.org/abs/2309.16349), instead of actual factuality or faithfulness.
49
+ - **Tone bias**: Crowdsourced annotators are notably very sensitive to tone, and underestimate the number of factual or logical errors in an assertive answer. In other terms, if a model says wrong things in a confident tone, human evaluators are much less likely to notice it, which could skew ratings towards the more assertive models. (Expert annotators are less likely to fall prey to these biases.)
50
  - **Self-preference bias**: Humans are [most likely to prefer answers which appeal to their views or align with their opinions or errors](https://arxiv.org/abs/2310.13548), rather than answers which are factually correct.
51
  - **Identity bias**: People with different identities tend to have different values, and rate model answers very differently (for example on [toxicity](https://arxiv.org/abs/2205.00501))
52
+
53
+ <Note title="Critical human evaluation biases" emoji="⚠️" variant="warning">
54
+
55
+ Human evaluators have significant biases:
56
+ - **First impressions**: Judge on presentation over factuality
57
+ - **Tone**: Confident incorrect answers score higher than hesitant correct ones
58
+ - **Self-preference**: Prefer answers aligning with their views over factually correct ones
59
+ - **Identity**: Different demographics rate identical content very differently
60
+
61
+ Expert annotators are less susceptible, but these biases affect crowdsourced evaluation significantly.
62
+ </Note>
63
  ### Systematic human evaluation
64
  Pros of systematic human evaluations, especially with paid annotators, are
65
  - **Getting high quality data** adapted to your use case, that you will be able to build on later (if you need to develop preference models for example)
 
79
 
80
  The obvious problems of casual approaches (without annotator selection) are:
81
  - **High subjectivity**: it's hard to enforce a consistent grading from many community members using broad guidelines, especially since annotators preferences tend to be [culturally bound](https://arxiv.org/abs/2404.16019v1). One can hope that these effect is smoothed over by the sheer scale of the votes, through a "wisdom of the crowd" effect (see Galton's wikipedia page).
82
+
83
+ <Sidenote>
84
+
85
+ The "wisdom of the crowd" effect (discovered by statistician Galton) suggests individual biases cancel out at scale. However, this requires truly diverse crowds—tech forums skew heavily toward young western men, potentially undermining this effect.
86
+ </Sidenote>
87
  - **Unrepresentative preference ranking**: since young western men are over re-represented on tech-sides of the internet, it can lead to very skewed preferences, mismatched to those of the general population, both in terms of topics explored and overall rankings.
88
  - **Easy to game**: if you're using unfiltered crowdsourced annotators, it's quite easy for a 3rd party to game your evaluation, for example to raise the score of a given model (since a number of models have a distinctive writing style)
app/src/content/chapters/human-evaluation/tips-and-tricks.mdx CHANGED
@@ -2,6 +2,9 @@
2
  title: "Human Evaluation: Tips and tricks"
3
  ---
4
 
 
 
 
5
  ### Tips and tricks
6
  Here are a few practical tips you might want consider when using human annotators to build an evaluation dataset. If you haven't done so yet, we recommend reading first the page on "Using human annotators" and then come back to this page.
7
 
@@ -19,6 +22,11 @@ Here are a few practical tips you might want consider when using human annotator
19
 
20
  - **Annotators should work independently**: It's better if annotators don't help each other or see each other's work during the task, as they can propagate their own biases and cause annotation drift. Alignment should always happen through comprehensive guidelines. You may want to train any new team members first on a separate dataset and/or use inter-annotator agreement metrics to make sure the team is aligned.
21
 
 
 
 
 
 
22
  - **Consistency is key**: If you make important changes to your guidelines (e.g., changed a definition or instruction, or have added/removed labels), consider if you need to iterate over the annotated data. At least, you should track the changes in your dataset through a metadata value like `guidelines-v1`.
23
 
24
  ### Hybrid human-machine annotation
@@ -27,6 +35,11 @@ Sometimes teams face contraints on time and resources but don't want to sacrific
27
 
28
  - **Model-aided annotation**: You may use the predictions or generations of a model as pre-annotations, so that the annotation team doesn't need to start from scratch. Just note that this could introduce the model's biases into human annotations, and that if the model's accuracy is poor it may increase work for annotators.
29
 
 
 
 
 
 
30
  - **Supervise model as a judge**: You can combine the power of the model as a judge methodology (see the section on "Model as a judge") and human supervisors who validate or discard the results. Note that the biases discussed in the "Pros and cons of human evaluation" will apply here.
31
 
32
  - **Idenfity edge cases**: For an even faster task, use a jury of models and then have your human supervisor(s) step in where models disagree or there's a tie to break. Again, be aware of the biases discussed in the "Pros and cons of human evaluation".
 
2
  title: "Human Evaluation: Tips and tricks"
3
  ---
4
 
5
+ import Note from "../../../components/Note.astro";
6
+ import Sidenote from "../../../components/Sidenote.astro";
7
+
8
  ### Tips and tricks
9
  Here are a few practical tips you might want consider when using human annotators to build an evaluation dataset. If you haven't done so yet, we recommend reading first the page on "Using human annotators" and then come back to this page.
10
 
 
22
 
23
  - **Annotators should work independently**: It's better if annotators don't help each other or see each other's work during the task, as they can propagate their own biases and cause annotation drift. Alignment should always happen through comprehensive guidelines. You may want to train any new team members first on a separate dataset and/or use inter-annotator agreement metrics to make sure the team is aligned.
24
 
25
+ <Note title="Prevent annotation drift" emoji="🎯" variant="info">
26
+
27
+ Annotators must work independently. Collaboration can propagate individual biases and cause "annotation drift" where the team gradually diverges from guidelines. Alignment should happen only through comprehensive written guidelines.
28
+ </Note>
29
+
30
  - **Consistency is key**: If you make important changes to your guidelines (e.g., changed a definition or instruction, or have added/removed labels), consider if you need to iterate over the annotated data. At least, you should track the changes in your dataset through a metadata value like `guidelines-v1`.
31
 
32
  ### Hybrid human-machine annotation
 
35
 
36
  - **Model-aided annotation**: You may use the predictions or generations of a model as pre-annotations, so that the annotation team doesn't need to start from scratch. Just note that this could introduce the model's biases into human annotations, and that if the model's accuracy is poor it may increase work for annotators.
37
 
38
+ <Sidenote>
39
+
40
+ Model-aided annotation (using predictions as pre-annotations) can speed up work but introduces model biases into human annotations. If model accuracy is poor, fixing errors may take longer than annotating from scratch.
41
+ </Sidenote>
42
+
43
  - **Supervise model as a judge**: You can combine the power of the model as a judge methodology (see the section on "Model as a judge") and human supervisors who validate or discard the results. Note that the biases discussed in the "Pros and cons of human evaluation" will apply here.
44
 
45
  - **Idenfity edge cases**: For an even faster task, use a jury of models and then have your human supervisor(s) step in where models disagree or there's a tie to break. Again, be aware of the biases discussed in the "Pros and cons of human evaluation".
app/src/content/chapters/human-evaluation/using-human-annotators.mdx CHANGED
@@ -4,11 +4,18 @@ title: "Using human annotators"
4
 
5
  import bestAnnotationPractices from '../../assets/image/best_annotation_practices.png';
6
  import Image from '../../../components/Image.astro';
 
 
7
 
8
  ### Using human annotators
9
 
10
  I suggest reading Section 3 of this [review](https://aclanthology.org/2024.cl-3.1/) of good practices in data annotation quality. If you want production level quality and have the means to implement all of these methods, go ahead!
11
 
 
 
 
 
 
12
  <Image src={bestAnnotationPractices} alt="Best annotation practices diagram" />
13
 
14
  However, important guidelines (no matter your project size) are the following, once you defined your task and scoring guidelines.
@@ -18,13 +25,23 @@ You likely want the people working on your task to:
18
  1) obey some demographics.
19
  Some examples: be native speakers of the target language, have a higher education level, be experts in a specific domain, be diverse in their geographical origins, etc.
20
  Your needs will vary depending on your task.
21
- 1) produce high quality work.
22
  It's notably important now to add a way to check if answers are LLM-generated, and you'll need to filter some annotators out of your pool.
23
  *Imo, unless you're counting on highly motivated crowdsourced annotators, it's always better to pay your annotators correctly.*
24
 
25
- - **Guideline design**
 
 
 
 
 
26
  Make sure to spend a lot of time really brainstorming your guidelines! That's one of the points on which we spent the most time for the [GAIA](https://huggingface.co/gaia-benchmark) dataset.
27
 
 
 
 
 
 
28
  - **Iterative annotation**
29
  Be ready to try several rounds of annotations, as your annotators will misunderstand your guidelines (they are more ambiguous than you think)! Generating samples several times will allow your annotators to really converge on what you need.
30
 
 
4
 
5
  import bestAnnotationPractices from '../../assets/image/best_annotation_practices.png';
6
  import Image from '../../../components/Image.astro';
7
+ import Note from "../../../components/Note.astro";
8
+ import Sidenote from "../../../components/Sidenote.astro";
9
 
10
  ### Using human annotators
11
 
12
  I suggest reading Section 3 of this [review](https://aclanthology.org/2024.cl-3.1/) of good practices in data annotation quality. If you want production level quality and have the means to implement all of these methods, go ahead!
13
 
14
+ <Note title="Comprehensive annotation guide" emoji="📚" variant="info">
15
+
16
+ For production-level quality, read Section 3 of this [comprehensive review](https://aclanthology.org/2024.cl-3.1/) of data annotation best practices. The diagram below summarizes key principles.
17
+ </Note>
18
+
19
  <Image src={bestAnnotationPractices} alt="Best annotation practices diagram" />
20
 
21
  However, important guidelines (no matter your project size) are the following, once you defined your task and scoring guidelines.
 
25
  1) obey some demographics.
26
  Some examples: be native speakers of the target language, have a higher education level, be experts in a specific domain, be diverse in their geographical origins, etc.
27
  Your needs will vary depending on your task.
28
+ 1) produce high quality work.
29
  It's notably important now to add a way to check if answers are LLM-generated, and you'll need to filter some annotators out of your pool.
30
  *Imo, unless you're counting on highly motivated crowdsourced annotators, it's always better to pay your annotators correctly.*
31
 
32
+ <Sidenote>
33
+
34
+ Unless you have highly motivated crowdsourced annotators, always pay fairly. Underpaid annotators produce lower quality work, introduce more errors, and may use LLMs to complete tasks quickly.
35
+ </Sidenote>
36
+
37
+ - **Guideline design**
38
  Make sure to spend a lot of time really brainstorming your guidelines! That's one of the points on which we spent the most time for the [GAIA](https://huggingface.co/gaia-benchmark) dataset.
39
 
40
+ <Sidenote>
41
+
42
+ When creating the [GAIA benchmark](https://huggingface.co/gaia-benchmark), guideline design consumed more time than any other phase. Clear, unambiguous guidelines are worth the investment—they prevent costly re-annotation rounds.
43
+ </Sidenote>
44
+
45
  - **Iterative annotation**
46
  Be ready to try several rounds of annotations, as your annotators will misunderstand your guidelines (they are more ambiguous than you think)! Generating samples several times will allow your annotators to really converge on what you need.
47
 
app/src/content/chapters/intro.mdx CHANGED
@@ -3,112 +3,126 @@ title: "Intro"
3
  ---
4
 
5
  import HtmlEmbed from "../../components/HtmlEmbed.astro";
 
 
6
 
 
7
 
8
- ### How do we do LLM evaluation?
9
 
10
- First, let's align on a couple definitions. There are, to my knowledge, at the moment, 3 main ways to do evaluation: automated benchmarking, using humans as judges, and using models as judges. Each approach has its own reason for existing, uses, and limitations.
11
 
12
- #### Benchmarks
13
 
14
- Automated benchmarking usually works the following way: you'd like to know how well your model performs on something. This something can be a well-defined concrete **task**, such as *How well can my model classify spam from non spam emails?*, or a more abstract and general **capability**, such as *How good is my model at math?*.
15
 
16
- From this, you construct an evaluation, usually made of two things:
17
- - a collection of *samples*, given as input to the model to see what comes out as output, sometimes coupled with a reference (called gold) to compare with. Samples are usually designed to try to emulate what you want to test the model on: for example, if you are looking at email classification, you create a dataset of spam and non spam emails, try to include some hard edge cases, etc. For LLMs, the two main tasks are generation evaluation (comparing generated text with a reference after normalization), or multi-choice (compare the relative log-probabilities of possible continuations after a prompt).
18
- - a *metric*, which is a way to compute a score for the model. For example, how accurately can your model classify spam (score of well classified sample = 1, badly classified = 0).
19
 
20
- This is more interesting to do on data that was not included in the model training set, because you want to test if it **generalizes** well. You don't want a model which can only classify emails it has already "seen", that would not be very useful!
21
 
22
- Note: A model which can only predict well on its training data (and has not latently learnt more high-level general patterns) is said to be **overfitting**. In less extreme cases, you still want to test if your model is able to generalize to data patterns which were not in the training set's distribution (for example, classify spam emails about 'health' products after having seen only spam emails about fake banks).
23
 
24
- This works quite well for very well-defined tasks, where performance is "easy" to assess and measure: when you are literally testing your model on spam classification, you can say "the model classified correctly n% of these samples". For LLMs benchmarks, some issues can arise, such as models [favoring specific choices based on the order in which they have been presented for multi-choice evaluations](https://arxiv.org/abs/2309.03882), and generative evaluations relying on normalisations which can easily [be unfair if not designed well](https://huggingface.co/blog/open-llm-leaderboard-drop), but overall they still provide signal at the task level.
25
 
26
- For capabilities however, it's hard to decompose them into well-defined and precise tasks: what does "good at math" mean? good at arithmetic? at logic? able to reason on mathematical concepts?
27
 
28
- In this case, people tend to do more "holistic" evaluations, by not decomposing the capability in actual tasks, but assuming that performance on general samples will be a **good proxy** for what we aim to measure. For example, GSM8K is made of actual high school math problems, which require a whole set of capabilities to solve. It also means that both failure and success are very hard to interpret. Some capabilities or topics, such as "is this model good at writing poetry?" or "are the model outputs helpful?" are even harder to evaluate with automatic metrics - and at the same time, models now seem to have more and more **generalist** capabilities, so we need to evaluate their abilities in a broader manner. (For example, there was a debate in the scientific community as to whether LLMs [can draw](https://arxiv.org/abs/2303.12712) unicorns [or not](https://twitter.com/DimitrisPapail/status/1719119242186871275). Most likely not at this point, but clearly an important point to investigate.)
29
 
30
- Automatic benchmarks also tend to have another problem: once they are published publicly in plain text, they are very likely to end up (often accidentally) in the training datasets of models. Some benchmarks creators, like the authors of BigBench, have tried to mitigate this by adding a "canary string" (a very specific combination of characters) for people to look for, and remove from training sets, but not everybody is aware of the mechanism nor trying to do this removal. There is also a non negligible quantity of benchmarks, so looking for accidental copies of absolutely all of them in data is costly. Other options include providing benchmarks in an [encrypted form](https://arxiv.org/pdf/2309.16575), or behind a [gating system](https://huggingface.co/datasets/Idavidrein/gpqa). However, when evaluating closed models behind black box APIs, there is no guarantee that the provided data won’t be later used internally for training or fine-tuning.
31
 
32
- The case were an evaluation dataset ends up in the training set is called **contamination**, and a model which was contaminated will have a high benchmark performance that does not generalize well to the underlying task (an extensive description of contamination can be found [here](https://aclanthology.org/2023.findings-emnlp.722/), and here is a fun way to [detect it](https://arxiv.org/abs/2311.06233)). A way to address contamination is to run [**dynamic benchmarks**](https://arxiv.org/abs/2104.14337) (evaluations on datasets which are regularly refreshed to provide scores on systematically unseen new data), but this approach is costly in the long term.
33
 
34
- #### Human as a judge
35
 
36
- A solution to both contamination and more open-ended evaluation is asking humans to evaluate model outputs.
 
 
37
 
38
- This is usually done by tasking humans with first, prompting models, then, grading a model answer or ranking several outputs according to guidelines. Using humans as judges allows to study more complex tasks, with more flexibility than automated metrics. It also prevents most contamination cases, since the written prompts are (hopefully) new. Lastly, it correlates well with human preference, since this is literally what is evaluated!
39
 
40
- Different approaches exist to evaluate models with humans in the loop.
41
 
42
- **Vibes-checks** is the name given to manual evaluations done individually by some members of the community, usually on undisclosed prompts, to get an overall "feeling" of how well models perform on many use cases, which range from coding to quality of smut written. (I've also seen the term "canary-testing" used for this, in reference to high signal canary in a coalmine approach). Often shared on Twitter and Reddit, they mostly constitute anecdotal evidence, and tend to be highly sensitive to confirmation bias (in other words, people tend to find what they look for). However, some people have been trying to do more methodical vibe-checks evaluations; for example, the user *Wolfram Ravenwolf* shares his model comparisons findings in a very systematic way through blogs (see [here](https://huggingface.co/blog/wolfram/llm-comparison-test-llama-3) for an example).
43
 
44
- Using community feedback to establish massive model rankings is what we call an **arena**. A well known example of this is the [LMSYS chatbot arena](https://huggingface.co/spaces/lmsys/chatbot-arena-leaderboard), where community users are asked to chat with models until they find one is better than the other. Votes are then aggregated in an Elo ranking (a ranking of matches) to select which model is "the best". The obvious problem of such an approach is the high subjectivity - it's hard to enforce a consistent grading from many community members using broad guidelines, especially since annotators preferences tend to be [culturally bound](https://arxiv.org/abs/2404.16019v1) (with different people favoring different discussion topics, for example). One can hope that this effect is smoothed over by the sheer scale of the votes, through a "wisdom of the crowd" effect (this effect was found by a statistician named Galton, who observed that individual answers trying to estimate a numerical value, like the weight of a hog, could be modeled as a probability distribution centered around the actual answer).
 
 
 
45
 
46
- The last approach is **systematic annotations**, where you provide extremely specific guidelines to paid selected annotators, in order to remove as much as the subjectivity bias as possible (this is the approach used by [ScaleAI](https://scale.com/guides/data-labeling-annotation-guide#hight-quality-data-annotations), and most data annotation companies). However, it can get extremely expensive fast, as you have to keep on doing evaluations in a continuous and non automatic manner for every new model you want to evaluate, and it can still fall prey to human bias (this [study](https://arxiv.org/abs/2205.00501) showed that people with different identities tend to rate model answer toxicity very differently).
47
 
48
- Recent [work](https://arxiv.org/pdf/2309.16349) has also shown that human evaluators tend to estimate the quality of answers based on first impressions, instead of actual factuality or faithfulness. Crowdsourced annotators are notably very sensitive to tone, and underestimate the number of factual or logical errors in an assertive answer. In other terms, if a model says wrong things in a confident tone, human evaluators are much less likely to notice it, which could skew ratings towards the more assertive models. (Expert annotators are less likely to fall prey to these biases.) This kind of human bias was confirmed in another [paper](https://arxiv.org/pdf/2310.13548) : humans are most likely to prefer answers which appeal to their views or align with their opinions or errors, rather than answers which are factually correct.
49
 
50
- These biases are not unexpected, but they must be taken into account: not all use cases should rely on using human annotators, especially crowdsourced, unexpert ones - any task requiring factuality (such as code writing, evaluation of model knowledge, etc) should include another, more robust, type of evaluation to complete the benchmark.
 
 
51
 
52
- #### Model as a judge
53
 
54
- To mitigate the cost of human annotators, some people have looked into using models or derived artifacts (preferably aligned with human preferences) to evaluate models' outputs. This approach is not new, as you can find techniques to measure summarization quality from [model embeddings](https://arxiv.org/abs/1904.09675) in 2019.
55
 
56
- Two approach exist for grading: using [generalist, high capability models](https://arxiv.org/abs/2306.05685v4) or using [small specialist models](https://arxiv.org/pdf/2405.01535) trained specifically to discriminate from preference data. The former approach gives results well correlated with human preference, but most strong enough models tend to be closed source, therefore subject to change behind APIs, and uninterpretable.
57
 
58
- LLM as judges have several strong limitations: they tend to [favor their own outputs](https://arxiv.org/abs/2404.13076) when scoring answers, are [bad at providing consistent score ranges](https://twitter.com/aparnadhinak/status/1748368364395721128) (though you can improve this with asking the model to explain its reasoning [before providing a score](https://twitter.com/seungonekim/status/1749289437165769177)), and are actually not that consistent [with human rankings](https://arxiv.org/pdf/2308.15812).
59
 
60
- My main personal gripe with using models as judges is that they introduce very subtle and un-interpretable bias in the answer selection. I feel that, much like when crossbreeding too much in genetics studies, you end up with dysfunctional animals or plants, by using LLMs to select and train LLMs, we are just as likely to introduce minute changes that will have bigger repercussions a couple generations down the line. I believe this type of bias is less likely to occur in smaller and more specialized models as judges (such as toxicity classifiers), but this remains to be rigorously tested and proven.
61
 
62
- ### Why do we do LLM evaluation?
 
 
63
 
64
- Now that we’ve seen how we do evaluation, what is it actually useful for?
65
 
66
- I strongly believe that there are 3 main reasons for which people do evaluation, which tend to be conflated together, but are actually **very different**, and each answer a separate question.
67
 
68
- <HtmlEmbed src="d3-intro-boxes.html" title="Evaluation purposes" />
69
 
 
70
 
71
- #### 1) Is my model training well? Is my training method sound? - Non-regression testing
 
 
72
 
73
- **Non-regression testing** is a concept which comes from the software industry, to make sure small changes have not broken the overall approach.
74
 
75
- The idea is the following: when you add a new feature to your software, or fix a problem in the code base, have you broken something else? That's what non-regression tests are for: making sure the expected, high-level behavior of your software is not suddenly broken by a (seemingly unrelated) change.
 
 
76
 
77
- When you select a setup to train models, you want to test something very similar, and make sure that your changes (choosing different training data, architecture, parameters, etc) have not "broken" the expected performance for a model of these properties.
78
 
79
- To give a concrete example, you would expect a 7B base LLM to get between 50 and 65 on (multiple choice) MMLU after training, and on the other hand, know that performance fluctuating between 20 and 30 indicates that no learning occurred.
80
 
81
- For "non-regression" evaluation, you need to look at 1) evaluation scores **trajectories** (is the performance better now that when starting training), 2) evaluation scores **ranges** (is the performance within what's expected). You actually... don't care about the precise score themselves!
82
 
83
- This evaluation is therefore not here to tell you anything about actual model capabilities, but instead just here to confirm that your training approach is "as sound" as the other training approach, and that your model behaves in similar ways. I believe that even some evaluations simply looking at changes in the perplexity (probabilities) of text could be sufficient for this step, but you usually want benchmarks which have a high "signal to noise" ratio, or in other words, you want to make sure that a big change in the score reflects a big shift in your model.
84
 
85
- #### 2) Which model is the best? Is my model better than your model? - Leaderboards and rankings
 
 
86
 
87
- The next role of evaluation is simply to sort models to find and select the best architectures and approaches overall. If you have a leaderboard, take the best model, and it's not working on your use case, it's unlikely the next best model will work. In [their paper](https://arxiv.org/pdf/2404.02112) about lessons learned on benchmarking and dataset design from the ImageNet era, the authors argue that, since scores are susceptible to instability, the only robust way to evaluate models is through rankings, and more specifically by finding broad groups of evaluations which provide consistent and stable rankings.
88
 
89
- I believe looking for ranking stability is indeed an extremely interesting approach to model benchmarking, as we have shown that LLMs *scores* on automated benchmarks are extremely susceptible to [minute changes in prompting](https://huggingface.co/blog/evaluation-structured-outputs), and that human evaluations are not more consistent - where *rankings* are actually more stable when using robust evaluation methods.
90
 
91
- If scores, by themselves, are not that relevant, could using the relative ordering of models tell us something of value instead?
92
 
93
- In the related ICLR 2024 plenary of evaluation, Moritz Hardt compared adding perturbations to the Open LLM Leaderboard (through minuscule score modification, well within score ranges) and on the Chatbot Arena (through adding a bad contender to the arena to see how it affected the Elo rankings). Neither these benchmarks provide stable and consistent rankings at the moment. We'll be sure to explore this aspect with future versions of the Open LLM Leaderboard!
 
 
94
 
95
- #### 3) Where are we, as a field, in terms of model capabilities? Can my model do X?
 
 
96
 
97
- "How do you know if models can do X?" is a question which comes up a lot, and I think it is a very valid one.
98
 
99
- However, for any complex capability, **we cannot at the moment just say "this model is the best at this", but instead "this model is the best on this task that we hope is a good proxy for this capability, without any guarantee"**.
100
 
101
- We are strongly missing any kind of good definitions and framework on what a capability is for a machine learning model, especially for those surrounding reasoning and mind theory. However, this is not specific to machine learning! In human and animal studies, it is also quite hard to define what constitutes a "capability", and metrics which try to provide precise scores (IQ and EQ for example) are hotly debated and controversial, with reason.
102
 
103
- We might want to look at social sciences to think about evaluation of capabilities, as in these fields, people are used to thinking seriously about confounding factors in data gathering and analysis. However, I also believe it likely that 1) we cannot define these broad capabilities at all, since we cannot define them in humans and animals at the moment, 2) frameworks made with the human (or animal) in mind will not transfer well to models, as the underlying behaviors and assumptions are not the same.
104
 
105
- ### Conclusion
106
 
107
- LLM evaluation is nowadays done in the following manner:
108
- Using automatic benchmarks, affected by contamination and lack of “generalness” (the latter not necessarily being a bad thing, as specialized evaluations are interesting)
109
- Using human evaluations, which tends to suffer from lack of reproducibility at a small scale, and psychological biases overall (such as preference for sycophantic answers), though one can hope some of the biases get smoothed over at a high scale
110
- Using models as judges, which has very subtle biases when evaluating, likely to be unnoticed but introduce perturbations downstream.
111
-
112
- However, all is not lost: evaluation, within its limits, is still able to provide some signal on which new training methods or datasets sound promising or not, both from looking at how performance falls within expected ranges (non-regression testing), and at how models are ranked overall (with stable enough evaluations). We can also hope that combining enough data points across topics and tasks will provide us with enough signal to get an idea of overall model performance, without however assuming anything about more “general” capabilities.
113
 
114
- Contrary to hype, we cannot really evaluate “general model capabilities” at the moment, first and foremost because we have not defined what that means. However, LLM evaluation, as a research field, is very much in its infancy at the moment, and there is a lot to be done, which is very exciting! Inspiration can be grabbed from many fields, from machine learning [interpretability](https://transformer-circuits.pub/2024/scaling-monosemanticity/index.html) to sociology, in order to define new metrics and tasks. Interdisciplinary work will likely open very new cool directions for the field!
 
3
  ---
4
 
5
  import HtmlEmbed from "../../components/HtmlEmbed.astro";
6
+ import Note from "../../components/Note.astro";
7
+ import Sidenote from "../../components/Sidenote.astro";
8
 
9
+ ## Intro
10
 
11
+ ### Why should you even care about evaluation?
12
 
13
+ Evaluation, in short, is how you know a model is "good at" something (though we'll see the reality is more complex than this).
14
 
15
+ As you navigate the world of LLMs—whether you're training or fine-tuning your own models, selecting one for your application, or trying to understand the state of the field—you'll inevitably encounter evaluation. It's everywhere: leaderboards ranking models, benchmarks claiming to measure "reasoning" or "knowledge," papers announcing new state-of-the-art results.
16
 
17
+ But what does it all actually mean? And more importantly, what can evaluation really tell you?
18
 
19
+ This guide is here to help you understand evaluation in practice: what it can and cannot do, when to trust different approaches (what their limitations and biases are too!), and how to think critically about the claims made from evaluation results.
 
 
20
 
21
+ Before we dive into the details, let's quickly look at why people do evaluation, concretely, and how.
22
 
23
+ ### Why do we do LLM evaluation?
24
 
25
+ There are 3 main reasons for which people do evaluation, which tend to be conflated together, but are actually **very different**, and each answer a separate question.
26
 
27
+ <HtmlEmbed src="d3-intro-boxes.html" title="Evaluation purposes" />
28
 
29
+ #### Is this model training correctly?
30
 
31
+ **Non-regression testing** is a concept which comes from the software industry, to make sure small changes have not broken the overall approach. The idea is the following: when you add a new feature to your software, or fix a problem in the code base, have you broken something else? That's what non-regression tests are for: making sure the expected, high-level behavior of your software is not suddenly broken by a (seemingly unrelated) change.
32
 
33
+ When you select a setup to train models, you want to test something very similar, and make sure that your changes (choosing different training data, architecture, parameters, etc) have not "broken" the expected performance for a model of these properties.
34
 
35
+ In ML, these experiments are often referred to as ablations, and the core of them is actually having a good set of evaluations (looking at the loss will only get you so far!)
36
 
37
+ For these evaluations, you need to select evaluations which
38
+ - give you a strong enough signal (see section TODO on how to select your evals)
39
+ - while being relatively cheap to run as you'll be running them **a lot**.
40
 
41
+ You'll also need to look at both **trajectories** (is the performance better now that when starting training) and scores **ranges** (is the performance within what's expected). You actually... don't really care about the precise score themselves! This evaluation is therefore not here to tell you anything about actual model capabilities, but instead just here to confirm that your training approach is "as sound" as the other training approach, and that your model behaves in similar ways.
42
 
43
+ #### Which model is the best on X?
44
 
45
+ The next role of evaluation is simply to sort models to find and select the best architectures and approaches for use case X.
46
 
47
+ If you have a leaderboard for your domain and task, take the best model, and it's not working for you, it's unlikely the next best model will work.
48
+ <Sidenote>
49
+ In [their paper](https://arxiv.org/pdf/2404.02112) about lessons learned on benchmarking and dataset design from the ImageNet era, the authors argue that, since scores are susceptible to instability, the only robust way to evaluate models is through rankings, and more specifically by finding broad groups of evaluations which provide consistent and stable rankings. I believe looking for ranking stability is indeed an extremely interesting approach to model benchmarking, as we have shown that LLMs *scores* on automated benchmarks are extremely susceptible to [minute changes in prompting](https://huggingface.co/blog/evaluation-structured-outputs), and that human evaluations are not more consistent - where *rankings* are actually more stable when using robust evaluation methods.
50
+ </Sidenote>
51
 
 
52
 
53
+ If you don't... that's where you need to think about designing your own evaluations, which we will cover below in section TODO.
54
 
55
+ <Note>
56
+ "How do you know for sure if models can do X?" is a question which comes up a lot, and it is a very valid one. However, for any complex capability, **we cannot at the moment just say "this model is the best at this", but instead "this model is the best on this task that we hope is a good proxy for this capability, without any guarantee"**.
57
+ </Note>
58
 
 
59
 
60
+ #### When will we finally reach AGI?
61
 
62
+ We are strongly missing any kind of good definitions and framework on what intelligence is for machine learning models (though some people have tried, for example [Chollet](https://arxiv.org/abs/1911.01547) in 2019 and [Hendrycks et al](https://www.agidefinition.ai/paper.pdf) this year). However, this problem is not specific to machine learning! In human and animal studies, it is also quite hard to define what constitutes intelligence, and metrics which try to provide precise scores (IQ and EQ for example) are hotly debated and controversial, with reason.
63
 
64
+ To solve this, we should look at social sciences, as in these fields, people are used to thinking seriously about confounding factors in data gathering and results analysis, which I'm not seeing a lot in "intelligence evaluation" in ML for now.
65
 
66
+ However, I also don't think we'll be able to define these broad capabilities at all (we'll just end up with moving targets) since we cannot define them in humans and animals at the moment, and frameworks made with the human (or animal) in mind will most likely not transfer well to models, as the underlying behaviors and assumptions are not the same.
67
 
68
+ <Sidenote>
69
+ I also believe that this question is a bad one, as targeting "general intelligence" is much more blurry, risky, and less useful than targetting good tools with specific capabilities for actual problems that humans encounter at their jobs.
70
+ </Sidenote>
71
 
72
+ ### So how do people evaluate models, then?
73
 
74
+ To my knowledge, at the moment, people use 3 main ways to do evaluation: automated benchmarking, using humans as judges, and using models as judges. Each approach has its own reason for existing, uses, and limitations.
75
 
76
+ #### Automated benchmarks
77
 
78
+ Automated benchmarking usually works the following way: you'd like to know how well your model performs on something. This something can be a well-defined concrete **task**, such as *How well can my model classify spam from non spam emails?*, or a more abstract and general **capability**, such as *How good is my model at math?*.
79
 
80
+ From this, you construct an evaluation, usually made of two things:
81
+ - a collection of *samples*, given as input to the model to see what comes out as output, sometimes coupled with a reference (called gold) to compare with. Samples are usually designed to try to emulate what you want to test the model on: for example, if you are looking at email classification, you create a dataset of spam and non spam emails, try to include some hard edge cases, etc. For LLMs, the two main tasks are generation evaluation (comparing generated text with a reference after normalization), or multi-choice (compare the relative log-probabilities of possible continuations after a prompt).
82
+ - a *metric*, which is a way to compute a score for the model. For example, how accurately can your model classify spam (score of well classified sample = 1, badly classified = 0).
83
 
84
+ This is more interesting to do on data that was not included in the model training set, because you want to test if it **generalizes** well. You don't want a model which can only classify emails it has already "seen", that would not be very useful!
85
 
86
+ <Note>
87
+ A model which can only predict well on its training data (and has not latently learnt more high-level general patterns) is said to be **overfitting**. In less extreme cases, you still want to test if your model is able to generalize to data patterns which were not in the training set's distribution (for example, classify spam emails about 'health' products after having seen only spam emails about fake banks).
88
+ </Note>
89
 
90
+ This works quite well for very well-defined tasks, where performance is "easy" to assess and measure: when you are literally testing your model on spam classification, you can say "the model classified correctly n% of these samples". For LLMs benchmarks, some issues can arise, such as models [favoring specific choices based on the order in which they have been presented for multi-choice evaluations](https://arxiv.org/abs/2309.03882), and generative evaluations relying on normalisations which can easily [be unfair if not designed well](https://huggingface.co/blog/open-llm-leaderboard-drop), but overall they still provide signal at the task level.
91
 
92
+ For capabilities however, it's hard to decompose them into well-defined and precise tasks: what does "good at math" mean? good at arithmetic? at logic? able to reason on mathematical concepts?
93
 
94
+ In this case, people tend to do more "holistic" evaluations, by not decomposing the capability in actual tasks, but assuming that performance on general samples will be a **good proxy** for what we aim to measure. For example, GSM8K is made of actual high school math problems, which require a whole set of capabilities to solve. It also means that both failure and success are very hard to interpret. Some capabilities or topics, such as "is this model good at writing poetry?" or "are the model outputs helpful?" are even harder to evaluate with automatic metrics - and at the same time, models now seem to have more and more **generalist** capabilities, so we need to evaluate their abilities in a broader manner. (For example, there was a debate in the scientific community as to whether LLMs [can draw](https://arxiv.org/abs/2303.12712) unicorns [or not](https://twitter.com/DimitrisPapail/status/1719119242186871275). A year later, seems like most can!)
95
 
96
+ Automatic benchmarks also tend to have another problem: once they are published publicly in plain text, they are very likely to end up (often accidentally) in the training datasets of models. Some benchmarks creators, like the authors of BigBench, have tried to mitigate this by adding a "canary string" (a very specific combination of characters) for people to look for, and remove from training sets, but not everybody is aware of the mechanism nor trying to do this removal. There is also a non negligible quantity of benchmarks, so looking for accidental copies of absolutely all of them in data is costly. Other options include providing benchmarks in an [encrypted form](https://arxiv.org/pdf/2309.16575), or behind a [gating system](https://huggingface.co/datasets/Idavidrein/gpqa). However, when evaluating closed models behind black box APIs, there is no guarantee that the provided data won’t be later used internally for training or fine-tuning.
97
 
98
+ <Note>
99
+ The case were an evaluation dataset ends up in the training set is called **contamination**, and a model which was contaminated will have a high benchmark performance that does not generalize well to the underlying task (an extensive description of contamination can be found [here](https://aclanthology.org/2023.findings-emnlp.722/), and here is a fun way to [detect it](https://arxiv.org/abs/2311.06233)). A way to address contamination is to run [**dynamic benchmarks**](https://arxiv.org/abs/2104.14337) (evaluations on datasets which are regularly refreshed to provide scores on systematically unseen new data), but this approach is costly in the long term.
100
+ </Note>
101
 
102
+ #### Human as a judge
103
 
104
+ A solution to both contamination and more open-ended evaluation is asking humans to evaluate model outputs.
105
 
106
+ This is usually done by tasking humans with first, prompting models, then, grading a model answer or ranking several outputs according to guidelines. Using humans as judges allows to study more complex tasks, with more flexibility than automated metrics. It also prevents most contamination cases, since the written prompts are (hopefully) new. Lastly, it correlates well with human preference, since this is literally what is evaluated!
107
 
108
+ Different approaches exist to evaluate models with humans in the loop.
109
+
110
+ **Vibes-checks** is the name given to manual evaluations done individually by some members of the community, usually on undisclosed prompts, to get an overall "feeling" of how well models perform on many use cases, which range from coding to quality of smut written. (I've also seen the term "canary-testing" used for this, in reference to high signal canary in a coalmine approach). Often shared on Twitter and Reddit, they mostly constitute anecdotal evidence, and tend to be highly sensitive to confirmation bias (in other words, people tend to find what they look for). However, some people have been trying to do more methodical vibe-checks evaluations; for example, the user *Wolfram Ravenwolf* shares his model comparisons findings in a very systematic way through blogs (see [here](https://huggingface.co/blog/wolfram/llm-comparison-test-llama-3) for an example).
111
 
112
+ Using community feedback to establish massive model rankings is what we call an **arena**. A well known example of this is the [LMSYS chatbot arena](https://huggingface.co/spaces/lmsys/chatbot-arena-leaderboard), where community users are asked to chat with models until they find one is better than the other. Votes are then aggregated in an Elo ranking (a ranking of matches) to select which model is "the best". The obvious problem of such an approach is the high subjectivity - it's hard to enforce a consistent grading from many community members using broad guidelines, especially since annotators preferences tend to be [culturally bound](https://arxiv.org/abs/2404.16019v1) (with different people favoring different discussion topics, for example). One can hope that this effect is smoothed over by the sheer scale of the votes, through a "wisdom of the crowd" effect (this effect was found by a statistician named Galton, who observed that individual answers trying to estimate a numerical value, like the weight of a hog, could be modeled as a probability distribution centered around the actual answer).
113
+
114
+ The last approach is **systematic annotations**, where you provide extremely specific guidelines to paid selected annotators, in order to remove as much as the subjectivity bias as possible (this is the approach used by most data annotation companies). However, it can get extremely expensive fast, as you have to keep on doing evaluations in a continuous and non automatic manner for every new model you want to evaluate, and it can still fall prey to human bias (this [study](https://arxiv.org/abs/2205.00501) showed that people with different identities tend to rate model answer toxicity very differently).
115
 
116
+ Recent [work](https://arxiv.org/pdf/2309.16349) has also shown that human evaluators tend to estimate the quality of answers based on first impressions, instead of actual factuality or faithfulness. Crowdsourced annotators are notably very sensitive to tone, and underestimate the number of factual or logical errors in an assertive answer. In other terms, if a model says wrong things in a confident tone, human evaluators are much less likely to notice it, which could skew ratings towards the more assertive models. (Expert annotators are less likely to fall prey to these biases.) This kind of human bias was confirmed in another [paper](https://arxiv.org/pdf/2310.13548) : humans are most likely to prefer answers which appeal to their views or align with their opinions or errors, rather than answers which are factually correct.
117
 
118
+ These biases are not unexpected, but they must be taken into account: not all use cases should rely on using human annotators, especially crowdsourced, unexpert ones - any task requiring factuality (such as code writing, evaluation of model knowledge, etc) should include another, more robust, type of evaluation to complete the benchmark.
119
 
120
+ #### Model as a judge
121
 
122
+ To mitigate the cost of human annotators, some people have looked into using models or derived artifacts (preferably aligned with human preferences) to evaluate models' outputs. This approach is not new, as you can find techniques to measure summarization quality from [model embeddings](https://arxiv.org/abs/1904.09675) in 2019.
123
 
124
+ Two approach exist for grading: using [generalist, high capability models](https://arxiv.org/abs/2306.05685v4) or using [small specialist models](https://arxiv.org/pdf/2405.01535) trained specifically to discriminate from preference data. The former approach gives results well correlated with human preference, but most strong enough models tend to be closed source, therefore subject to change behind APIs, and uninterpretable.
125
 
126
+ LLM as judges have several strong limitations: they tend to [favor their own outputs](https://arxiv.org/abs/2404.13076) when scoring answers, are [bad at providing consistent score ranges](https://twitter.com/aparnadhinak/status/1748368364395721128) (though you can improve this with asking the model to explain its reasoning [before providing a score](https://twitter.com/seungonekim/status/1749289437165769177)), and are actually not that consistent [with human rankings](https://arxiv.org/pdf/2308.15812).
 
 
 
 
 
127
 
128
+ My main personal gripe with using models as judges is that they introduce very subtle and un-interpretable bias in the answer selection. I feel that, much like when crossbreeding too much in genetics studies, you end up with dysfunctional animals or plants, by using LLMs to select and train LLMs, we are just as likely to introduce minute changes that will have bigger repercussions a couple generations down the line. I believe this type of bias is less likely to occur in smaller and more specialized models as judges (such as toxicity classifiers), but this remains to be rigorously tested and proven.
app/src/content/chapters/model-as-a-judge/basics.mdx CHANGED
@@ -2,6 +2,9 @@
2
  title: "Model as a Judge: Basics"
3
  ---
4
 
 
 
 
5
  Judge models are simply **neural network used to evaluate the output of other neural networks**. In most cases, they evaluate text generations.
6
 
7
  Judge models range from small specialized classifiers (think "spam filter", but for toxicity for example) to LLMs, either large and generalist or small and specialized. In the latter case, when using an LLM as a judge, you give it a prompt to explain how to score models (ex: `Score the fluency from 0 to 5, 0 being completely un-understandable, ...`).
@@ -30,6 +33,17 @@ In my opinion, using LLM judges correctly is extremely tricky, and it's easy to
30
  - They are indeed scalable, but contribute to creating massive amounts of data which themselves need to be examined to ensure their quality (for example, you can improve the quality of LLM-judges by asking them to generate a thinking trace, or reasoning around their data, which makes even more new artificial data to analyse)
31
  - They are indeed cheap to instantiate, but paying actual expert human annotators is likely to give you qualitatively better results for your specific use cases.
32
 
 
 
 
 
 
 
 
 
 
 
 
33
  This section is a bit long, because you need to be well aware of their limitations: a lot of people are blindly jumping into using model judges because they seem easier, but then end up with uninsterpretable data with tricky bias to extract.
34
 
35
  If you want to give it a go, I suggest first reading this [very good guide](https://huggingface.co/learn/cookbook/en/llm_judge) (⭐) by Aymeric Roucher on how to setup your first LLM as judge!
 
2
  title: "Model as a Judge: Basics"
3
  ---
4
 
5
+ import Note from "../../../components/Note.astro";
6
+ import Sidenote from "../../../components/Sidenote.astro";
7
+
8
  Judge models are simply **neural network used to evaluate the output of other neural networks**. In most cases, they evaluate text generations.
9
 
10
  Judge models range from small specialized classifiers (think "spam filter", but for toxicity for example) to LLMs, either large and generalist or small and specialized. In the latter case, when using an LLM as a judge, you give it a prompt to explain how to score models (ex: `Score the fluency from 0 to 5, 0 being completely un-understandable, ...`).
 
33
  - They are indeed scalable, but contribute to creating massive amounts of data which themselves need to be examined to ensure their quality (for example, you can improve the quality of LLM-judges by asking them to generate a thinking trace, or reasoning around their data, which makes even more new artificial data to analyse)
34
  - They are indeed cheap to instantiate, but paying actual expert human annotators is likely to give you qualitatively better results for your specific use cases.
35
 
36
+ <Note title="Critical limitations of LLM judges" emoji="⚠️" variant="warning">
37
+
38
+ Using LLM judges is extremely tricky:
39
+ - **Hidden biases**: Harder to detect than human biases; creates echo-chamber effects
40
+ - **Data overload**: Generates massive synthetic data needing quality examination
41
+ - **False objectivity**: Seems objective but reinforces subtle biases
42
+ - **Expert humans better**: For critical use cases, expert annotators provide higher quality
43
+
44
+ See [Tips and tricks](./tips-and-tricks) for bias mitigation strategies.
45
+ </Note>
46
+
47
  This section is a bit long, because you need to be well aware of their limitations: a lot of people are blindly jumping into using model judges because they seem easier, but then end up with uninsterpretable data with tricky bias to extract.
48
 
49
  If you want to give it a go, I suggest first reading this [very good guide](https://huggingface.co/learn/cookbook/en/llm_judge) (⭐) by Aymeric Roucher on how to setup your first LLM as judge!
app/src/content/chapters/model-as-a-judge/designing-your-evaluation-prompt.mdx CHANGED
@@ -2,13 +2,16 @@
2
  title: "Designing your evaluation prompt"
3
  ---
4
 
 
 
 
5
  ### Designing your evaluation prompt
6
 
7
  Once you've selected your model, you need to define what is the best possible prompt for your task.
8
 
9
  Some general guidelines I've come across online when designing the prompt itself are:
10
  - Provide a clear description of the task at hand:
11
- - `Your task is to do X`.
12
  - `You will be provided with Y`.
13
  - Provide clear instructions on the evaluation criteria, including a detailed scoring system if needed:
14
  - `You should evaluate property Z on a scale of 1 - 5, where 1 means ...`
@@ -18,6 +21,16 @@ Some general guidelines I've come across online when designing the prompt itself
18
  - Specify the desired output format (adding fields will help consistency)
19
  - `Your answer should be provided in JSON, with the following format {"Score": Your score, "Reasoning": The reasoning which led you to this score}`
20
 
 
 
 
 
 
 
 
 
 
 
21
  You can and should take inspiration from [MixEval](https://github.com/huggingface/lighteval/blob/main/src/lighteval/tasks/extended/mix_eval/judge_prompts.pyy) or [MTBench](https://github.com/huggingface/lighteval/blob/main/src/lighteval/tasks/extended/mt_bench/judge_prompt_templates.py) prompt templates.
22
 
23
  Other tidbits:
@@ -25,16 +38,44 @@ Other tidbits:
25
  - If you really want a score, use an integer scale make sure you provide a detailed explanation for what [each score represents](https://x.com/seungonekim/status/1749289437165769177), or an additive prompt (`provide 1 point for this characteristic of the answer, 1 additional point if ...` etc)
26
  - Using one prompt per capability to score tends to give better and more robust results
27
 
 
 
 
 
 
 
28
  You can also improve accuracy using the following, possibly more costly, techniques:
29
  - **Few shot examples**: like in many other tasks, if you provide examples it can help its reasoning. However, this adds to your context length.
30
- - **Reference**: you can also enhance your prompt with a reference if present, which increases accuracy
31
  - **CoT**: [improves accuracy](https://arxiv.org/abs/2212.08073), if you ask the model to output its chain of thought **before** the score (also observed [here](https://x.com/seungonekim/status/1749289437165769177))
32
  - **Multiturn analysis**: can improve [factual error detection](https://arxiv.org/abs/2305.13281)
33
- - Using **a jury** (many judges, where you pick an aggregate of the answers): [gives better results](https://arxiv.org/abs/2404.18796) than using a single model.
34
- - It can be made considerably less costly by leveraging many smaller models instead of one big expensive model.
35
  - You can also experiment with using one model with variations on temperature
36
  - Surprisingly, the community has found that adding stakes to the prompts (`answer correctly and you'll get a kitten`) can increase correctness. Your mileage may vary on this one, adapt to your needs.
37
 
 
 
 
 
 
 
 
 
 
 
 
38
  Note on prompting: Depending on the stakes of your use case, to remove as much bias as possible, you would want to look at work done in sociology on how to design good surveys. If you treat your evaluator as a replacement for a human annotator, then you need to look at similar metrics: computing inter-annotator agreement, using correct survey design methodology to mitigate bias, etc.
39
 
 
 
 
 
 
 
 
 
 
 
 
40
  However, most people don't really want a reproducible and high quality unbiased eval, and will be happy with quick and dirty evaluation through OK-ish prompts. (Which is an OK situation to be in! Just depends on the consequences attached).
 
2
  title: "Designing your evaluation prompt"
3
  ---
4
 
5
+ import Note from "../../../components/Note.astro";
6
+ import Sidenote from "../../../components/Sidenote.astro";
7
+
8
  ### Designing your evaluation prompt
9
 
10
  Once you've selected your model, you need to define what is the best possible prompt for your task.
11
 
12
  Some general guidelines I've come across online when designing the prompt itself are:
13
  - Provide a clear description of the task at hand:
14
+ - `Your task is to do X`.
15
  - `You will be provided with Y`.
16
  - Provide clear instructions on the evaluation criteria, including a detailed scoring system if needed:
17
  - `You should evaluate property Z on a scale of 1 - 5, where 1 means ...`
 
21
  - Specify the desired output format (adding fields will help consistency)
22
  - `Your answer should be provided in JSON, with the following format {"Score": Your score, "Reasoning": The reasoning which led you to this score}`
23
 
24
+ <Note title="Core prompt design principles" emoji="📝" variant="info">
25
+
26
+ **Essential elements for effective judge prompts:**
27
+ - **Clear task description**: Specify exactly what the judge needs to do
28
+ - **Detailed criteria**: Provide explicit scoring scales with clear definitions
29
+ - **Reasoning steps**: Guide the judge through the evaluation process
30
+ - **Structured output**: Use JSON format for consistency and parsability
31
+
32
+ </Note>
33
+
34
  You can and should take inspiration from [MixEval](https://github.com/huggingface/lighteval/blob/main/src/lighteval/tasks/extended/mix_eval/judge_prompts.pyy) or [MTBench](https://github.com/huggingface/lighteval/blob/main/src/lighteval/tasks/extended/mt_bench/judge_prompt_templates.py) prompt templates.
35
 
36
  Other tidbits:
 
38
  - If you really want a score, use an integer scale make sure you provide a detailed explanation for what [each score represents](https://x.com/seungonekim/status/1749289437165769177), or an additive prompt (`provide 1 point for this characteristic of the answer, 1 additional point if ...` etc)
39
  - Using one prompt per capability to score tends to give better and more robust results
40
 
41
+ <Sidenote>
42
+
43
+ Pairwise comparison consistently outperforms absolute scoring for judging model outputs. It correlates better with human preferences and is less sensitive to judge biases and scale interpretation issues.
44
+
45
+ </Sidenote>
46
+
47
  You can also improve accuracy using the following, possibly more costly, techniques:
48
  - **Few shot examples**: like in many other tasks, if you provide examples it can help its reasoning. However, this adds to your context length.
49
+ - **Reference**: you can also enhance your prompt with a reference if present, which increases accuracy
50
  - **CoT**: [improves accuracy](https://arxiv.org/abs/2212.08073), if you ask the model to output its chain of thought **before** the score (also observed [here](https://x.com/seungonekim/status/1749289437165769177))
51
  - **Multiturn analysis**: can improve [factual error detection](https://arxiv.org/abs/2305.13281)
52
+ - Using **a jury** (many judges, where you pick an aggregate of the answers): [gives better results](https://arxiv.org/abs/2404.18796) than using a single model.
53
+ - It can be made considerably less costly by leveraging many smaller models instead of one big expensive model.
54
  - You can also experiment with using one model with variations on temperature
55
  - Surprisingly, the community has found that adding stakes to the prompts (`answer correctly and you'll get a kitten`) can increase correctness. Your mileage may vary on this one, adapt to your needs.
56
 
57
+ <Note title="Advanced techniques to improve accuracy" emoji="⚡" variant="success">
58
+
59
+ **More sophisticated but effective approaches:**
60
+ - **Chain-of-Thought (CoT)**: Ask for reasoning BEFORE the score
61
+ - **Judge jury**: Multiple judges with aggregated results (can use smaller models to reduce cost)
62
+ - **Few-shot examples**: Provide examples, though this increases context length
63
+ - **Reference answers**: Include reference material to improve accuracy
64
+ - **Multi-turn analysis**: Better for detecting factual errors
65
+
66
+ </Note>
67
+
68
  Note on prompting: Depending on the stakes of your use case, to remove as much bias as possible, you would want to look at work done in sociology on how to design good surveys. If you treat your evaluator as a replacement for a human annotator, then you need to look at similar metrics: computing inter-annotator agreement, using correct survey design methodology to mitigate bias, etc.
69
 
70
+ <Note title="High-stakes evaluation requires rigor" emoji="⚠️" variant="warning">
71
+
72
+ For production or critical use cases, apply rigorous methodologies from sociology:
73
+ - Compute inter-annotator agreement metrics
74
+ - Use proper survey design methodology to mitigate bias
75
+ - Treat the evaluator like a human annotator with similar quality standards
76
+
77
+ Quick evaluations with "OK-ish prompts" may suffice for low-stakes exploration, but don't mistake convenience for quality when decisions matter.
78
+
79
+ </Note>
80
+
81
  However, most people don't really want a reproducible and high quality unbiased eval, and will be happy with quick and dirty evaluation through OK-ish prompts. (Which is an OK situation to be in! Just depends on the consequences attached).
app/src/content/chapters/model-as-a-judge/evaluating-your-evaluator.mdx CHANGED
@@ -2,19 +2,37 @@
2
  title: "Evaluating your evaluator"
3
  ---
4
 
 
 
 
5
  ### Evaluating your evaluator
6
 
7
- Before using a judge-LLM in production or at scale, you want to first evaluate its quality for your task, to make sure its scores are actually relevant and useful for you.
 
 
 
 
8
 
9
- Note: *This will be easier to do if it predicts binary outputs, because you'll be able to interpretable classification metrics (accuracy/recall/precision). If it predicts scores on a scale, it will be much harder to estimate the quality of the correlation with a reference.*
 
 
10
 
11
  So, once you have selected your model judge and its prompt, you'll need to do the following.
12
 
13
  1. **Pick your baseline**
14
- You'll need to compare your evaluator judgments to a baseline: it can be human annotations, the output of another judge model that you know is qualitative on your task, a gold truth, itself with another prompt, etc.
15
 
16
  You don't necessarily need a lot of examples (50 can be enough), but you need them to be extremely representative of your task, discriminative (representative of edge cases notably), and of as high quality as you can manage.
17
 
 
 
 
 
 
 
 
 
 
18
  2. **Pick your metric**
19
  Your metric will be used to compare your judge's evaluations with your reference.
20
 
@@ -29,5 +47,15 @@ For this step, you simply need to use your model and its prompt to evaluate your
29
 
30
  You need to decide what your threshold for acceptance is. Depending on how hard your task is, you can aim for 80% to 95% accuracy, if you're doing pairwise comparison. Regarding correlations (if you're using scores), people in the literature tend to seem happy with 0.8 Pearson correlation with a reference. However, I've seen some papers declare that 0.3 indicates a good correlation with human annotators (^^") so ymmv.
31
 
 
 
 
 
 
 
 
 
 
 
32
 
33
 
 
2
  title: "Evaluating your evaluator"
3
  ---
4
 
5
+ import Note from "../../../components/Note.astro";
6
+ import Sidenote from "../../../components/Sidenote.astro";
7
+
8
  ### Evaluating your evaluator
9
 
10
+ Before using a judge-LLM in production or at scale, you want to first evaluate its quality for your task, to make sure its scores are actually relevant and useful for you.
11
+
12
+ Note: *This will be easier to do if it predicts binary outputs, because you'll be able to interpretable classification metrics (accuracy/recall/precision). If it predicts scores on a scale, it will be much harder to estimate the quality of the correlation with a reference.*
13
+
14
+ <Sidenote>
15
 
16
+ Binary outputs (yes/no, pass/fail) are much easier to evaluate than continuous scores. You can use clear metrics like accuracy, precision, and recall. Continuous scores require correlation analysis which is harder to interpret.
17
+
18
+ </Sidenote>
19
 
20
  So, once you have selected your model judge and its prompt, you'll need to do the following.
21
 
22
  1. **Pick your baseline**
23
+ You'll need to compare your evaluator judgments to a baseline: it can be human annotations, the output of another judge model that you know is qualitative on your task, a gold truth, itself with another prompt, etc.
24
 
25
  You don't necessarily need a lot of examples (50 can be enough), but you need them to be extremely representative of your task, discriminative (representative of edge cases notably), and of as high quality as you can manage.
26
 
27
+ <Note title="Quality over quantity for baseline" emoji="🎯" variant="info">
28
+
29
+ You don't need many baseline examples (50 can suffice), but they must be:
30
+ - **Representative**: Cover the full range of your task
31
+ - **Discriminative**: Include edge cases and challenging examples
32
+ - **High quality**: Use the best reference data you can obtain
33
+
34
+ </Note>
35
+
36
  2. **Pick your metric**
37
  Your metric will be used to compare your judge's evaluations with your reference.
38
 
 
47
 
48
  You need to decide what your threshold for acceptance is. Depending on how hard your task is, you can aim for 80% to 95% accuracy, if you're doing pairwise comparison. Regarding correlations (if you're using scores), people in the literature tend to seem happy with 0.8 Pearson correlation with a reference. However, I've seen some papers declare that 0.3 indicates a good correlation with human annotators (^^") so ymmv.
49
 
50
+ <Note title="Acceptance thresholds vary widely" emoji="📊" variant="warning">
51
+
52
+ **Realistic thresholds for judge quality:**
53
+ - **Pairwise comparison**: Aim for 80-95% accuracy depending on task difficulty
54
+ - **Score correlation**: 0.8 Pearson correlation is considered good, but some papers claim 0.3 is acceptable
55
+
56
+ The wide range in reported "acceptable" correlations (0.3 to 0.8) suggests you should carefully set your own thresholds based on your specific use case requirements.
57
+
58
+ </Note>
59
+
60
 
61
 
app/src/content/chapters/model-as-a-judge/getting-a-judge-llm.mdx CHANGED
@@ -2,19 +2,38 @@
2
  title: "Getting a Judge-LLM"
3
  ---
4
 
 
 
 
5
  ### Getting a Judge-Model
6
 
7
  When using an existing LLM, you can go for [generalist, high capability models](https://arxiv.org/abs/2306.05685v4), using [small specialist models](https://arxiv.org/abs/2405.01535) trained specifically to discriminate from preference data, or training your own.
8
 
9
  #### Using a generalist LLM
10
 
11
- With the introduction of more capable LLMs (such as ChatGPT), some researchers started exploring using big models as judges. The best current big model judges tend to be closed source models (like Claude or gpt-o models) though the gap with open source is closing very fast thanks to high quality models such as [Qwen 2.5](https://huggingface.co/collections/Qwen/qwen25-66e81a666513e518adb90d9e), [Command R+](https://huggingface.co/CohereForAI/c4ai-command-r-plus-08-2024) or [Llama 3.1-405-Instruct](meta-llama/Llama-3.1-405B-Instruct).
12
 
13
  Closed source models, despite their performance, present the multiple disadvantages of being:
14
  - under APIs, which mean that models (therefore results) can change with no notice, hurting the reproducibility of evals
15
  - black boxes, which makes them un-interpretable
16
  - possible sources of data leakage/lack of data privacy, as you send your data to a third party through the internet (which tends to be less safe than locally managed data), and you don't know for certain what is done with it (you often need to opt out of it being used in training sets).
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  However, they also allow anyone to have access to a high quality model without needing to setup things locally or requiring access to hardware. This pros are now also present for most high quality open models, which are accessible through model providers, and solve the first 2 problems above.
19
 
20
  You'll find a good cost analysis of model providers [here](https://huggingface.co/spaces/ArtificialAnalysis/LLM-Performance-Leaderboard) if you need help picking one.
@@ -23,6 +42,12 @@ You'll find a good cost analysis of model providers [here](https://huggingface.c
23
 
24
  You can also make the choice to use tiny specialized LLM judges. With often a couple billion parameters, they can run locally on most recent consumer hardware, while being trained from scratch or fine-tuned using instruction data. You often need to follow their specific prompt formats.
25
 
 
 
 
 
 
 
26
  Some existing models:
27
  - Flow-Judge-v0.1 ([weights](https://huggingface.co/collections/flowaicom/flow-judge-v01-66e6af5fc3b3a128bde07dec)), 3.8B parameters, a Phi-3.5-mini-instruct fine-tuned on a synthetic preference dataset
28
  - Prometheus ([weights](https://huggingface.co/prometheus-eval/prometheus-13b-v1.0), [paper](https://arxiv.org/abs/2310.08491)), 13B parameters, a model trained from scratch on synthetic preference dataset. A 7B parameter [v2](https://huggingface.co/prometheus-eval/prometheus-7b-v2.0) also exists, a Mistral-7B-Instruct-v0.2 fine-tune on a bigger synthetic preference dataset, with added weight merging
@@ -35,8 +60,19 @@ You first need to gather preference data for your task of interest, which can co
35
  - From existing [human preference datasets](https://www.kaggle.com/competitions/lmsys-chatbot-arena)
36
  - From model generated preference data (which you can generate following the above tiny-model judges papers data sections, or get directly, for example from the Prometheus [preference](https://huggingface.co/datasets/prometheus-eval/Preference-Collection) and [feedback](https://huggingface.co/datasets/prometheus-eval/Feedback-Collection) collections).
37
 
38
- Then you need to decide whether to start from a small model to train from scratch, or from an existing model, that you can
39
  - distill into a new smaller model
40
  - quantize.
41
  - then fine-tune (using peft or adapter weights if the model is big and your training compute low) using the above data
42
  - apparently [starting from a reward model works better than from an instruct model](https://x.com/dk21/status/1826292289930674590)
 
 
 
 
 
 
 
 
 
 
 
 
2
  title: "Getting a Judge-LLM"
3
  ---
4
 
5
+ import Note from "../../../components/Note.astro";
6
+ import Sidenote from "../../../components/Sidenote.astro";
7
+
8
  ### Getting a Judge-Model
9
 
10
  When using an existing LLM, you can go for [generalist, high capability models](https://arxiv.org/abs/2306.05685v4), using [small specialist models](https://arxiv.org/abs/2405.01535) trained specifically to discriminate from preference data, or training your own.
11
 
12
  #### Using a generalist LLM
13
 
14
+ With the introduction of more capable LLMs (such as ChatGPT), some researchers started exploring using big models as judges. The best current big model judges tend to be closed source models (like Claude or gpt-o models) though the gap with open source is closing very fast thanks to high quality models such as [Qwen 2.5](https://huggingface.co/collections/Qwen/qwen25-66e81a666513e518adb90d9e), [Command R+](https://huggingface.co/CohereForAI/c4ai-command-r-plus-08-2024) or [Llama 3.1-405-Instruct](meta-llama/Llama-3.1-405B-Instruct).
15
 
16
  Closed source models, despite their performance, present the multiple disadvantages of being:
17
  - under APIs, which mean that models (therefore results) can change with no notice, hurting the reproducibility of evals
18
  - black boxes, which makes them un-interpretable
19
  - possible sources of data leakage/lack of data privacy, as you send your data to a third party through the internet (which tends to be less safe than locally managed data), and you don't know for certain what is done with it (you often need to opt out of it being used in training sets).
20
 
21
+ <Note title="Closed vs open source judge models" emoji="⚖️" variant="warning">
22
+
23
+ **Closed source models (Claude, GPT-o) tradeoffs:**
24
+
25
+ Disadvantages:
26
+ - **Non-reproducible**: Models can change without notice via API updates
27
+ - **Black box**: Un-interpretable decision-making
28
+ - **Privacy risks**: Data sent to third parties, potential leakage
29
+
30
+ Advantages:
31
+ - Easy access without local setup or hardware requirements
32
+
33
+ **Open source models are closing the gap** while solving reproducibility and interpretability issues. Models like Qwen 2.5, Command R+, and Llama 3.1-405-Instruct are now competitive alternatives.
34
+
35
+ </Note>
36
+
37
  However, they also allow anyone to have access to a high quality model without needing to setup things locally or requiring access to hardware. This pros are now also present for most high quality open models, which are accessible through model providers, and solve the first 2 problems above.
38
 
39
  You'll find a good cost analysis of model providers [here](https://huggingface.co/spaces/ArtificialAnalysis/LLM-Performance-Leaderboard) if you need help picking one.
 
42
 
43
  You can also make the choice to use tiny specialized LLM judges. With often a couple billion parameters, they can run locally on most recent consumer hardware, while being trained from scratch or fine-tuned using instruction data. You often need to follow their specific prompt formats.
44
 
45
+ <Sidenote>
46
+
47
+ Tiny specialized judge models (3-13B parameters) can run on consumer hardware while being trained specifically for evaluation tasks. They require following specific prompt formats but offer local deployment and fast inference.
48
+
49
+ </Sidenote>
50
+
51
  Some existing models:
52
  - Flow-Judge-v0.1 ([weights](https://huggingface.co/collections/flowaicom/flow-judge-v01-66e6af5fc3b3a128bde07dec)), 3.8B parameters, a Phi-3.5-mini-instruct fine-tuned on a synthetic preference dataset
53
  - Prometheus ([weights](https://huggingface.co/prometheus-eval/prometheus-13b-v1.0), [paper](https://arxiv.org/abs/2310.08491)), 13B parameters, a model trained from scratch on synthetic preference dataset. A 7B parameter [v2](https://huggingface.co/prometheus-eval/prometheus-7b-v2.0) also exists, a Mistral-7B-Instruct-v0.2 fine-tune on a bigger synthetic preference dataset, with added weight merging
 
60
  - From existing [human preference datasets](https://www.kaggle.com/competitions/lmsys-chatbot-arena)
61
  - From model generated preference data (which you can generate following the above tiny-model judges papers data sections, or get directly, for example from the Prometheus [preference](https://huggingface.co/datasets/prometheus-eval/Preference-Collection) and [feedback](https://huggingface.co/datasets/prometheus-eval/Feedback-Collection) collections).
62
 
63
+ Then you need to decide whether to start from a small model to train from scratch, or from an existing model, that you can
64
  - distill into a new smaller model
65
  - quantize.
66
  - then fine-tune (using peft or adapter weights if the model is big and your training compute low) using the above data
67
  - apparently [starting from a reward model works better than from an instruct model](https://x.com/dk21/status/1826292289930674590)
68
+
69
+ <Note title="Training your own judge model" emoji="🔧" variant="info">
70
+
71
+ **Key steps for custom judge training:**
72
+
73
+ 1. **Gather preference data**: Use human preference datasets or synthetic data from other models
74
+ 2. **Choose starting point**: Train from scratch, distill from larger model, or fine-tune existing model
75
+ 3. **Optimize for compute**: Use PEFT/adapter weights for efficient training on limited hardware
76
+ 4. **Pro tip**: Starting from a reward model reportedly works better than starting from an instruct model
77
+
78
+ </Note>
app/src/content/chapters/model-as-a-judge/tips-and-tricks.mdx CHANGED
@@ -2,20 +2,39 @@
2
  title: "Model as a Judge: Tips and tricks"
3
  ---
4
 
 
 
 
5
  ### Tips and tricks
6
 
7
  **Mitigating well known biases of LLM as judges**
8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  - **Lack of internal consistency**: a judge might give you different judgments if you prompt it several times (if the temperature is not 0)
10
  - You can mitigate this by doing self-consistency prompting of your judge, prompting it multiple times and keeping the majority output
11
  - **Self-preference**: they tend to [favor their own outputs](https://arxiv.org/abs/2404.13076) when scoring answers
12
  - You can mitigate this by using a jury
13
- - **Blindness to input perturbation**: models are bad at identifying [perturbated input](https://arxiv.org/abs/2406.13439) and tangentially [bad at providing consistent score ranges](https://twitter.com/aparnadhinak/status/1748368364395721128) (extended experiments on this [here](https://github.com/LeonEricsson/llmjudge/blob/main/README.md)). For example, if asked to rank text quality on text where noise has been added on a consistent scale, the grades predicted do not reflect this scale.
14
- - You can mitigate this by
15
  - asking the model to explain its reasoning [before providing a score](https://twitter.com/seungonekim/status/1749289437165769177)
16
  - providing a coherent grading scale in the prompt.
17
  - **Position-bias**: they tend to [favor specific answer positions](https://arxiv.org/abs/2306.05685). For example, when presented with pairwise comparisons, Claude and GPT3.5 tend to quite systematically prefer the first choice, or the second choice
18
- - You can mitigate this by
19
  - switching answer positions randomly
20
  - computing the log-probabilities of all possible choices to get a normalized answer
21
  - **Verbosity-bias** (or length-bias): they tend to like more verbose answers
 
2
  title: "Model as a Judge: Tips and tricks"
3
  ---
4
 
5
+ import Note from "../../../components/Note.astro";
6
+ import Sidenote from "../../../components/Sidenote.astro";
7
+
8
  ### Tips and tricks
9
 
10
  **Mitigating well known biases of LLM as judges**
11
 
12
+ <Note title="Known LLM judge biases and mitigations" emoji="⚠️" variant="warning">
13
+
14
+ - **Lack of internal consistency**: Different judgments at temperature > 0
15
+ - Mitigation: Self-consistency prompting (multiple runs, majority vote)
16
+ - **Self-preference**: [Favor own outputs](https://arxiv.org/abs/2404.13076)
17
+ - Mitigation: Use judge jury
18
+ - **Blindness to perturbation**: Can't identify [perturbed input](https://arxiv.org/abs/2406.13439)
19
+ - Mitigation: Chain-of-thought before scoring, coherent grading scale
20
+ - **Position bias**: [Favor specific positions](https://arxiv.org/abs/2306.05685)
21
+ - Mitigation: Random position switching, log-probability normalization
22
+ - **Verbosity bias**: Prefer verbose answers
23
+ - Mitigation: [Account for length differences](https://arxiv.org/abs/2404.04475)
24
+ - **Format bias**: Fail when format differs from training
25
+ - Mitigation: Match training prompt format
26
+ </Note>
27
+
28
  - **Lack of internal consistency**: a judge might give you different judgments if you prompt it several times (if the temperature is not 0)
29
  - You can mitigate this by doing self-consistency prompting of your judge, prompting it multiple times and keeping the majority output
30
  - **Self-preference**: they tend to [favor their own outputs](https://arxiv.org/abs/2404.13076) when scoring answers
31
  - You can mitigate this by using a jury
32
+ - **Blindness to input perturbation**: models are bad at identifying [perturbated input](https://arxiv.org/abs/2406.13439) and tangentially [bad at providing consistent score ranges](https://twitter.com/aparnadhinak/status/1748368364395721128) (extended experiments on this [here](https://github.com/LeonEricsson/llmjudge/blob/main/README.md)). For example, if asked to rank text quality on text where noise has been added on a consistent scale, the grades predicted do not reflect this scale.
33
+ - You can mitigate this by
34
  - asking the model to explain its reasoning [before providing a score](https://twitter.com/seungonekim/status/1749289437165769177)
35
  - providing a coherent grading scale in the prompt.
36
  - **Position-bias**: they tend to [favor specific answer positions](https://arxiv.org/abs/2306.05685). For example, when presented with pairwise comparisons, Claude and GPT3.5 tend to quite systematically prefer the first choice, or the second choice
37
+ - You can mitigate this by
38
  - switching answer positions randomly
39
  - computing the log-probabilities of all possible choices to get a normalized answer
40
  - **Verbosity-bias** (or length-bias): they tend to like more verbose answers
app/src/content/chapters/model-as-a-judge/what-about-reward-models.mdx CHANGED
@@ -2,6 +2,9 @@
2
  title: "What about Reward Models?"
3
  ---
4
 
 
 
 
5
  ### What about Reward Models?
6
 
7
  Reward models learn to predict a score from human annotations for given prompt/completion pairs. The end goal is for them to do predictions aligned with human preference.
@@ -13,11 +16,21 @@ $$p(\text{completion b is better than completion a}) = \text{sigmoid}(\text{scor
13
 
14
  This model is trained using only pairwise comparisons of completions, which are easier to collect than scores, but can only compare several completions for one prompt, and not completions across prompts.
15
 
16
- Other models have expanded on this approach to predict a more nuanced probability that a completion is better than the other one ([example](https://huggingface.co/RLHFlow/pair-preference-model-LLaMA3-8B)).
17
 
18
  This allows them to (theoretically) judge subtle differences between completions, at the cost of not being able to easily save and compare many different scores across prompts for the same test set. In addition, context length and memory limits can become an issue when comparing too long completions.
19
 
20
- Some reward models such as [SteerLM](https://arxiv.org/abs/2311.09528) output **absolute scores**, which can be used to evaluate completions directly without the need for pairwise comparisions. These models can be easier to use for evaluation, but are also harder to collect data for, as absolute scores tend to be less stable than pairwise scores in human preferences.
 
 
 
 
 
 
 
 
 
 
21
 
22
  More recently, models have been proposed that output both absolute and relative scores, such as [HelpSteer2-Preference](https://arxiv.org/abs/2410.01257) and [ArmoRM](https://arxiv.org/abs/2406.12845).
23
 
@@ -29,8 +42,14 @@ For models that give absolute scores, the resulting scores can be averaged to ge
29
 
30
  However, in the more common case of relative scores, the average reward can be biased by outliers (a few very good or very bad completions) as different prompts may have inherently different reward scales (some prompts are way harder or easier than others).
31
 
32
- Instead, we can use
33
- - win rates: take a reference set of completions and calculate the percentage of completions from the model that are ranked higher than the reference completions. It is slightly more granular.
 
 
 
 
 
 
34
  - win probabilities: the mean probability of the completions being better than the reference completions, which can give a more fine-grained and smoothly changing signal.
35
 
36
  #### Pros and Cons of Reward Models
@@ -45,6 +64,20 @@ On the other hand they:
45
  - **Require specific fine-tuning**: This can be a relatively costly step, and elthough they inherit many capabilities from a base model, they may still perform poorly on tasks that are out of the training distribution.
46
  - **Loose efficiency when used both in reinforcement learning and evaluation** (or when using direct alignment algorithms on datasets that are similar to the training data of the reward model), as the language model may overfit to the reward model's preferences.
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  Some notes:
49
  - A good place to find high performing models is the [RewardBench Leaderboard](https://huggingface.co/spaces/allenai/reward-bench).
50
  - You can look at how reward models have been used in the [Nemotron](https://arxiv.org/abs/2406.11704) paper.
 
2
  title: "What about Reward Models?"
3
  ---
4
 
5
+ import Note from "../../../components/Note.astro";
6
+ import Sidenote from "../../../components/Sidenote.astro";
7
+
8
  ### What about Reward Models?
9
 
10
  Reward models learn to predict a score from human annotations for given prompt/completion pairs. The end goal is for them to do predictions aligned with human preference.
 
16
 
17
  This model is trained using only pairwise comparisons of completions, which are easier to collect than scores, but can only compare several completions for one prompt, and not completions across prompts.
18
 
19
+ Other models have expanded on this approach to predict a more nuanced probability that a completion is better than the other one ([example](https://huggingface.co/RLHFlow/pair-preference-model-LLaMA3-8B)).
20
 
21
  This allows them to (theoretically) judge subtle differences between completions, at the cost of not being able to easily save and compare many different scores across prompts for the same test set. In addition, context length and memory limits can become an issue when comparing too long completions.
22
 
23
+ <Note title="Types of reward models" emoji="📊" variant="info">
24
+
25
+ **Three main approaches:**
26
+
27
+ - **Pairwise (Bradley-Terry)**: Most common. Compares two completions for same prompt. Easier to train (pairwise comparisons) but can't compare across different prompts.
28
+ - **Absolute scores** (e.g., SteerLM): Direct evaluation without comparison. Easier to use but harder to collect training data (absolute scores less stable in human preferences).
29
+ - **Hybrid models** (HelpSteer2, ArmoRM): Output both absolute and relative scores for maximum flexibility.
30
+
31
+ </Note>
32
+
33
+ Some reward models such as [SteerLM](https://arxiv.org/abs/2311.09528) output **absolute scores**, which can be used to evaluate completions directly without the need for pairwise comparisions. These models can be easier to use for evaluation, but are also harder to collect data for, as absolute scores tend to be less stable than pairwise scores in human preferences.
34
 
35
  More recently, models have been proposed that output both absolute and relative scores, such as [HelpSteer2-Preference](https://arxiv.org/abs/2410.01257) and [ArmoRM](https://arxiv.org/abs/2406.12845).
36
 
 
42
 
43
  However, in the more common case of relative scores, the average reward can be biased by outliers (a few very good or very bad completions) as different prompts may have inherently different reward scales (some prompts are way harder or easier than others).
44
 
45
+ <Sidenote>
46
+
47
+ For relative scores, don't just average raw rewards—outliers and varying prompt difficulty scales will bias results. Use win rates or win probabilities against a reference instead.
48
+
49
+ </Sidenote>
50
+
51
+ Instead, we can use
52
+ - win rates: take a reference set of completions and calculate the percentage of completions from the model that are ranked higher than the reference completions. It is slightly more granular.
53
  - win probabilities: the mean probability of the completions being better than the reference completions, which can give a more fine-grained and smoothly changing signal.
54
 
55
  #### Pros and Cons of Reward Models
 
64
  - **Require specific fine-tuning**: This can be a relatively costly step, and elthough they inherit many capabilities from a base model, they may still perform poorly on tasks that are out of the training distribution.
65
  - **Loose efficiency when used both in reinforcement learning and evaluation** (or when using direct alignment algorithms on datasets that are similar to the training data of the reward model), as the language model may overfit to the reward model's preferences.
66
 
67
+ <Note title="Reward models vs LLM judges" emoji="⚡" variant="success">
68
+
69
+ **Reward models excel at:**
70
+ - **Speed**: Single forward pass for a score (no text generation)
71
+ - **Determinism**: Reproducible scores, no temperature variation
72
+ - **No positional bias**: Models trained on balanced data avoid order effects
73
+ - **Zero prompt engineering**: Just pass completions, get scores
74
+
75
+ **But beware:**
76
+ - **Require fine-tuning**: Costly setup, may fail out-of-distribution
77
+ - **Overfitting risk**: Language models can learn to game the reward model during RL training
78
+
79
+ </Note>
80
+
81
  Some notes:
82
  - A good place to find high performing models is the [RewardBench Leaderboard](https://huggingface.co/spaces/allenai/reward-bench).
83
  - You can look at how reward models have been used in the [Nemotron](https://arxiv.org/abs/2406.11704) paper.
app/src/content/chapters/picking-your-evaluation.mdx CHANGED
@@ -1,132 +1,203 @@
 
 
 
1
 
2
- Here are the many ways one can evaluate a post trained model:
 
 
3
 
4
- 1. **Capability evals**
5
 
6
- This class of evals target fundamental skills, like reasoning and competitive math and coding.
7
- - **Knowledge.** We currently use GPQA Diamond [@gpqa] as the main eval for scientific knowledge. This benchmark consists of graduate-level, multiple-choice questions. For small models, it's far from saturated and gives better signal than MMLU and friends, while being much faster to run. Another good test of factuality is SimpleQA [[@simpleqa](https://huggingface.co/papers/2411.04368)], although small models tend to struggle significantly on this benchmark due to their limited knowledge.
8
- - **Math.** To measure mathematical ability, most models today are evaluated on the latest version of AIME (currently the 2025 version). MATH-500 [[@openaiprm](https://arxiv.org/abs/2305.20050)] remains a useful sanity test for small models, but is largely saturated by reasoning models. For a more comprehensive set of math evals, we recommend those from [MathArena](https://matharena.ai/).
9
- - **Code.** We use the latest version of [LiveCodeBench](https://livecodebench.github.io/leaderboard.html) to track coding competency. Although targeted towards competitive programming problems, we've found that improvements on LiveCodeBench do translate into better coding models, albeit limited to Python. [SWE-bench Verified](https://openai.com/index/introducing-swe-bench-verified/) is a more sophisticated measure of coding skill, but tends to be too hard for small models and thus is not one we usually consider.
10
- - **Multilinguality.** Unfortunately, there are not many options when it comes to testing the multilingual capabilities of models. We currently rely on Global MMLU [[@globalmmlu](https://arxiv.org/abs/2412.03304)] to target the main languages our models should perform well in, with MGSM [[@mgsm](/2421384ebcac800cb22cdf0bb34c69f7)] included as a test of multilingual mathematical ability.
11
 
12
- 1. **Integrated task evals**
13
 
14
- These evals test things that are close to what we'll ship: multi-turn reasoning, long-context use, and tool calls in semi-realistic settings.
15
- - **Long context.** The most commonly used test for long-context retrieval is the Needle in a Haystack (NIAH) [[@niah](https://github.com/gkamradt/LLMTest_NeedleInAHaystack)], where a random fact ("needle") is placed in somewhere within a long document ("haystack") and the model has to retrieve it. However, this benchmark is too superficial to discriminate long-context understanding, so the community has developed more comprehensive evals like RULER [[@ruler](https://arxiv.org/abs/2404.06654)] and HELMET [[@helmet](https://arxiv.org/abs/2410.02694)]. More recently, OpenAI have released the [MRCR](https://huggingface.co/datasets/openai/mrcr) and [GraphWalks](https://huggingface.co/datasets/openai/graphwalks) benchmarks which extend the difficulty of long-context evals.
16
 
17
- <Sidenote>
18
 
19
- See also this <a href="https://nrehiew.github.io/blog/long_context/">excellent [blog post](https://nrehiew.github.io/blog/long_context/)</a> on the limitations of long-context evals and how to design realistic ones.
20
- </Sidenote>
 
 
 
21
 
22
- - **Instruction following.** IFEval [[@ifeval](https://arxiv.org/abs/2311.07911)] is currently the most popular eval to measure instruction following, and uses automatic scoring against "verifiable instructions". IFBench [[@ifbench](https://arxiv.org/abs/2507.02833)] is a new extension from Ai2 which includes a more diverse set of constraints than IFEval and mitigates some benchmaxxing that has occurred in recent model releases. For multi-turn instruction following, we recommend Multi-IF [[@multiif](https://arxiv.org/abs/2410.15553)] or MultiChallenge [[@multichallenge](https://arxiv.org/abs/2501.17399)].
23
- - **Alignment.** Measuring how well models align to user intent is typically done through human annotators or by public leaderboards like [LMArena](https://lmarena.ai/). This is because qualities such as free-form generation, style, or overall helpfulness are difficult to measure quantitatively with automated metrics. However, in all cases it is very expensive to run these evaluations which is why the community has resorted to using LLMs as a proxy for human preferences. The most popular benchmarks of this flavour include AlpacaEval [[@alpacaeval](https://arxiv.org/abs/2404.04475)], ArenaHard [[@arenahard](https://arxiv.org/abs/2406.11939)] and MixEval [[@mixeval](https://arxiv.org/abs/2406.06565)], with the latter having the strongest correlation with human Elo ratings on LMArena.
24
- - **Tool calling.** [BFCL](https://gorilla.cs.berkeley.edu/leaderboard.html) provides a comprehensive test of tool calling, albeit one that is often saturated quite quickly. TAU-Bench [[@taubench](https://arxiv.org/abs/2506.07982)] provides a test of a model's ability to use tools and resolve user problems in simulated customer service settings and has also become a popular benchmark to report on.
25
 
26
- 1. **Overfitting-prevention evals**
27
 
28
- To test whether our models are overfitting to a specific skill, we include some robustness or adaptability evals in our set, like GSMPlus [[@gsmplus](https://arxiv.org/abs/2402.19255)], which perturbs problems from GSM8k [[@gsm8k](https://arxiv.org/abs/2110.14168)] to test whether models can still solve problems of similar difficulty.
29
 
30
- 1. **Internal evals**
31
 
32
- Although public benchmarks can provide some useful signal during model development, they are no substitute for implementing your own internal evals to target specific capabilities, or asking internal experts to interact with your model.
33
 
34
- <Sidenote>
35
 
36
- This is especially true if you are building an AI product. See Hamel Husain's wonderful <a href="https://hamel.dev/blog/posts/evals/">[blog post](https://decodingml.substack.com/?utm_source=navbar&utm_medium=web)</a> for specific advice on this topic.
37
- </Sidenote>
38
 
39
- For example, for SmolLM3 we needed a benchmark to evaluate whether the model was capable of *multi-turn* *reasoning* , so we implemented a variant of Multi-IF to measure this.
40
 
41
- 1. **Vibe evaluations and arenas**
42
 
43
- Similarly, we have found that "vibe testing" intermediate checkpoints (aka interacting with your model) is essential for uncovering subtle quirks in model behaviour that are not captured by eval scores. As we discuss later, vibe testing uncovered a bug in our data processing code where all system messages were deleted from the corpus!
44
- This is also something that can be done at scale to measure human preference, like on the popular [LMArena](https://lmarena.ai/). However, crowdsourced human evaluation tends to be brittle (favouring sycophancy and flowery speech over actual usefulness), so it's important to see it as a low signal feedback.
 
 
45
 
46
- <Note title="Decontaminate your training data" emoji="☝️" variant="danger">
47
 
48
- One risk with relying on public benchmarks is that the models can easily be overfit to them, especially when synthetic data is used to generate prompts and responses that are similar to the target benchmarks. For this reason, it is essential to decontaminate your training data against the evals you will use to guide model development. You can do this with N-gram matching using scripts like those in <a href="https://github.com/huggingface/open-r1/blob/main/scripts/decontaminate.py">Open-R1.</a>
49
- </Note>
50
 
51
- For SmolLM3 specifically, we wanted a hybrid reasoning model that could reliably follow instructions and reason well in popular domains like mathematics and code. We also wanted to ensure we preserved the base model's capabilities of multilinguality and long-context retrieval.
52
 
53
- This led us to the following set of evals:
54
 
55
- | Benchmark | Category | Number of prompts | Metric |
56
- | --- | --- | --- | --- |
57
- | AIME25 | Competitive mathematics | 30 | avg@64 |
58
- | LiveCodeBench (v4 for validation, v5 for final release) | Competitive programming | 100 (268) | avg@16 |
59
- | GPQA Diamond | Graduate-level reasoning | 198 | avg@8 |
60
- | IFEval | Instruction following | 541 | accuracy |
61
- | MixEval Hard | Alignment | 1000 | accuracy |
62
- | BFCL v3 | Tool use | 4441 | mixed |
63
- | Global MMLU (lite for validation) | Multilingual Q&A | 590,000 (6,400) | accuracy |
64
- | GSMPlus (mini for validation) | Robustness | 10,000 (2,400) | accuracy |
65
- | RULER | Long context | 6,500 | accuracy |
66
 
67
- Let's look at a few example questions from each to get a concrete sense of what these evaluations actually test:
68
 
69
- <iframe
70
- src="https://huggingface.co/datasets/HuggingFaceTB/post-training-benchmarks-viewer/embed/viewer/aime25/test"
71
- frameborder="0"
72
- width="100%"
73
- height="560px"
74
- ></iframe>
75
 
 
 
 
76
 
77
- Browse through the examples above to see the types of questions in each benchmark. Notice how the diversity of domains ensures we're testing different aspects of model capability throughout our ablations.
78
 
 
79
 
80
- #### **Understanding what works: evaluation**
81
 
82
- Once we launch our ablations, how do we know what works or not?
83
 
84
- The first instinct of anyone who trains models might be to look at the loss, and yes, that's indeed important. You want to see it decreasing smoothly without wild spikes or instability. For many architectural choices, the loss correlates well with downstream performance and can be sufficient [@chen2025]. However, looking at the loss only is not always reliable. Taking the example of data ablations, you would find that training on Wikipedia gives a lower loss than training on web pages (the next token is easier to predict), but that doesn't mean you'd get a more capable model. Similarly, if we change the tokenizer between runs, the losses aren't directly comparable since text gets split differently. Some changes might also specifically affect certain capabilities like reasoning and math and get washed away in the average loss. Last but not least, models can continue improving on downstream tasks even after pretraining loss has converged [@liu2022].
 
 
 
85
 
86
- We need more fine-grained evaluation to see the full picture and understand these nuanced effects and a natural approach is to use downstream evaluations that test knowledge, understanding, reasoning, and whatever other domains matter for us.
87
 
88
- For these ablations, it's good to focus on tasks that give good early signal and avoid noisy benchmarks. In [FineTasks](https://huggingface.co/spaces/HuggingFaceFW/blogpost-fine-tasks) and [FineWeb2](https://arxiv.org/pdf/2506.20920), reliable evaluation tasks are defined by four key principles:
89
 
90
- - **Monotonicity:** The benchmark scores should consistently improve as models train longer.
91
- - **Low noise:** When we train models with the same setup but different random seeds, the benchmark scores shouldn't vary wildly.
92
- - **Above-random performance:** Many capabilities only emerge later in training, so tasks that show random-level performance for extended periods aren't useful for ablations. This is the case, for example, for MMLU in multiple choice format as we will explain later.
93
- - **Ranking consistency:** If one approach outperforms another at early stages, this ordering should remain stable as training continues.
94
 
95
- The quality of a task also depends on the task formulation (how we ask the model questions) and metric choice (how we compute the answer score).
96
 
97
- Three common task formulations are multiple choice format (MCF), cloze formulation (CF) and freeform generation (FG). Multiple choice format requires models to select an option from a number of choices explicitly presented in the prompt and prefixed with A/B/C/D (as is done in MMLU, for example). In cloze formulation, we compare the likelihood of the different choices to see which one is more likely without having provided them in the prompt. In FG, we look at the accuracy of the greedy generation for a given prompt. FG requires a lot of latent knowledge in the model and is usually too difficult a task for the models to be really useful in short pre-training ablations before a full of training. We thus focus on multiple choice formulations when running small sized ablations (MCF or CF).
98
 
99
- <Note title="Heads‑up" emoji="📍" variant="info">
100
 
101
- For post-trained models, FG becomes the primary formulation since
102
- we're evaluating whether the model can actually generate useful responses.
103
- We'll cover evaluation for these models in the [post-training chapter](#beyond-base-models--post-training-in-2025).
104
  </Note>
105
 
106
- Research has also shown that models struggle with MCF early in training, only learning this skill after extensive training, making CF better for early signal [@olmes; @du2025; @datacomp]. We thus use CF for small ablations, and integrate MCF in the main run as it gives better mid-training signal once a model has passed a threshold to get sufficiently high signal-over-noise ratio for MCF. A quick note also that, to score a model's answer in sequence likelihood evaluations like CF, we compute accuracy as the percentage of questions where the the correct answer has the highest log probability normalised by character count. This normalisation prevents a bias toward shorter answers.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
 
108
- <Sidenote>
109
 
110
- The point at which MMLU MCF becomes non-random depends on the model size and training data. For a 7B transformer, the OLMES paper [@olmes] found the model starts showing non-random performance after 500B tokens. For 1.7B model, we found this happens after 6T tokens in SmolLM2 [@smollm2]. @du2025 argue this is fundamentally about the pre-training loss reaching a certain threshold.
111
- </Sidenote>
112
 
113
- Our ablations evaluation suite includes the benchmarks from [FineWeb](https://huggingface.co/spaces/HuggingFaceFW/blogpost-fineweb-v1) ablations, except for SIQA which we found to be too noisy. We add math and code benchmarks like GSM8K and HumanEval and the long context benchmark RULER for long context ablations. This aggregation of tasks test world knowledge, reasoning, and common sense across a variety of formats, as shown in the table below. To speed up evaluations at the expense of some additional noise, we only evaluate on 1,000 questions from each benchmark (except for GSM8K, HumanEval & RULER, which we used in full for the 3B SmolLM3 ablations but omit from the 1B experiments below). We also use the cloze fomulation (CF) way of evaluating for all multiple-choice benchmarks, as explained above. Note that for multilingual ablations and actual training, we add more benchmarks to test multilinguality, which we detail later. These evaluations are run using [LightEval](https://github.com/huggingface/lighteval) and the table below summarises the key characteristics of each benchmark:
114
 
115
- | Benchmark | Domain | Task Type | Questions | What it Tests |
116
- | --- | --- | --- | --- | --- |
117
- | MMLU | Knowledge | Multiple choice | 14k | Broad academic knowledge across 57 subjects |
118
- | ARC | Science & reasoning | Multiple choice | 7k | Grade-school level science reasoning |
119
- | HellaSwag | Commonsense reasoning | Multiple choice | 10k | Commonsense reasoning about everyday situations (narrative completion) |
120
- | WinoGrande | Commonsense reasoning | Binary choice | 1.7k | Pronoun resolution requiring world knowledge |
121
- | CommonSenseQA | Commonsense reasoning | Multiple choice | 1.1k | Commonsense reasoning about everyday concepts |
122
- | OpenBookQA | Science | Multiple choice | 500 | Elementary science facts with reasoning |
123
- | PIQA | Physical commonsense | Binary choice | 1.8k | Physical commonsense about everyday objects |
124
- | GSM8K | Math | Free-form generation | 1.3k | Grade-school math word problems |
125
- | HumanEval | Code | Free-form generation | 164 | Python function synthesis from docstrings |
126
 
127
- Let's look at a few example questions from each to get a concrete sense of what these evaluations actually test:
128
 
129
- <iframe src="https://huggingface.co/datasets/HuggingFaceTB/llm-benchmarks-viewer/embed/viewer/default/mmlu" class="card card--p0" frameborder="0" width="100%" height="450px"></iframe>
130
 
 
131
 
132
- Browse through the examples above to see the types of questions in each benchmark. Notice how MMLU and ARC test factual knowledge with multiple choices, GSM8K requires computing numerical answers to math problems, and HumanEval requires generating complete Python code. This diversity ensures we're testing different aspects of model capability throughout our ablations.
 
1
+ ---
2
+ title: "Picking good automatic evaluations for pretraining"
3
+ ---
4
 
5
+ import Note from "../../../components/Note.astro";
6
+ import Sidenote from "../../../components/Sidenote.astro";
7
+ import HtmlEmbed from "../../../components/HtmlEmbed.astro";
8
 
9
+ ## What Makes a Task "Fine"?
10
 
11
+ Covering all 7000+ languages spoken over the world would be monumental endeavor, so we settled on using **9 languages** that offered diversity in script, language family and resource availability: **Chinese, French, Arabic, Russian, Thai, Hindi, Turkish, Swahili, and Telugu**.
 
 
 
 
12
 
13
+ For these languages, we collected all available tasks that we could find, implementing a total of **185 tasks across languages** in [LightEval](https://github.com/huggingface/lighteval), HuggingFace's model evaluation library.
14
 
15
+ Then, we began task selection with two primary goals: ensuring **evaluation diversity**, and making sure each task provided a **reliable signal** during pre-training.
 
16
 
17
+ For evaluation diversity, we aimed to assess a broad range of model capabilities, including:
18
 
19
+ - **Reading comprehension (RC)**: Understanding provided context and answering questions based on it.
20
+ - **General knowledge (GK)**: Answering questions about facts from various fields without added context.
21
+ - **Natural Language Understanding (NLU)**: Comprehending the semantics of provided input.
22
+ - **Common-sense reasoning (RES)**: Demonstrating the ability to perform simple reasoning requiring embodied knowledge.
23
+ - **Generative tasks**: Ability to generate text in the target language without the "help" of multiple choice options.
24
 
25
+ We consider that tasks provide a reliable signal if they provide a dependable score. This means the score should be above the random baseline, increase as training progresses, show low variability across different seeds, and provide consistent model ranking at each training step<d-footnote>For similar sized models trained with the same hyperparameters on the same amount of data.</d-footnote>.
 
 
26
 
27
+ ### Finding how much signal our tasks give during pre-training
28
 
29
+ To thoroughly examine the signal our tasks provide, we trained many 1.5B parameter models for each language, using 30B tokens from subsets of the supported languages of the five largest openly available multilingual web datasets. These models were trained with the same hyperparameters and tokenizer. We then evaluated them at regular checkpoint intervals on the collected tasks (with no instruction and no system prompt in a 0-shot setting).
30
 
31
+ This process required multiple evaluation runs for each task due to iterations on its implementation, resulting in a total of **73 000 GPU hours consumed** 🔥!
32
 
33
+ With **49 models trained** we could finally define what a **reliable signal** means to us!
34
 
35
+ #### Monotonicity
36
 
37
+ One of our core requirements for a task is that it can be learned from training data and this **learning can be gradually observed as the training progresses**. Without this improvement through time, it's uncertain whether there will ever be an improvement in the future.
 
38
 
39
+ To measure this, we used the **Spearman rank correlation** to quantify the correlation between steps and score. Spearman rank correlation can capture monotonicity even when scores don't evolve linearly with the number of steps. We required each task to have at least an average correlation of 0.5 over all model training runs.
40
 
 
41
 
42
+ <div style="display: flex; grid-column: middle">
43
+ <div class="task-signal-plot" data-language="French" data-task="mlmm_hellaswag_fra_cf" data-show-controls="false" data-task-metrics="monotonicity" data-metric="acc_norm_token" data-group-seeds="true" data-title="✅ Good monotonicity: mlmm_hellaswag_fra_cf [fr]"></div>
44
+ <div class="task-signal-plot" data-language="Arabic" data-task="mlmm_truthfulqa_ara_cf:mc1" data-show-controls="false" data-task-metrics="monotonicity" data-metric="acc_norm_token" data-group-seeds="true" data-title="❌ Bad monotonicity: mlmm_truthfulqa_ara_cf:mc1 [ar]"></div>
45
+ </div>
46
 
47
+ #### Low noise
48
 
49
+ When comparing model performance on tasks, we need to consider whether differences are due to **evaluation noise or genuine performance variations**.
 
50
 
51
+ Noise can arise from the stochastic processes involved in model training, such as random token sampling, data shuffling, or model initialization.[Madaan et al., 2024](https://arxiv.org/abs/2406.10229) To measure how sensitive each task is to this noise, we trained four additional models on our own monolingual corpora (unfiltered CommonCrawl data in each language) using different seeds.
52
 
53
+ For each task, we computed:
54
 
55
+ 1. First, a standard deviation of model scores for every step (approximately every 1B tokens), which we call the **per-step-std**.
56
+ 2. Then, to obtain a global variability measurement, we averaged all the per-step-std values to get the **avg-std** over the full training. We assume this value is an upper-bound across model architectures and training datasets (as it was approximated by models trained on a "dirtier" dataset, therefore with higher variability).
57
+ 3. Finally, we computed the **signal-to-noise ratio** (SNR) as the main metric for task variability. We calculate SNR as the mean score at 30B tokens of all runs divided by the avg-std. This metric measures how significant the overall score is relative to the score variations (noise).
 
 
 
 
 
 
 
 
58
 
59
+ We aimed for each task to have an SNR > 20. The only exception to this rule are generative tasks, which typically have relatively low SNR, but are still worth including as they provide insights into how the model behaves when prompted to generate unconstrained (without answer options). In a multilingual setting, this is particularly relevant as some models trained on multiple languages can exhibit high task scores but then suddenly reply in the wrong language for generative tasks!
60
 
61
+ <div style="display: flex; grid-column: middle">
62
+ <div class="task-signal-plot" data-language="Telugu" data-task="xstory_cloze_tel_cf" data-show-controls="false" data-task-metrics="snr" data-metric="acc_norm_token" data-group-seeds="false" data-title="✅ Good SNR: xstory_cloze_tel_cf [te]"></div>
63
+ <div class="task-signal-plot" data-language="Telugu" data-task="tydiqa_tel" data-show-controls="false" data-task-metrics="snr" data-metric="acc_norm_token" data-group-seeds="false" data-title="❌ Bad SNR: tydiqa_tel [te]"></div>
64
+ </div>
 
 
65
 
66
+ <Note>
67
+ Assuming model performance is normally distributed across different seeds, we want the benchmark-run performance to be at least 3 final-stds above the benchmark random baseline. This would mean that 99.85% of seed scores are above the random baseline (formally, benchmark-run performance - benchmark random baseline > 3 * final-std).
68
+ </Note>
69
 
70
+ #### Non-Random Performance
71
 
72
+ Many model capabilities are acquired later in training, thus **many tasks** (especially harder ones, such as math-related ones) **show baseline-level performance for an extended period**. While these tasks are useful, they're not ideal for early pre-training evaluation, and **we did not want to keep them** for this setting.
73
 
74
+ We first computed the baseline random performance of the task (as the sum of 1/n_choices for all samples for multiple choice questions, and as zero for generative evaluations). Then we calculated the task's distance from the baseline as the maximum score across all models minus the baseline.
75
 
 
76
 
77
+ <div style="display: flex; grid-column: middle">
78
+ <div class="task-signal-plot" data-language="Chinese" data-task="agieval_zho_cf:_average" data-show-controls="false" data-task-metrics="randomness" data-metric="acc_norm_pmi" data-group-seeds="true" data-title="✅ Non-random: agieval_zho_cf/acc_pmi [zh]"></div>
79
+ <div class="task-signal-plot" data-language="Chinese" data-task="agieval_zho_cf:_average" data-show-controls="false" data-task-metrics="randomness" data-metric="acc" data-group-seeds="true" data-title="❌ Random perf: agieval_zho_cf/acc [zh]"></div>
80
+ </div>
81
 
82
+ #### Model Ordering Consistency
83
 
84
+ Let's not forget that the main goal of these evaluations is to compare models and datasets!
85
 
86
+ In the future, we want to use these evaluations to select the best datasets for full model pretraining. This means **our tasks should rank datasets trained using very few tokens (we typically run data ablations on 30B tokens), in the same order as they would when trained for longer, after significantly more steps.**
 
 
 
87
 
88
+ In other words, we would like tasks to have **predictive capability regarding future performance during pre-training**: if pre-training dataset A outperforms pre-training dataset B at 30 billion tokens, we would like this trend to continue at 300 billion tokens.
89
 
90
+ Proving this is inherently impossible, but there is a necessary preliminary condition that we can test for: for the results to be consistent at large scales, they must also first show consistency at smaller scales!
91
 
92
+ To measure this consistency in task ordering, we computed the average **Kendall's Tau** of models ranking between every two consecutive steps. We only considered steps starting after 15B tokens of pre-training, as we found orderings before the range incredibly noisy. A high value of this metric indicates that the ordering remains consistent as training progresses.
93
 
94
+ <Note>
95
+ We had no strict minimum value requirement for this property, instead using it to establish comparisons between tasks.
 
96
  </Note>
97
 
98
+ <div style="display: flex; grid-column: middle">
99
+ <div class="task-signal-plot" data-language="Arabic" data-task="xcsqa_ara_cf" data-show-controls="false" data-task-metrics="ordering" data-metric="acc_norm_token" data-group-seeds="true" data-title="✅ Good ordering: xcsqa_ara_cf [ar]"></div>
100
+ <div class="task-signal-plot" data-language="Thai" data-task="thai_exams_tha_cf:_average" data-show-controls="false" data-task-metrics="ordering" data-metric="acc_norm_token" data-group-seeds="true" data-title="❌ Bad ordering: thai_exams_tha_cf [th]"></div>
101
+ </div>
102
+
103
+
104
+ ## Important properties of evaluation impacting stability
105
+
106
+ Now that we covered what we were looking for in our tasks, let's examine two important aspects that can affect the above properties: task formulations and metric choice.
107
+
108
+ <Note>Both of these aspects are thoroughly described and studied in the brilliant OLMES paper [Gu et al., 2024](https://arxiv.org/abs/2406.08446), which greatly inspired our work.</Note>
109
+
110
+ ### Task Formulations
111
+
112
+ The way tasks are presented to the model is crucial, particularly for multiple-choice (MC) tasks. In these scenarios, we must carefully determine how the choices are displayed and what the model is expected to predict.
113
+
114
+ There are two common approaches: **Cloze Formulation** (CF) and **Multi-Choice Formulation** (MCF). In CF, choices are not provided in context, allowing the model to predict each option directly. In contrast, MCF presents the choices in the prompt, using A/B/C/D prefixes, with the targets being those letter prefixes.
115
+
116
+ It's important to know that:
117
+
118
+ - The choice of formulation significantly impacts task scores (see [the release blog of the Open LLM Leaderboard 2](https://huggingface.co/spaces/open-llm-leaderboard/blog)).
119
+ - Both formulations **behave very differently during training**. As noted by both OLMES [Gu et al., 2024](https://arxiv.org/abs/2406.08446) and DataComp-LM [Li et al., 2024](https://arxiv.org/abs/2406.11794), when employing MCF, task scores initially show random performance over extended training periods before experiencing a sudden increase. Conversely, with CF, task scores improve right from the beginning but tend to plateau relatively early.
120
+
121
+ Therefore, we decided to utilize CF for task selection and MCF for later evaluation of major open source models, as they have generally undergone enough training for these evaluations to have a signal.
122
+
123
+ ### Metrics
124
+
125
+ As the targets in CF of multiple choice tasks are choices themselves, each target can have a different number of tokens, characters, and unconditional probability (probability of generating the choice without a context prefix).
126
+
127
+ <Note>Measuring accuracy without normalization would have the models prefer answers with fewer tokens, for example.</Note>
128
+
129
+ To account for this, we consider the following accuracy variations:
130
+
131
+ - **Accuracy** :
132
+ `acc` = <d-math>\underset{i}{\arg\max}(ln(P (a_i|q)))</d-math>
133
+ - **Accuracy normalized over character length** :
134
+ `acc_char` = <d-math> \underset{i}{\arg\max}\frac{ln(P (a_i|q))}{num\_characters(a_i)}</d-math>
135
+ - **Accuracy normalized over token length** :
136
+ `acc_token` = <d-math> \underset{i}{\arg\max}\frac{ln(P (a_i|q))}{num\_tokens(a_i)}</d-math>
137
+ - **PMI Accuracy** :
138
+ `acc_pmi` = <d-math> \underset{i}{\arg\max}ln\frac{P (a_i|q)}{P (a_i|u)}</d-math>, where <d-math>u =</d-math>''Answer:''
139
+
140
+ Where <d-math>a_i</d-math> is the answer choice <d-math>i</d-math>, <d-math>q</d-math> is a question prompt and <d-math>P (a_i|q)</d-math> is the probability of having <d-math>a_i</d-math> follow <d-math>q</d-math>. For more details see [Gu et al., 2024](https://arxiv.org/abs/2406.08446) and [Biderman et al., 2024](https://arxiv.org/abs/2405.14782).
141
+
142
+ <Note>`acc_pmi` metric measures how much more likely a model is to predict A_i if provided with question context compared to if there was no context at all. This can be useful if the correct choice contains generally unlikely tokens, making the model less likely to choose such an answer.</Note>
143
+
144
+ For our generative tasks on the other hand, we used the following metrics:
145
+
146
+ - `prefix_match`: Exact match where only the prefix of the answer must match
147
+ - `f1`: F1 score computed over predicted/gold words extracted using a word tokenizer
148
+
149
+ For both generative metrics, minor preprocessing is applied to remove articles and punctuation, and lowercase the text.
150
+
151
+ ## The Fine selection
152
+
153
+ With our goals and evaluation setup properly defined, we proceeded with **task selection**!
154
+
155
+ We reviewed tasks one by one, choosing based on the quantified properties. For each language, we aimed to have at least one task for each of the four categories outlined above. Additionally we wanted to have at least 1 generative task for each language.
156
+
157
+ In cases where multiple versions of a task existed (e.g., MMLU with different translation methods or native versions), we **prioritized native versions** as long as their metrics were reasonable, followed by human translations of English tasks. If no such version was available, we made our selection entirely based on metrics.
158
+
159
+ Thus, **after removing about half of the tasks**, we arrived at **96 final ones**, forming "FineTasks."
160
+
161
+ ### Explore tasks
162
+
163
+ Use the dropdowns below to navigate the list of tasks and how different metrics affect them.
164
+
165
+ <div id="fine-tasks-results"></div>
166
+
167
+ All tasks from the selection **comply with the criteria** outlined in previous sections, with the only exception being indicqa_tel, which we chose to include to ensure we had at least one generative task for Telugu. Overall we managed to cover all task categories for each language (the only exception being Thai Reasoning, where all tasks were unfortunately too noisy with low monotonicity to consider them).
168
+
169
+ One of the **biggest surprises** was that some tasks, even when translated using the same method, were **reliable in one language but not in others**. This was evident with xWinograd, which worked quite well for Russian but did not meet our conditions for French. An even more extreme example was XNLI, which performed well for 6 out of 7 languages, failing to satisfy the reliability properties for Chinese. We had to test four different implementations before finding a reliable version, which, interestingly, was the only one that was created by native speakers and not machine translated.
170
+
171
+ Feel free to use the dropdowns below to explore the evolution of scores over training for all tested tasks and metrics.
172
+
173
+ <div class="task-signal-plot" data-language="French" data-task="frenchbench_hellaswag_fra_cf" data-show-controls="true" data-metric="acc_norm_token" data-group-seeds="true" data-title=""></div>
174
+
175
+
176
+ ### Metrics recommendation
177
+
178
+ Selecting the best evaluation metrics proved to be a **challenging task**. Not only is there no single metric that consistently outperforms the rest, but we often encountered situations where one metric had better monotonicity while another had a higher signal-to-noise ratio. In such cases, we typically made our decision based on the selected metric for tasks' implementation in a different language. We are aware that such hand-picking is often not possible and thus offer the following recommendations:
179
+
180
+ #### Multichoice Tasks
181
+
182
+ - We found **base accuracy** to perform well for tasks with answer options varying subtly (e.g. Yes/No/Also), particularly NLI tasks. In such cases, where the answer options are often each a single token, the base accuracy is advisable to use.
183
+ - While OLMES [Gu et al., 2024](https://arxiv.org/abs/2406.08446) recommends using PMI for tasks with unusual words, we found **PMI** to be highly effective for "difficult" reasoning and knowledge tasks like AGIEVAL or MMLU. In these cases, PMI provided the best results and was often the only metric delivering performance above random. That said, PMI was, on average, the weakest metric across all other tasks, while also being two times more expensive to compute. We therefore only recommend its use for complex reasoning and knowledge tasks.
184
+ - The metrics we found to be **most reliable overall** were length normalization metrics (token or character-based). However, the best choice was dependent on language, rather than being consistent for a given task. Due to that, we recommend using the maximum of acc_char and acc_token for the most reliable results.<d-footnote>Note that acc_token is heavily tokenizer dependent. On our ablations all models were trained using the same tokenizer.</d-footnote>
185
+
186
+ #### Generative Tasks
187
+
188
+ For **generative metrics**, the choice is clearer: we suggest using the F1 score unless exact matching is required, as in math-related tasks. F1 is generally less noisy and more resilient to small changes in the generations.
189
 
 
190
 
191
+ ## Open/Closed Source models tackle FineTasks
 
192
 
193
+ Since we spent a lot of time and compute on task selection, we were interested in how well major **open-source** models would do on FineTasks. Given that our evaluation suite primarily targets pretrained models, we focused on these, with a few exceptions for models that don't offer a base (pretrained) version. These exceptions were included mainly out of curiosity, and their results should be interpreted with **caution**. Such models may significantly outperform other models due to the inclusion of supervised fine-tuning (SFT) data.
194
 
195
+ To assess the multilingual performance disparity between open-source and closed-source models, we expanded our selection by adding a closed source model: **gpt-4o-mini**.
 
 
 
 
 
 
 
 
 
 
196
 
197
+ As outlined in the task formulations, we are using MCF for this evaluation and employing a 5-shot approach, as recommended by OLMES [Gu et al., 2024](https://arxiv.org/abs/2406.08446) (and made possible by the large context size of the models).
198
 
199
+ ### Computing a global "multilingual" score
200
 
201
+ In the previous sections, we treated each task independently. However, to determine an overall "multilingual" score of a model, we need to **aggregate** the results from these tasks. We begin by **rescaling** the individual task scores in line with the OpenLLM leaderboard [Fourrier et al., 2024](https://huggingface.co/spaces/open-llm-leaderboard/open_llm_leaderboard). Then, we **average the scores** across task types (GK, RES, etc) for each language separately. To compute the score for each language, we take the average of the task type scores.<d-footnote>We first average by task type to properly measure all model capabilities without letting a single category dominate.</d-footnote>
202
 
203
+ For the final global "multilingual" score we followed a different approach. Instead of averaging the language scores directly, we **ranked the model's performance across languages** in comparison to other models and then averaged those rank scores. This method ensures that the result reflects the overall model's performance across all languages, preventing an exceptionally high score in one language from skewing the final outcome.
app/src/content/chapters/troubleshooting/troubleshooting-inference.mdx CHANGED
@@ -2,6 +2,9 @@
2
  title: "Troubleshooting inference"
3
  ---
4
 
 
 
 
5
  ## Troubleshooting inference
6
 
7
  ### My model is very slow!
@@ -30,10 +33,25 @@ You can estimate the minimal theoretical memory required to load a given model (
30
 
31
  Since you can store 8 bits in a Byte, the memory required is the total number of parameters times the number of Bytes required to store one parameter. The precision factor is therefore 4 for `float32`, 2 for `float16` or `bfoat16`, 1 for `8bit`, and 0.5 for `4bit` models, etc.
32
 
33
- And that's it!
34
 
35
  I would actually recommend using `<memory (in GB)> = <number of parameters (in G)> * (<precision factor> * 110%)`, to be on the safer side, as inference will require a bit more memory than just loading the model (you'll also need to load the batches).
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  ### My model does not fit on a GPU
38
  ➡️ Quantization
39
 
@@ -48,6 +66,16 @@ The 2 main types of model parallelism are
48
  - Pipeline parallelism, where the model is split at the whole layer level, and the layers are dispatched on different GPUs. Since layer 1's output is layer 2's input, this leads to a slower execution, as GPUs will be idle while waiting, which is called a "bubble" (and data must be transferred from one GPU to the next). The bubble can be reduced by splitting the inputs into smaller batches. It's being natively added to PyTorch with the `PiPPy` [lib](https://github.com/pytorch/PiPPy), and this is what `accelerate` uses under the hood for parallelism.
49
  - Tensor parallelism, where the model is split at the matrix computation level. This means that the matrices will be split on rows or columns, and the total result aggregated. This is incredibly efficient as long as all GPUs are on the same node (to avoid inter node network bottlenecks), but can be hard to code. You'll find cool implementations of this in the `vllm` lib. It provides **insane speedups**.
50
 
 
 
 
 
 
 
 
 
 
 
51
  The best document on the different kinds of parallelism (including data parallelism, for speedups) is [here](https://huggingface.co/docs/transformers/v4.15.0/en/parallelism).
52
 
53
  ➡️ CPU offloading
 
2
  title: "Troubleshooting inference"
3
  ---
4
 
5
+ import Note from "../../../components/Note.astro";
6
+ import Sidenote from "../../../components/Sidenote.astro";
7
+
8
  ## Troubleshooting inference
9
 
10
  ### My model is very slow!
 
33
 
34
  Since you can store 8 bits in a Byte, the memory required is the total number of parameters times the number of Bytes required to store one parameter. The precision factor is therefore 4 for `float32`, 2 for `float16` or `bfoat16`, 1 for `8bit`, and 0.5 for `4bit` models, etc.
35
 
36
+ And that's it!
37
 
38
  I would actually recommend using `<memory (in GB)> = <number of parameters (in G)> * (<precision factor> * 110%)`, to be on the safer side, as inference will require a bit more memory than just loading the model (you'll also need to load the batches).
39
 
40
+ <Note title="Estimating GPU memory requirements" emoji="💾" variant="info">
41
+
42
+ **Quick formula:**
43
+ `Memory (GB) = Params (billions) × Precision factor × 1.1`
44
+
45
+ **Precision factors:**
46
+ - float32: 4
47
+ - float16/bfloat16: 2
48
+ - 8-bit: 1
49
+ - 4-bit: 0.5
50
+
51
+ The 1.1 multiplier accounts for batch loading overhead. Example: A 7B model in float16 needs ~15.4GB (7 × 2 × 1.1).
52
+
53
+ </Note>
54
+
55
  ### My model does not fit on a GPU
56
  ➡️ Quantization
57
 
 
66
  - Pipeline parallelism, where the model is split at the whole layer level, and the layers are dispatched on different GPUs. Since layer 1's output is layer 2's input, this leads to a slower execution, as GPUs will be idle while waiting, which is called a "bubble" (and data must be transferred from one GPU to the next). The bubble can be reduced by splitting the inputs into smaller batches. It's being natively added to PyTorch with the `PiPPy` [lib](https://github.com/pytorch/PiPPy), and this is what `accelerate` uses under the hood for parallelism.
67
  - Tensor parallelism, where the model is split at the matrix computation level. This means that the matrices will be split on rows or columns, and the total result aggregated. This is incredibly efficient as long as all GPUs are on the same node (to avoid inter node network bottlenecks), but can be hard to code. You'll find cool implementations of this in the `vllm` lib. It provides **insane speedups**.
68
 
69
+ <Note title="Model parallelism strategies" emoji="🔀" variant="info">
70
+
71
+ **Two main approaches to split models across GPUs:**
72
+
73
+ - **Pipeline parallelism**: Split by layers, dispatch to different GPUs. Simpler but creates "bubbles" (idle GPU time waiting for previous layer). Reduce bubbles by using smaller micro-batches. Used by PyTorch PiPPy and Accelerate.
74
+
75
+ - **Tensor parallelism**: Split matrix operations across GPUs within each layer. Much faster (insane speedups!) but requires all GPUs on same node to avoid network bottlenecks. Check out `vllm` for implementations.
76
+
77
+ </Note>
78
+
79
  The best document on the different kinds of parallelism (including data parallelism, for speedups) is [here](https://huggingface.co/docs/transformers/v4.15.0/en/parallelism).
80
 
81
  ➡️ CPU offloading
app/src/content/chapters/troubleshooting/troubleshooting-reproducibility.mdx CHANGED
@@ -2,6 +2,9 @@
2
  title: "Troubleshooting reproducibility"
3
  ---
4
 
 
 
 
5
  ## Troubleshooting reproducibility
6
 
7
  Let's say you have read a recent tech report about a cool new model, and you want to reproduce their results on your machine... but you're not managing to?
@@ -18,20 +21,32 @@ If you want to easily understand what kind of discrepancies happen when using di
18
 
19
  ### Other subtle ways in which the implementation can be different
20
  We've observed that the following were easy things to mess up, even when using the same code base:
21
- - **Different random seeds.**
22
- - Normally, inference is less affected by random seeds than training. However, they can still affect some CUDA operations (see the PyTorch page on [reproducibility](https://pytorch.org/docs/stable/notes/randomness.html)) and change predictions if you're using a non greedy generation strategy. They can also affect the prompt if you're using few-shots, and some pre or post-processing functions.
23
  -> A tiny change can result in a couple of points of difference.
24
- - **Actually different metrics**.
25
  Metrics can be different in practice even if they share the same name. Some examples:
26
  - If the original implementation is a *log likelihood* `exact match` (computing the log probabilities of different possible answers), and you're using a *generative* `exact match` (only comparing the main greedy generation with the reference), you won't get the same scores.
27
- - We also saw, in evaluation code bases, a number of tasks which were defined as `exact match`, but were actually `prefix exact match` (comparing only the beginning of the generation with the reference), or `suffix exact match` (the opposite), or `quasi exact match` (exact match with a normalization).
28
  -> You therefore can't rely only on the metric name to determine what is happening, and need to look at the code.
29
  - **Different normalization**.
30
- - To go back to our above `exact match` comparison example, in `lm_eval` v1, a number of tasks were simply named generative `exact match`: you would assume from this that the prediction is *compared as such* to a reference.
31
- Looking at the code, the prediction would instead go through a normalization step (removing punctuation, homogenizing numbers, etc) before being compared to the reference. This will obviously change results quite a lot.
32
  (The `lm_eval` v2 now includes the normalization name in most metric names.)
33
  -> This is one of the easiest things to mess up, especially for tasks which require a lot of normalization/answer post processing, like math evaluations (where you want to extract the answer from a generated explanation).
34
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  ### Different prompt
36
  3 main things can come into play for prompt variation.
37
  ### Prompt itself
@@ -57,6 +72,16 @@ These prompts are **semantically equivalent**, as they contain the exact same co
57
 
58
  Some tasks are also prefixed with a task prompt (eg: `The following questions are about <topic>`) - its presence or absence will also affect the scores.
59
 
 
 
 
 
 
 
 
 
 
 
60
  This [great paper](https://arxiv.org/abs/2407.07890)⭐ also highlights a side effect of this: a number of models are now trained to overfit benchmark prompts and answer formats, to the cost of adaptation to other prompts at evaluation time.
61
 
62
  This is something we observed on the Open LLM Leaderboard 2 for the Llama3.1 models. They were predicting the correct answers to our MATH-Hard evaluations, but were getting low scores, being unable to fit to the template provided in few-shot because they overfit the GSM8K prompt and answer format (another math eval).
@@ -88,7 +113,18 @@ Some sources of differences that we have observed are:
88
  Pytorch does not ensure reproducibility of non deterministic operations across hardware
89
  - using **different libraries**.
90
  For example, if you use `transformers` vs `vllm` as your backend for inference, matrix computations are not managed exactly in the same way)
91
- - using **different batch sizes**.
92
  It's been documented in several evaluation libraries and model backends that using different batch sizes will change inference results - if you want fully reproducible evaluations, you should fix the batch size, though it might not always be possible for memory issues
93
  - using **different loading precision** for your model weights.
94
  Using a lower precision can reduce memory and inference costs, but it will also change the numerical results, since you are using different versions of the weights.
 
 
 
 
 
 
 
 
 
 
 
 
2
  title: "Troubleshooting reproducibility"
3
  ---
4
 
5
+ import Note from "../../../components/Note.astro";
6
+ import Sidenote from "../../../components/Sidenote.astro";
7
+
8
  ## Troubleshooting reproducibility
9
 
10
  Let's say you have read a recent tech report about a cool new model, and you want to reproduce their results on your machine... but you're not managing to?
 
21
 
22
  ### Other subtle ways in which the implementation can be different
23
  We've observed that the following were easy things to mess up, even when using the same code base:
24
+ - **Different random seeds.**
25
+ - Normally, inference is less affected by random seeds than training. However, they can still affect some CUDA operations (see the PyTorch page on [reproducibility](https://pytorch.org/docs/stable/notes/randomness.html)) and change predictions if you're using a non greedy generation strategy. They can also affect the prompt if you're using few-shots, and some pre or post-processing functions.
26
  -> A tiny change can result in a couple of points of difference.
27
+ - **Actually different metrics**.
28
  Metrics can be different in practice even if they share the same name. Some examples:
29
  - If the original implementation is a *log likelihood* `exact match` (computing the log probabilities of different possible answers), and you're using a *generative* `exact match` (only comparing the main greedy generation with the reference), you won't get the same scores.
30
+ - We also saw, in evaluation code bases, a number of tasks which were defined as `exact match`, but were actually `prefix exact match` (comparing only the beginning of the generation with the reference), or `suffix exact match` (the opposite), or `quasi exact match` (exact match with a normalization).
31
  -> You therefore can't rely only on the metric name to determine what is happening, and need to look at the code.
32
  - **Different normalization**.
33
+ - To go back to our above `exact match` comparison example, in `lm_eval` v1, a number of tasks were simply named generative `exact match`: you would assume from this that the prediction is *compared as such* to a reference.
34
+ Looking at the code, the prediction would instead go through a normalization step (removing punctuation, homogenizing numbers, etc) before being compared to the reference. This will obviously change results quite a lot.
35
  (The `lm_eval` v2 now includes the normalization name in most metric names.)
36
  -> This is one of the easiest things to mess up, especially for tasks which require a lot of normalization/answer post processing, like math evaluations (where you want to extract the answer from a generated explanation).
37
 
38
+ <Note title="Subtle reproducibility pitfalls" emoji="⚠️" variant="warning">
39
+
40
+ **Common sources of score differences (even with same codebase):**
41
+
42
+ - **Random seeds**: Can affect CUDA ops, sampling strategies, and few-shot prompt selection (multi-point differences possible)
43
+ - **Metric ambiguity**: "Exact match" can mean log-likelihood matching, generative matching, prefix/suffix/quasi-matching—always check the code, not just the name
44
+ - **Hidden normalization**: Predictions may be normalized (punctuation removal, number formatting) before comparison—easy to miss especially in math evals
45
+
46
+ **Key lesson**: Never trust metric names alone. Read the actual implementation.
47
+
48
+ </Note>
49
+
50
  ### Different prompt
51
  3 main things can come into play for prompt variation.
52
  ### Prompt itself
 
72
 
73
  Some tasks are also prefixed with a task prompt (eg: `The following questions are about <topic>`) - its presence or absence will also affect the scores.
74
 
75
+ <Note title="Prompt format sensitivity" emoji="📝" variant="danger">
76
+
77
+ **Semantically identical prompts can cause 7+ point score differences!**
78
+
79
+ Even tiny formatting variations (like `A.` vs `(A)` vs just listing choices) significantly impact scores. Models increasingly overfit to specific benchmark prompt formats during training, losing adaptation ability.
80
+
81
+ **Real example**: Llama 3.1 models predicted correct MATH-Hard answers but scored poorly because they overfit to GSM8K's prompt format and couldn't adapt to different few-shot templates.
82
+
83
+ </Note>
84
+
85
  This [great paper](https://arxiv.org/abs/2407.07890)⭐ also highlights a side effect of this: a number of models are now trained to overfit benchmark prompts and answer formats, to the cost of adaptation to other prompts at evaluation time.
86
 
87
  This is something we observed on the Open LLM Leaderboard 2 for the Llama3.1 models. They were predicting the correct answers to our MATH-Hard evaluations, but were getting low scores, being unable to fit to the template provided in few-shot because they overfit the GSM8K prompt and answer format (another math eval).
 
113
  Pytorch does not ensure reproducibility of non deterministic operations across hardware
114
  - using **different libraries**.
115
  For example, if you use `transformers` vs `vllm` as your backend for inference, matrix computations are not managed exactly in the same way)
116
+ - using **different batch sizes**.
117
  It's been documented in several evaluation libraries and model backends that using different batch sizes will change inference results - if you want fully reproducible evaluations, you should fix the batch size, though it might not always be possible for memory issues
118
  - using **different loading precision** for your model weights.
119
  Using a lower precision can reduce memory and inference costs, but it will also change the numerical results, since you are using different versions of the weights.
120
+
121
+ <Note title="Model loading affects reproducibility" emoji="🔧" variant="warning">
122
+
123
+ **Four factors that change results even with identical code:**
124
+
125
+ - **Hardware**: PyTorch doesn't guarantee reproducibility across different GPUs/hardware
126
+ - **Inference library**: transformers vs vllm handle matrix ops differently
127
+ - **Batch size**: Different batch sizes = different results (fix batch size for reproducibility, though memory may limit this)
128
+ - **Loading precision**: Lower precision (float16 vs float32) changes numerical results
129
+
130
+ </Note>
app/src/content/embeds/d3-decision-tree.html ADDED
@@ -0,0 +1,363 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="d3-decision-tree"></div>
2
+ <style>
3
+ .d3-decision-tree {
4
+ position: relative;
5
+ width: 100%;
6
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
7
+ }
8
+
9
+ .d3-decision-tree svg {
10
+ display: block;
11
+ overflow: hidden;
12
+ }
13
+
14
+ .d3-decision-tree .node-rect {
15
+ stroke: var(--border-color);
16
+ stroke-width: 2.5px;
17
+ rx: 10px;
18
+ cursor: pointer;
19
+ transition: all 0.3s ease;
20
+ filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1));
21
+ }
22
+
23
+ .d3-decision-tree .node-rect.start {
24
+ stroke: var(--primary-color);
25
+ stroke-width: 3.5px;
26
+ filter: drop-shadow(0 3px 8px rgba(0, 0, 0, 0.15));
27
+ }
28
+
29
+ .d3-decision-tree .node-rect.choice {
30
+ fill: var(--surface-bg);
31
+ }
32
+
33
+ .d3-decision-tree .node-rect.outcome {
34
+ fill: var(--surface-bg);
35
+ stroke-width: 2.5px;
36
+ }
37
+
38
+ .d3-decision-tree .node-rect:hover {
39
+ transform: scale(1.03);
40
+ stroke: var(--primary-color);
41
+ filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.2));
42
+ }
43
+
44
+ .d3-decision-tree .node-text {
45
+ fill: var(--text-color);
46
+ font-size: 13.5px;
47
+ font-weight: 500;
48
+ text-anchor: middle;
49
+ pointer-events: none;
50
+ user-select: none;
51
+ }
52
+
53
+ .d3-decision-tree .node-text.start {
54
+ font-weight: 700;
55
+ font-size: 15px;
56
+ }
57
+
58
+ .d3-decision-tree .node-text.outcome {
59
+ font-weight: 600;
60
+ font-size: 13.5px;
61
+ }
62
+
63
+ .d3-decision-tree .link {
64
+ fill: none;
65
+ stroke: var(--muted-color);
66
+ stroke-width: 2.5px;
67
+ stroke-opacity: 0.5;
68
+ }
69
+
70
+ .d3-decision-tree .link-label {
71
+ fill: var(--text-color);
72
+ font-size: 11px;
73
+ text-anchor: middle;
74
+ pointer-events: none;
75
+ user-select: none;
76
+ font-style: italic;
77
+ opacity: 0.7;
78
+ font-weight: 500;
79
+ }
80
+
81
+ </style>
82
+ <script>
83
+ (() => {
84
+ const ensureD3 = (cb) => {
85
+ if (window.d3 && typeof window.d3.select === 'function') return cb();
86
+ let s = document.getElementById('d3-cdn-script');
87
+ if (!s) {
88
+ s = document.createElement('script');
89
+ s.id = 'd3-cdn-script';
90
+ s.src = 'https://cdn.jsdelivr.net/npm/d3@7/dist/d3.min.js';
91
+ document.head.appendChild(s);
92
+ }
93
+ const onReady = () => {
94
+ if (window.d3 && typeof window.d3.select === 'function') cb();
95
+ };
96
+ s.addEventListener('load', onReady, { once: true });
97
+ if (window.d3) onReady();
98
+ };
99
+
100
+ const bootstrap = () => {
101
+ const scriptEl = document.currentScript;
102
+ let container = scriptEl ? scriptEl.previousElementSibling : null;
103
+ if (!(container && container.classList && container.classList.contains('d3-decision-tree'))) {
104
+ const candidates = Array.from(document.querySelectorAll('.d3-decision-tree'))
105
+ .filter((el) => !(el.dataset && el.dataset.mounted === 'true'));
106
+ container = candidates[candidates.length - 1] || null;
107
+ }
108
+ if (!container) return;
109
+ if (container.dataset) {
110
+ if (container.dataset.mounted === 'true') return;
111
+ container.dataset.mounted = 'true';
112
+ }
113
+
114
+ // Decision tree data structure
115
+ const treeData = {
116
+ name: "Are you a...",
117
+ type: "start",
118
+ children: [
119
+ {
120
+ name: "Model Builder",
121
+ type: "choice",
122
+ edgeLabel: "model builder",
123
+ children: [
124
+ {
125
+ name: "Training goes well",
126
+ type: "choice",
127
+ edgeLabel: "make sure training\ngoes well",
128
+ children: [
129
+ { name: "Ablations", type: "outcome" }
130
+ ]
131
+ },
132
+ {
133
+ name: "Compare models",
134
+ type: "choice",
135
+ edgeLabel: "compare models",
136
+ children: [
137
+ { name: "Leaderboards", type: "outcome" },
138
+ { name: "Design Your Evals", type: "outcome" }
139
+ ]
140
+ }
141
+ ]
142
+ },
143
+ {
144
+ name: "Model User",
145
+ type: "choice",
146
+ edgeLabel: "model user",
147
+ children: [
148
+ {
149
+ name: "Test on use case",
150
+ type: "choice",
151
+ edgeLabel: "test a model on\nyour use case",
152
+ children: [
153
+ { name: "Design Your Evals", type: "outcome" },
154
+ { name: "Vibe Checks", type: "outcome" }
155
+ ]
156
+ }
157
+ ]
158
+ },
159
+ {
160
+ name: "ML Enthusiast",
161
+ type: "choice",
162
+ edgeLabel: "ML enthusiast",
163
+ children: [
164
+ {
165
+ name: "Fun use cases",
166
+ type: "choice",
167
+ edgeLabel: "test a model on\nfun use cases",
168
+ children: [
169
+ { name: "Vibe Checks", type: "outcome" },
170
+ { name: "Fun Use Cases", type: "outcome" }
171
+ ]
172
+ }
173
+ ]
174
+ }
175
+ ]
176
+ };
177
+
178
+ // Get colors
179
+ const getColors = () => {
180
+ if (window.ColorPalettes && typeof window.ColorPalettes.getColors === 'function') {
181
+ return window.ColorPalettes.getColors('categorical', 3);
182
+ }
183
+ // Fallback colors
184
+ return ['#4e79a7', '#e15759', '#76b7b2'];
185
+ };
186
+
187
+ const colors = getColors();
188
+
189
+ // SVG setup
190
+ const svg = d3.select(container).append('svg').attr('width', '100%').style('display', 'block');
191
+ const gRoot = svg.append('g');
192
+
193
+ let width = 800, height = 600;
194
+ const margin = { top: 80, right: 120, bottom: 80, left: 120 };
195
+
196
+ function updateSize() {
197
+ width = container.clientWidth || 800;
198
+ height = Math.max(700, Math.round(width * 1.0));
199
+ svg.attr('width', width).attr('height', height);
200
+ gRoot.attr('transform', `translate(${margin.left},${margin.top})`);
201
+ return {
202
+ innerWidth: width - margin.left - margin.right,
203
+ innerHeight: height - margin.top - margin.bottom
204
+ };
205
+ }
206
+
207
+ function wrapText(text, maxWidth) {
208
+ const words = text.split(/\s+/);
209
+ const lines = [];
210
+ let currentLine = words[0];
211
+
212
+ for (let i = 1; i < words.length; i++) {
213
+ const testLine = currentLine + ' ' + words[i];
214
+ if (testLine.length * 7 < maxWidth) {
215
+ currentLine = testLine;
216
+ } else {
217
+ lines.push(currentLine);
218
+ currentLine = words[i];
219
+ }
220
+ }
221
+ lines.push(currentLine);
222
+ return lines;
223
+ }
224
+
225
+ function render() {
226
+ const { innerWidth, innerHeight } = updateSize();
227
+
228
+ // Create tree layout
229
+ const treeLayout = d3.tree().size([innerWidth, innerHeight]);
230
+ const root = d3.hierarchy(treeData);
231
+ treeLayout(root);
232
+
233
+ // Draw links
234
+ const links = gRoot.selectAll('.link')
235
+ .data(root.links())
236
+ .join('path')
237
+ .attr('class', 'link')
238
+ .attr('d', d3.linkVertical()
239
+ .x(d => d.x)
240
+ .y(d => d.y));
241
+
242
+ // Draw link labels - only for edges from level 0 to level 1
243
+ const linkLabels = gRoot.selectAll('.link-label')
244
+ .data(root.links().filter(d => d.source.depth === 0))
245
+ .join('text')
246
+ .attr('class', 'link-label')
247
+ .attr('x', d => d.source.x + (d.target.x - d.source.x) * 0.3)
248
+ .attr('y', d => d.source.y + (d.target.y - d.source.y) * 0.4)
249
+ .attr('dy', -5)
250
+ .each(function(d) {
251
+ const label = d.target.data.edgeLabel || '';
252
+ if (label) {
253
+ const lines = label.split('\n');
254
+ d3.select(this).selectAll('tspan').remove();
255
+ lines.forEach((line, i) => {
256
+ d3.select(this)
257
+ .append('tspan')
258
+ .attr('x', d.source.x + (d.target.x - d.source.x) * 0.3)
259
+ .attr('dy', i === 0 ? 0 : 13)
260
+ .text(line);
261
+ });
262
+ }
263
+ });
264
+
265
+ // Draw link labels for deeper levels (more compact)
266
+ const deeperLinkLabels = gRoot.selectAll('.link-label-deep')
267
+ .data(root.links().filter(d => d.source.depth > 0))
268
+ .join('text')
269
+ .attr('class', 'link-label link-label-deep')
270
+ .attr('x', d => d.source.x + (d.target.x - d.source.x) * 0.4)
271
+ .attr('y', d => d.source.y + (d.target.y - d.source.y) * 0.35)
272
+ .attr('dy', -5)
273
+ .style('font-size', '10px')
274
+ .each(function(d) {
275
+ const label = d.target.data.edgeLabel || '';
276
+ if (label) {
277
+ const lines = label.split('\n');
278
+ d3.select(this).selectAll('tspan').remove();
279
+ lines.forEach((line, i) => {
280
+ d3.select(this)
281
+ .append('tspan')
282
+ .attr('x', d.source.x + (d.target.x - d.source.x) * 0.4)
283
+ .attr('dy', i === 0 ? 0 : 11)
284
+ .text(line);
285
+ });
286
+ }
287
+ });
288
+
289
+ // Node dimensions - responsive based on depth
290
+ const getNodeDimensions = (depth) => {
291
+ if (depth === 0) return { width: 160, height: 60 };
292
+ if (depth === 1) return { width: 145, height: 55 };
293
+ if (depth === 2) return { width: 145, height: 55 };
294
+ return { width: 140, height: 50 };
295
+ };
296
+
297
+ // Draw nodes
298
+ const nodes = gRoot.selectAll('.node')
299
+ .data(root.descendants())
300
+ .join('g')
301
+ .attr('class', 'node')
302
+ .attr('transform', d => `translate(${d.x},${d.y})`);
303
+
304
+ // Node rectangles
305
+ nodes.selectAll('rect').remove();
306
+ nodes.append('rect')
307
+ .attr('class', d => `node-rect ${d.data.type}`)
308
+ .attr('x', d => -getNodeDimensions(d.depth).width / 2)
309
+ .attr('y', d => -getNodeDimensions(d.depth).height / 2)
310
+ .attr('width', d => getNodeDimensions(d.depth).width)
311
+ .attr('height', d => getNodeDimensions(d.depth).height)
312
+ .attr('fill', d => {
313
+ if (d.data.type === 'start') return colors[0];
314
+ if (d.data.type === 'outcome') return colors[2];
315
+ return colors[1];
316
+ })
317
+ .attr('fill-opacity', d => {
318
+ if (d.data.type === 'start') return 0.2;
319
+ if (d.data.type === 'outcome') return 0.25;
320
+ return 0.12;
321
+ });
322
+
323
+ // Node text
324
+ nodes.selectAll('text').remove();
325
+ nodes.append('text')
326
+ .attr('class', d => `node-text ${d.data.type}`)
327
+ .attr('dy', '0.35em')
328
+ .each(function(d) {
329
+ const nodeDims = getNodeDimensions(d.depth);
330
+ const lines = wrapText(d.data.name, nodeDims.width - 14);
331
+ const textEl = d3.select(this);
332
+ const lineHeight = 13.5;
333
+ const startY = -(lines.length - 1) * lineHeight / 2;
334
+
335
+ lines.forEach((line, i) => {
336
+ textEl.append('tspan')
337
+ .attr('x', 0)
338
+ .attr('dy', i === 0 ? startY : lineHeight)
339
+ .text(line);
340
+ });
341
+ });
342
+ }
343
+
344
+ // Initial render
345
+ render();
346
+
347
+ // Resize handling
348
+ const rerender = () => render();
349
+ if (window.ResizeObserver) {
350
+ const ro = new ResizeObserver(() => rerender());
351
+ ro.observe(container);
352
+ } else {
353
+ window.addEventListener('resize', rerender);
354
+ }
355
+ };
356
+
357
+ if (document.readyState === 'loading') {
358
+ document.addEventListener('DOMContentLoaded', () => ensureD3(bootstrap), { once: true });
359
+ } else {
360
+ ensureD3(bootstrap);
361
+ }
362
+ })();
363
+ </script>