--- id: llm-evaluation title: Evaluating LLMs code: EL subtitle: Specify tasks, score them, judge with a rubric, calibrate, rank with intervals and test long context. hue: 80 sources: phases/10-llms-from-scratch/10-evaluation, phases/11-llm-engineering/10-evaluation, phases/05-nlp-foundations-to-advanced/27-llm-evaluation-frameworks, phases/05-nlp-foundations-to-advanced/28-long-context-evaluation, phases/19-capstone-projects/27-eval-harness-fixture-tasks, phases/19-capstone-projects/41-eval-pipeline, phases/19-capstone-projects/49-lm-eval-harness, phases/19-capstone-projects/70-task-spec-format, phases/19-capstone-projects/71-classical-metrics, phases/19-capstone-projects/72-code-exec-metric, phases/19-capstone-projects/73-perplexity-calibration, phases/19-capstone-projects/74-leaderboard-aggregation, phases/19-capstone-projects/75-end-to-end-eval-runner source_hash: f41ffc5fe2795abd --- ## End-to-end eval runner type: architecture from: phases/19-capstone-projects/75-end-to-end-eval-runner/docs/en.md, phases/19-capstone-projects/75-end-to-end-eval-runner/code/main.py, phases/19-capstone-projects/72-code-exec-metric/code/main.py ```arch node | tasks | 1,1 | tasks.jsonl | validate_file node | adapter | 2,1 | ModelAdapter | generate(prompt, task) node | post | 3,1 | post_process | one rule per task node | metric | 4,1 | score | metric_name dispatch node | calib | 1,2 | CalibrationReport | ece, brier node | board | 2,2 | aggregate | JSON + markdown node | runs | 3,2 | EvalRun | one per model, task node | exec | 4,2 | run_candidate | subprocess, 3 s edge | tasks | adapter | render edge | adapter | post | text edge | post | metric | edge | post | exec | code_exec edge | metric | runs | score edge | exec | runs | score edge | adapter | calib | confidence edge | runs | board | edge | calib | board | report ``` ## Score one task type: flow from: phases/19-capstone-projects/75-end-to-end-eval-runner/docs/en.md, phases/19-capstone-projects/75-end-to-end-eval-runner/code/main.py, phases/19-capstone-projects/70-task-spec-format/docs/en.md 1. **Render**: few-shot examples, then the prompt, with a blank line between. 2. **Adapter**: `generate(prompt, task)` returns text and confidence. The runner times it. 3. **post_process**: applies the single rule of the task. 4. **Dispatch**: `score` for text metrics, `run_candidate` for `code_exec`. 5. **EvalRun**: one record with the score and the metric name. 6. **Calibration buffer**: appends the (confidence, correct) pair. 7. **Correct**: score of 1 for exact_match, accuracy, code_exec. At least 0.5 for graded metrics. ## Pick and run a metric type: task-table span: 2 from: phases/19-capstone-projects/70-task-spec-format/code/main.py, phases/19-capstone-projects/71-classical-metrics/code/main.py, phases/11-llm-engineering/10-evaluation/code/eval_framework.py, phases/10-llms-from-scratch/10-evaluation/docs/en.md, phases/05-nlp-foundations-to-advanced/28-long-context-evaluation/docs/en.md | Task | Code | |---|---| | Score arithmetic | `"exact_match"` with `"strip_whitespace"` | | Score multiple choice | `"exact_match"` with `"extract_letter"` | | Score generated code | `"code_exec"` with `"extract_code_block"` | | Score a summary | `"rouge_l"` or `"bleu_4"` | | Interval on a pass rate | `wilson_confidence_interval(successes, total, z=1.96)` | | Rank by pairwise wins | `ELOTracker(k=32, initial_rating=1500)` | | Plant a needle | `build_haystack(filler_text, needle, depth_ratio, total_tokens)` | | Run a public benchmark | `lm_eval --model hf --model_args pretrained= --tasks mmlu` | ## Harness API type: annotated-code lang: python from: phases/19-capstone-projects/70-task-spec-format/code/main.py, phases/19-capstone-projects/70-task-spec-format/docs/en.md, phases/19-capstone-projects/71-classical-metrics/code/main.py, phases/19-capstone-projects/72-code-exec-metric/code/main.py, phases/19-capstone-projects/73-perplexity-calibration/code/main.py, phases/19-capstone-projects/74-leaderboard-aggregation/code/main.py ```python tasks, errors = validate_file("tasks.jsonl") # do not run if errors s = score("f1", prediction, targets) # best F1 over the targets s = score_code_exec(prediction, assertions) # passed / total, 3 s limit p = pass_at_k(n=10, c=3, k=5) # unbiased estimator report = CalibrationReport.from_predictions(confidences, correct) report.ece, report.brier, report.populated_bins # bins=10 by default ppl = perplexity(neg_log_probs, token_counts) # exp(total nll / tokens) rows = aggregate(runs, b=500, alpha=0.05) # mean, bootstrap CI, win rate print(render_markdown(rows)) # table for a PR comment ``` ## Post-process rules type: command-table from: phases/19-capstone-projects/70-task-spec-format/docs/en.md, phases/19-capstone-projects/70-task-spec-format/code/main.py | Command | What it does | |---|---| | `none` | Returns the string unchanged | | `strip_whitespace` | Strips leading and trailing whitespace | | `lower` | Lowercases the string | | `extract_letter` | First character in `[A-E]`. For MCQ | | `extract_code_block` | Body of the first fenced block. For code | | `extract_first_line` | First non-empty line. For summary classes | ## Key formulas type: concepts from: phases/10-llms-from-scratch/10-evaluation/docs/en.md, phases/19-capstone-projects/71-classical-metrics/docs/en.md, phases/19-capstone-projects/72-code-exec-metric/docs/en.md, phases/19-capstone-projects/73-perplexity-calibration/docs/en.md - **Perplexity**: $\mathrm{PPL} = \exp\left(-\frac{1}{N} \sum_i \log P(\text{token}_i \mid \text{context})\right)$ - **Token F1**: $\frac{2 P R}{P + R}$. P and R are token overlap over prediction and target. - **BLEU-4**: brevity penalty times the geometric mean of $p_1$ to $p_4$. - **Brevity penalty**: 1 if $c \ge r$, else $\exp(1 - r / c)$. - **ROUGE-L**: LCS over reference length and over candidate length, then F1. - **pass@k**: $1 - \binom{n - c}{k} / \binom{n}{k}$ for $c$ passes in $n$ samples. - **ECE**: confidence minus accuracy per bin, weighted by bin size, summed. - **Brier**: $\mathrm{mean}((p_i - y_i)^2)$. Penalizes spread that ECE misses. ## Sample size and confidence type: command-table from: phases/11-llm-engineering/10-evaluation/docs/en.md | Test cases at 90% | 95% CI width | |---|---| | 50 | 19 points. Cannot detect a 5% regression | | 100 | 12 points. Barely | | 200 | 9 points. Yes | | 500 | 5 points. Confidently | | 1000 | 3 points. Precisely | ## Defaults in the code type: defaults from: phases/19-capstone-projects/72-code-exec-metric/code/main.py, phases/19-capstone-projects/70-task-spec-format/code/main.py, phases/19-capstone-projects/73-perplexity-calibration/code/main.py, phases/19-capstone-projects/73-perplexity-calibration/docs/en.md, phases/19-capstone-projects/74-leaderboard-aggregation/code/main.py, phases/19-capstone-projects/75-end-to-end-eval-runner/code/main.py, phases/10-llms-from-scratch/10-evaluation/docs/en.md | Setting | Default | Note | |---|---|---| | `DEFAULT_TIMEOUT_S` | 3.0 | Per task. `MAX_TIMEOUT_S` is 30.0 | | `OUTPUT_CAP_BYTES` | 256 * 1024 | Then the result is "output overflow" | | `FEW_SHOT_MAX` | 8 | Few-shot examples per task | | ECE `bins` | 10 | 15 is the comparison convention | | Bootstrap `b` | 500 | Low-level helpers use 1000 | | `alpha` | 0.05 | 95% percentile interval | | `max_workers` | 8 | Thread pool in `run_eval` | | ELO `k` | 32 | Start rating 1500 | ## Troubleshooting type: troubleshooting from: phases/19-capstone-projects/73-perplexity-calibration/docs/en.md, phases/19-capstone-projects/41-eval-pipeline/docs/en.md, phases/05-nlp-foundations-to-advanced/27-llm-evaluation-frameworks/docs/en.md, phases/05-nlp-foundations-to-advanced/28-long-context-evaluation/docs/en.md, phases/19-capstone-projects/74-leaderboard-aggregation/docs/en.md | Symptom | Cause | Fix | |---|---|---| | Perplexity below 1 | Adapter returns log p, not -log p | Negate. The function rejects it | | Perplexity too good | Padding counted in the denominator | Count only non-pad tokens | | Judge scores go missing | Bad JSON gives NaN, mean drops it | Catch it as an explicit failure | | Judge rates its own model high | Self-evaluation adds 10-20% | Judge with a different model family | | Pairwise judge picks the first | Position bias | Randomize order and run both | | Mean 0.85, users complain | Mean hides 5% catastrophic failures | Inspect the bottom quantile | | Passes NIAH, fails real docs | NIAH tests retrieval only | Add RULER or a multi-hop test | | One task dominates the mean | Score in [0, 100] | Return fractions in [0, 1] | ## Abbreviations type: glossary from: phases/05-nlp-foundations-to-advanced/27-llm-evaluation-frameworks/docs/en.md, phases/19-capstone-projects/73-perplexity-calibration/docs/en.md, phases/10-llms-from-scratch/10-evaluation/docs/en.md, phases/05-nlp-foundations-to-advanced/28-long-context-evaluation/docs/en.md - **EM**: Exact Match. 1 or 0 per task after normalization. - **ECE**: Expected Calibration Error. Gap between confidence and accuracy. - **MMLU**: Massive Multitask Language Understanding. 15,908 questions, 57 subjects. - **HumanEval**: 164 Python function-completion problems. - **SWE-bench**: 2,294 GitHub issues from 12 Python repos. - **NIAH**: Needle in a Haystack. Plant a fact in filler, ask for it. - **MRCR**: Multi-Round Coreference Resolution. 8, 24 or 100 needles. - **RAGAS**: Retrieval-Augmented Generation ASsessment. Four RAG metrics. ## Questions type: qa from: phases/11-llm-engineering/10-evaluation/docs/en.md, phases/19-capstone-projects/27-eval-harness-fixture-tasks/docs/en.md, phases/19-capstone-projects/74-leaderboard-aggregation/docs/en.md, phases/05-nlp-foundations-to-advanced/27-llm-evaluation-frameworks/docs/en.md, phases/05-nlp-foundations-to-advanced/28-long-context-evaluation/docs/en.md - **How many test cases?** At least 200 for a deploy decision. 500 or more for close systems. - **Why report pass@1 too?** pass@k hides a model that is right once in twenty tries. - **When is a difference real?** When the bootstrap interval of the paired difference excludes zero. - **When can I trust a judge?** Spearman rho against human labels of 0.7 or more. - **How long is the real context?** Reasoning-effective is often 25-50% of the advertised window. ## Tips type: tips from: phases/11-llm-engineering/10-evaluation/docs/en.md, phases/05-nlp-foundations-to-advanced/27-llm-evaluation-frameworks/docs/en.md, phases/19-capstone-projects/49-lm-eval-harness/docs/en.md, phases/05-nlp-foundations-to-advanced/28-long-context-evaluation/docs/en.md - Anchor each rubric score to observable behavior. Judge variance drops 30-40%. - Freeze the judge model and its version. - Pin task files by hash in the leaderboard. - Diff predictions, not only scores. Use `--include-per-example`. - Keep eval cases apart from prompt and training examples. - Test needle depths 0, 0.25, 0.5, 0.75 and 1.0.