Skip to content

Commit dc30165

Browse files
authored
docs(examples): MMLU-Pro worked example (Inspect AI task + locked claim + verified sample log)
Adds a complete end-to-end example under `examples/mmlu_pro/`: - `mmlu_pro_prml.py` — Inspect AI task definition pinned to the `TIGER-Lab/MMLU-Pro` HF dataset (specific revision). - `claim.prml.yaml` — locked PRML manifest for a 10-sample run (`sha256:218b553d49c6…`). - `sample_eval_log.json` — compact Inspect-shaped log that satisfies the claim. - `verify_claim.py` — verifier that re-derives the hash and checks the threshold; exits 0/1. - `tests/test_examples.py` — CI assertion that the checked-in log passes verification. This is the worked example the README was implicitly pointing at. Anyone reading the README can now run `python examples/mmlu_pro/verify_claim.py` and watch the chain close. Co-authored-by: adit24dhaya <adit24dhaya@users.noreply.github.com>
1 parent 11907c9 commit dc30165

6 files changed

Lines changed: 207 additions & 0 deletions

File tree

examples/mmlu_pro/README.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# MMLU-Pro PRML example
2+
3+
This example shows how to pre-register and verify a small Inspect AI
4+
MMLU-Pro run with `falsify-inspect`.
5+
6+
## Files
7+
8+
- `mmlu_pro_prml.py` defines an Inspect AI task backed by the
9+
`TIGER-Lab/MMLU-Pro` Hugging Face dataset.
10+
- `claim.prml.yaml` is the locked PRML manifest for a 10-sample run.
11+
- `sample_eval_log.json` is a compact Inspect-shaped log that matches the
12+
manifest.
13+
- `verify_claim.py` verifies the sample log against the pre-registered hash.
14+
15+
## Run the eval
16+
17+
From a source checkout, install the package with the optional Inspect
18+
dependency first:
19+
20+
```bash
21+
python -m pip install -e ".[inspect]"
22+
```
23+
24+
Then run a small sample:
25+
26+
```bash
27+
inspect eval examples/mmlu_pro/mmlu_pro_prml.py \
28+
--model openai/gpt-4o-mini \
29+
--limit 10 \
30+
--sample-shuffle 42
31+
```
32+
33+
Before publishing a result, lock the claim fields that will be verified later:
34+
35+
```bash
36+
falsify-inspect lock \
37+
--metric accuracy \
38+
--threshold 0.75 \
39+
--threshold-direction ">=" \
40+
--dataset TIGER-Lab/MMLU-Pro \
41+
--dataset-hash hf:527feea0afed1de15a8c115abf7be4c912123315 \
42+
--model-version openai/gpt-4o-mini \
43+
--sample-size 10 \
44+
--seed 42 \
45+
--task mmlu_pro_prml \
46+
--output examples/mmlu_pro/claim.prml.yaml
47+
```
48+
49+
The checked-in manifest hashes to:
50+
51+
```text
52+
sha256:218b553d49c6f1f4b1f100a1c143995cc4ece4cbda2e8366d0817060783f1026
53+
```
54+
55+
## Verify the sample claim
56+
57+
```bash
58+
python examples/mmlu_pro/verify_claim.py
59+
```
60+
61+
The script exits with `0` when the hash matches and the observed accuracy
62+
satisfies the pre-registered threshold.

examples/mmlu_pro/claim.prml.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
dataset: TIGER-Lab/MMLU-Pro
2+
dataset_hash: hf:527feea0afed1de15a8c115abf7be4c912123315
3+
inspect_task: mmlu_pro_prml
4+
metric: accuracy
5+
model_version: openai/gpt-4o-mini
6+
pre_registered: '2026-05-16T00:00:00Z'
7+
prml_version: '0.1'
8+
sample_size: 10
9+
seed: 42
10+
threshold: 0.75
11+
threshold_direction: '>='

examples/mmlu_pro/mmlu_pro_prml.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
"""Inspect AI task for a small MMLU-Pro PRML example.
2+
3+
Run a development sample with:
4+
5+
inspect eval examples/mmlu_pro/mmlu_pro_prml.py --limit 10 --sample-shuffle 42
6+
"""
7+
8+
from __future__ import annotations
9+
10+
from typing import Any
11+
12+
from inspect_ai import Task, task
13+
from inspect_ai.dataset import Sample, hf_dataset
14+
from inspect_ai.scorer import choice
15+
from inspect_ai.solver import multiple_choice
16+
17+
DATASET_PATH = "TIGER-Lab/MMLU-Pro"
18+
DATASET_REVISION = "527feea0afed1de15a8c115abf7be4c912123315"
19+
20+
21+
def record_to_sample(record: dict[str, Any]) -> Sample:
22+
"""Convert one MMLU-Pro Hugging Face record into an Inspect sample."""
23+
return Sample(
24+
input=record["question"],
25+
choices=record["options"],
26+
target=record["answer"],
27+
id=record["question_id"],
28+
metadata={
29+
"subject": record["category"].lower(),
30+
},
31+
)
32+
33+
34+
@task
35+
def mmlu_pro_prml(shuffle: bool = False) -> Task:
36+
"""Return a lightweight MMLU-Pro task suitable for PRML examples."""
37+
dataset = hf_dataset(
38+
path=DATASET_PATH,
39+
split="test",
40+
sample_fields=record_to_sample,
41+
revision=DATASET_REVISION,
42+
shuffle=shuffle,
43+
)
44+
45+
return Task(
46+
dataset=dataset,
47+
solver=[multiple_choice()],
48+
scorer=choice(),
49+
)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"eval": {
3+
"task": "mmlu_pro_prml",
4+
"model": "openai/gpt-4o-mini",
5+
"dataset": {
6+
"name": "TIGER-Lab/MMLU-Pro",
7+
"sha": "hf:527feea0afed1de15a8c115abf7be4c912123315"
8+
},
9+
"config": {
10+
"sample_size": 10,
11+
"seed": 42
12+
}
13+
},
14+
"results": {
15+
"scores": [
16+
{
17+
"name": "accuracy",
18+
"metrics": {
19+
"accuracy": {
20+
"value": 0.8
21+
}
22+
}
23+
}
24+
]
25+
}
26+
}

examples/mmlu_pro/verify_claim.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""Verify the checked-in MMLU-Pro example claim."""
2+
3+
from __future__ import annotations
4+
5+
import json
6+
from pathlib import Path
7+
from typing import Any
8+
9+
import yaml
10+
11+
from falsify_inspect import verify_eval_log
12+
13+
HERE = Path(__file__).resolve().parent
14+
EXPECTED_HASH = "sha256:218b553d49c6f1f4b1f100a1c143995cc4ece4cbda2e8366d0817060783f1026"
15+
16+
17+
def verify() -> dict[str, Any]:
18+
manifest = yaml.safe_load((HERE / "claim.prml.yaml").read_text(encoding="utf-8"))
19+
return verify_eval_log(
20+
HERE / "sample_eval_log.json",
21+
expected_hash=EXPECTED_HASH,
22+
threshold=manifest["threshold"],
23+
threshold_direction=manifest["threshold_direction"],
24+
pre_registered=manifest["pre_registered"],
25+
sample_size=manifest["sample_size"],
26+
seed=manifest["seed"],
27+
)
28+
29+
30+
def main() -> int:
31+
result = verify()
32+
print(json.dumps(result, indent=2, default=str))
33+
return 0 if result["ok"] else 1
34+
35+
36+
if __name__ == "__main__":
37+
raise SystemExit(main())

tests/test_examples.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"""Tests for checked-in examples."""
2+
3+
from __future__ import annotations
4+
5+
import importlib.util
6+
from pathlib import Path
7+
8+
9+
def test_mmlu_pro_verification_example_passes():
10+
root = Path(__file__).resolve().parents[1]
11+
script = root / "examples" / "mmlu_pro" / "verify_claim.py"
12+
spec = importlib.util.spec_from_file_location("mmlu_pro_verify_claim", script)
13+
assert spec is not None
14+
assert spec.loader is not None
15+
16+
module = importlib.util.module_from_spec(spec)
17+
spec.loader.exec_module(module)
18+
19+
result = module.verify()
20+
assert result["hash_match"] is True
21+
assert result["threshold_satisfied"] is True
22+
assert result["ok"] is True

0 commit comments

Comments
 (0)