benchkit-cli 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- benchkit/__init__.py +1 -0
- benchkit/_pi_proxy.py +219 -0
- benchkit/answer_key_guard.ts +49 -0
- benchkit/artifacts.py +87 -0
- benchkit/benchmarks/__init__.py +105 -0
- benchkit/benchmarks/aider_polyglot.py +405 -0
- benchkit/benchmarks/arc.py +52 -0
- benchkit/benchmarks/banking77.py +149 -0
- benchkit/benchmarks/base.py +19 -0
- benchkit/benchmarks/boolq.py +49 -0
- benchkit/benchmarks/chartqa.py +133 -0
- benchkit/benchmarks/code_verifier.py +77 -0
- benchkit/benchmarks/downloads.py +166 -0
- benchkit/benchmarks/evalplus.py +288 -0
- benchkit/benchmarks/git_surgery.py +485 -0
- benchkit/benchmarks/gpqa.py +56 -0
- benchkit/benchmarks/gsm8k.py +97 -0
- benchkit/benchmarks/hellaswag.py +49 -0
- benchkit/benchmarks/humaneval.py +103 -0
- benchkit/benchmarks/ifeval.py +56 -0
- benchkit/benchmarks/ifeval_instructions.py +477 -0
- benchkit/benchmarks/mbpp.py +60 -0
- benchkit/benchmarks/mc_arena.py +479 -0
- benchkit/benchmarks/mcq.py +94 -0
- benchkit/benchmarks/medfailbench.py +537 -0
- benchkit/benchmarks/mmlu.py +54 -0
- benchkit/benchmarks/mmlu_pro.py +62 -0
- benchkit/benchmarks/mmvp.py +115 -0
- benchkit/benchmarks/ocrbench.py +96 -0
- benchkit/benchmarks/openbookqa.py +52 -0
- benchkit/benchmarks/patcheval.py +929 -0
- benchkit/benchmarks/piqa.py +52 -0
- benchkit/benchmarks/ruler.py +172 -0
- benchkit/benchmarks/ruler_generator.py +535 -0
- benchkit/benchmarks/sanity.py +174 -0
- benchkit/benchmarks/treejs_arena.py +268 -0
- benchkit/benchmarks/truthfulqa.py +52 -0
- benchkit/benchmarks/utils.py +25 -0
- benchkit/benchmarks/vision.py +230 -0
- benchkit/benchmarks/vstar.py +108 -0
- benchkit/benchmarks/winogrande.py +52 -0
- benchkit/benchmarks/xstest.py +116 -0
- benchkit/browser.py +429 -0
- benchkit/catalog.py +121 -0
- benchkit/cli.py +1000 -0
- benchkit/client.py +1413 -0
- benchkit/controls.py +87 -0
- benchkit/datasets/MMLU_LICENSE.txt +21 -0
- benchkit/datasets/README.md +142 -0
- benchkit/datasets/arc_challenge.jsonl +1172 -0
- benchkit/datasets/banking77.jsonl +3080 -0
- benchkit/datasets/banking77_intents.json +79 -0
- benchkit/datasets/boolq.jsonl +3270 -0
- benchkit/datasets/code_verifier.jsonl +500 -0
- benchkit/datasets/gpqa_diamond.jsonl +198 -0
- benchkit/datasets/gsm8k.jsonl +1319 -0
- benchkit/datasets/hellaswag.jsonl +1000 -0
- benchkit/datasets/humaneval.jsonl +164 -0
- benchkit/datasets/ifeval.jsonl +541 -0
- benchkit/datasets/mbpp.jsonl +500 -0
- benchkit/datasets/mc_blocks_1_20_1.jsonl +1003 -0
- benchkit/datasets/medfailbench_hard30.jsonl +30 -0
- benchkit/datasets/medfailbench_hard30.md +13 -0
- benchkit/datasets/openbookqa.jsonl +500 -0
- benchkit/datasets/piqa.jsonl +1838 -0
- benchkit/datasets/sanity_code.jsonl +6 -0
- benchkit/datasets/truthfulqa.jsonl +817 -0
- benchkit/datasets/winogrande.jsonl +1267 -0
- benchkit/datasets/xstest.csv +451 -0
- benchkit/decision.py +194 -0
- benchkit/demo.py +451 -0
- benchkit/dockerfiles.py +247 -0
- benchkit/engine.py +1270 -0
- benchkit/evaluation.py +195 -0
- benchkit/events.py +141 -0
- benchkit/executor.py +96 -0
- benchkit/git_surgery/backport-release-stack/setup.sh +328 -0
- benchkit/git_surgery/backport-release-stack/verify.sh +119 -0
- benchkit/git_surgery/bisect-the-regression/setup.sh +49 -0
- benchkit/git_surgery/bisect-the-regression/verify.sh +34 -0
- benchkit/git_surgery/rebase-conflict-chain/setup.sh +65 -0
- benchkit/git_surgery/rebase-conflict-chain/verify.sh +43 -0
- benchkit/git_surgery/recover-complex-stash/setup.sh +152 -0
- benchkit/git_surgery/recover-complex-stash/verify.sh +95 -0
- benchkit/git_surgery/recover-lost-work/setup.sh +40 -0
- benchkit/git_surgery/recover-lost-work/verify.sh +36 -0
- benchkit/git_surgery/repair-force-pushed-remote/setup.sh +171 -0
- benchkit/git_surgery/repair-force-pushed-remote/verify.sh +83 -0
- benchkit/git_surgery/revert-merge-with-followups/setup.sh +198 -0
- benchkit/git_surgery/revert-merge-with-followups/verify.sh +98 -0
- benchkit/git_surgery/secret-in-history/README.md +27 -0
- benchkit/git_surgery/secret-in-history/setup.sh +107 -0
- benchkit/git_surgery/secret-in-history/verify.sh +106 -0
- benchkit/git_surgery/split-the-mega-commit/setup.sh +50 -0
- benchkit/git_surgery/split-the-mega-commit/verify.sh +48 -0
- benchkit/git_surgery/untangle-nested-submodules/setup.sh +193 -0
- benchkit/git_surgery/untangle-nested-submodules/verify.sh +90 -0
- benchkit/history.py +474 -0
- benchkit/jobs.py +332 -0
- benchkit/leakage.py +51 -0
- benchkit/looping.py +873 -0
- benchkit/mc_render.py +274 -0
- benchkit/mc_viewer/dist/atlas.png +0 -0
- benchkit/mc_viewer/dist/blockStates.json.gz +0 -0
- benchkit/mc_viewer/dist/version.json +4 -0
- benchkit/mc_viewer/dist/viewer.html +23 -0
- benchkit/mc_viewer/dist/viewer.js +2 -0
- benchkit/mc_viewer/dist/viewer.js.LICENSE.txt +25 -0
- benchkit/mc_viewer/dist/worker.js +2 -0
- benchkit/mc_viewer/dist/worker.js.LICENSE.txt +19 -0
- benchkit/metrics.py +100 -0
- benchkit/ollama.py +60 -0
- benchkit/perf.py +353 -0
- benchkit/perf_report.py +207 -0
- benchkit/perturbations.py +208 -0
- benchkit/pi_agent.py +476 -0
- benchkit/pi_package/package-lock.json +1827 -0
- benchkit/pi_package/package.json +8 -0
- benchkit/report.py +142 -0
- benchkit/report_markdown.py +645 -0
- benchkit/results.py +688 -0
- benchkit/retry.py +163 -0
- benchkit/runner.py +769 -0
- benchkit/sandbox.py +1167 -0
- benchkit/template_check.py +291 -0
- benchkit/templates/arena.html +504 -0
- benchkit/templates/history.html +58 -0
- benchkit/templates/perf.html +509 -0
- benchkit/templates/report.html +769 -0
- benchkit/tui/__init__.py +5 -0
- benchkit/tui/app.py +87 -0
- benchkit/tui/app.tcss +512 -0
- benchkit/tui/formatting.py +84 -0
- benchkit/tui/screens/__init__.py +1 -0
- benchkit/tui/screens/connect.py +191 -0
- benchkit/tui/screens/detail.py +288 -0
- benchkit/tui/screens/help.py +84 -0
- benchkit/tui/screens/modals.py +544 -0
- benchkit/tui/screens/results.py +361 -0
- benchkit/tui/screens/run.py +988 -0
- benchkit/tui/screens/setup.py +733 -0
- benchkit/tui/theme.py +135 -0
- benchkit/tui/widgets.py +120 -0
- benchkit_cli-0.1.0.dist-info/METADATA +294 -0
- benchkit_cli-0.1.0.dist-info/RECORD +149 -0
- benchkit_cli-0.1.0.dist-info/WHEEL +5 -0
- benchkit_cli-0.1.0.dist-info/entry_points.txt +3 -0
- benchkit_cli-0.1.0.dist-info/licenses/LICENSE +201 -0
- benchkit_cli-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""PIQA benchmark - binary physical commonsense reasoning."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from benchkit.benchmarks.base import Task
|
|
7
|
+
from benchkit.benchmarks.mcq import extract_choice
|
|
8
|
+
from benchkit.benchmarks.utils import strip_think_tags
|
|
9
|
+
|
|
10
|
+
DATASET = Path(__file__).parent.parent / "datasets" / "piqa.jsonl"
|
|
11
|
+
|
|
12
|
+
SYSTEM = (
|
|
13
|
+
"Choose the most appropriate solution for the goal. "
|
|
14
|
+
"Reply with ONLY the letter (A or B)."
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _format_choices(choices: list[str]) -> str:
|
|
19
|
+
return "\n".join(
|
|
20
|
+
f"{letter}) {choice}" for letter, choice in zip("AB", choices, strict=False)
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class PIQA:
|
|
25
|
+
name = "piqa"
|
|
26
|
+
decision_instructions = "Which solution best achieves the goal?"
|
|
27
|
+
|
|
28
|
+
def load_tasks(self) -> list[Task]:
|
|
29
|
+
tasks = []
|
|
30
|
+
with open(DATASET) as f:
|
|
31
|
+
for line in f:
|
|
32
|
+
d = json.loads(line)
|
|
33
|
+
tasks.append(
|
|
34
|
+
Task(
|
|
35
|
+
id=d["task_id"],
|
|
36
|
+
prompt=d["goal"],
|
|
37
|
+
metadata={
|
|
38
|
+
"choices": d["choices"],
|
|
39
|
+
"answer": d["answer"],
|
|
40
|
+
},
|
|
41
|
+
)
|
|
42
|
+
)
|
|
43
|
+
return tasks
|
|
44
|
+
|
|
45
|
+
def build_prompt(self, task: Task) -> str:
|
|
46
|
+
choices = _format_choices(task.metadata["choices"])
|
|
47
|
+
return f"{SYSTEM}\n\nGoal: {task.prompt}\n\n{choices}"
|
|
48
|
+
|
|
49
|
+
def evaluate(self, task: Task, response: str) -> bool:
|
|
50
|
+
text = strip_think_tags(response)
|
|
51
|
+
choice = extract_choice(text, task.metadata["choices"])
|
|
52
|
+
return choice == task.metadata["answer"]
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"""RULER effective-context benchmark with runtime-generated prompts."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import math
|
|
6
|
+
import threading
|
|
7
|
+
from collections.abc import Callable
|
|
8
|
+
|
|
9
|
+
from benchkit.benchmarks.base import Task
|
|
10
|
+
from benchkit.benchmarks.downloads import Dataset
|
|
11
|
+
from benchkit.benchmarks.ruler_generator import (
|
|
12
|
+
CONTEXT_BUCKETS,
|
|
13
|
+
DEFAULT_SAMPLES_PER_KIND,
|
|
14
|
+
ESSAY_FILE,
|
|
15
|
+
PRACTICAL_SAMPLES_PER_KIND,
|
|
16
|
+
TASK_KINDS,
|
|
17
|
+
TASKS_PER_BUCKET,
|
|
18
|
+
cache_dir,
|
|
19
|
+
context_label,
|
|
20
|
+
corpus_installed,
|
|
21
|
+
fit_prompt,
|
|
22
|
+
generate_tasks,
|
|
23
|
+
install_corpus,
|
|
24
|
+
)
|
|
25
|
+
from benchkit.benchmarks.utils import strip_think_tags
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class RULER:
|
|
29
|
+
"""Consumer-friendly RULER suite with repeated task-family coverage."""
|
|
30
|
+
|
|
31
|
+
name = "ruler"
|
|
32
|
+
samples_per_kind = PRACTICAL_SAMPLES_PER_KIND
|
|
33
|
+
tasks_per_variant = samples_per_kind * len(TASK_KINDS)
|
|
34
|
+
task_count = tasks_per_variant * len(CONTEXT_BUCKETS)
|
|
35
|
+
context_buckets = CONTEXT_BUCKETS
|
|
36
|
+
variant_labels = tuple(context_label(bucket) for bucket in CONTEXT_BUCKETS)
|
|
37
|
+
variant_count = len(CONTEXT_BUCKETS)
|
|
38
|
+
list_task_count = f"{tasks_per_variant} × 6"
|
|
39
|
+
include_in_overall = False
|
|
40
|
+
list_note = "practical · 13 tasks × 3 samples · 4k–128k"
|
|
41
|
+
evaluation_activity = "checking retrieved values"
|
|
42
|
+
data_source = Dataset(
|
|
43
|
+
summary="SQuAD 2.0 + HotpotQA haystacks and the Paul Graham essays",
|
|
44
|
+
size=None,
|
|
45
|
+
location=cache_dir,
|
|
46
|
+
is_installed=corpus_installed,
|
|
47
|
+
install=lambda _progress: install_corpus(),
|
|
48
|
+
hint=(
|
|
49
|
+
f"{ESSAY_FILE} is not downloadable; generate it with NVIDIA/RULER's "
|
|
50
|
+
"download_paulgraham_essay.py"
|
|
51
|
+
),
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
def __init__(self) -> None:
|
|
55
|
+
self._unit_hints: dict[tuple[str, str, int], int] = {}
|
|
56
|
+
self._hint_lock = threading.Lock()
|
|
57
|
+
|
|
58
|
+
def load_tasks(self) -> list[Task]:
|
|
59
|
+
return generate_tasks(samples_per_kind=self.samples_per_kind)
|
|
60
|
+
|
|
61
|
+
def variants(self, client: object, model: str) -> list[str]:
|
|
62
|
+
"""Return buckets that fit the model's discovered served context."""
|
|
63
|
+
limit: int | None = None
|
|
64
|
+
discover = getattr(client, "context_length", None)
|
|
65
|
+
if callable(discover):
|
|
66
|
+
try:
|
|
67
|
+
value = discover(model)
|
|
68
|
+
if isinstance(value, int) and not isinstance(value, bool) and value > 0:
|
|
69
|
+
limit = value
|
|
70
|
+
except Exception:
|
|
71
|
+
limit = None
|
|
72
|
+
return [
|
|
73
|
+
context_label(bucket)
|
|
74
|
+
for bucket in CONTEXT_BUCKETS
|
|
75
|
+
if limit is None or bucket <= limit
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
def tasks_for_variant(self, tasks: list[Task], variant: str) -> list[Task]:
|
|
79
|
+
return [task for task in tasks if task.metadata.get("variant") == variant]
|
|
80
|
+
|
|
81
|
+
def result_metadata(self, variant: str | None) -> dict:
|
|
82
|
+
if not variant:
|
|
83
|
+
return {"include_in_overall": self.include_in_overall}
|
|
84
|
+
context_tokens = next(
|
|
85
|
+
(bucket for bucket in CONTEXT_BUCKETS if context_label(bucket) == variant),
|
|
86
|
+
0,
|
|
87
|
+
)
|
|
88
|
+
return {
|
|
89
|
+
"context_tokens": context_tokens,
|
|
90
|
+
"context_label": variant,
|
|
91
|
+
"include_in_overall": self.include_in_overall,
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
def build_prompt(self, task: Task) -> str:
|
|
95
|
+
prompt, _, _ = fit_prompt(task)
|
|
96
|
+
return prompt
|
|
97
|
+
|
|
98
|
+
def build_prompt_for(self, task: Task, client: object, model: str) -> str:
|
|
99
|
+
tokenizer = getattr(client, "tokenize", None)
|
|
100
|
+
token_count: Callable[[str], int | None] | None = None
|
|
101
|
+
if callable(tokenizer):
|
|
102
|
+
|
|
103
|
+
def count(prompt: str) -> int | None:
|
|
104
|
+
tokens = tokenizer(model, prompt)
|
|
105
|
+
return len(tokens) if isinstance(tokens, list) else None
|
|
106
|
+
|
|
107
|
+
token_count = count
|
|
108
|
+
|
|
109
|
+
cache_key = (
|
|
110
|
+
model,
|
|
111
|
+
str(task.metadata["task_type"]),
|
|
112
|
+
int(task.metadata["context_tokens"]),
|
|
113
|
+
)
|
|
114
|
+
with self._hint_lock:
|
|
115
|
+
initial_units = self._unit_hints.get(cache_key)
|
|
116
|
+
prompt, units, _ = fit_prompt(
|
|
117
|
+
task,
|
|
118
|
+
token_count,
|
|
119
|
+
initial_units=initial_units,
|
|
120
|
+
)
|
|
121
|
+
with self._hint_lock:
|
|
122
|
+
self._unit_hints[cache_key] = units
|
|
123
|
+
return prompt
|
|
124
|
+
|
|
125
|
+
def evaluate(self, task: Task, response: str) -> float:
|
|
126
|
+
"""Return RULER's fraction of reference strings found in the answer."""
|
|
127
|
+
text = strip_think_tags(response).casefold()
|
|
128
|
+
answers = [str(answer).casefold() for answer in task.metadata["answers"]]
|
|
129
|
+
if not answers:
|
|
130
|
+
return 0.0
|
|
131
|
+
return sum(answer in text for answer in answers) / len(answers)
|
|
132
|
+
|
|
133
|
+
def task_statistics(self, records: list[object]) -> list[dict]:
|
|
134
|
+
"""Return per-task mean scores and Wilson 95% intervals."""
|
|
135
|
+
grouped: dict[str, list[float]] = {}
|
|
136
|
+
for record in records:
|
|
137
|
+
parts = str(getattr(record, "task_id", "")).split("/")
|
|
138
|
+
if len(parts) >= 4:
|
|
139
|
+
grouped.setdefault(parts[2], []).append(
|
|
140
|
+
float(getattr(record, "score", 0.0))
|
|
141
|
+
)
|
|
142
|
+
rows = []
|
|
143
|
+
z = 1.959963984540054
|
|
144
|
+
for kind, scores in sorted(grouped.items()):
|
|
145
|
+
n = len(scores)
|
|
146
|
+
mean = sum(scores) / n
|
|
147
|
+
denominator = 1 + z * z / n
|
|
148
|
+
center = (mean + z * z / (2 * n)) / denominator
|
|
149
|
+
margin = (
|
|
150
|
+
z * math.sqrt(mean * (1 - mean) / n + z * z / (4 * n * n)) / denominator
|
|
151
|
+
)
|
|
152
|
+
rows.append(
|
|
153
|
+
{
|
|
154
|
+
"task": kind,
|
|
155
|
+
"samples": n,
|
|
156
|
+
"score": round(mean * 100, 1),
|
|
157
|
+
"ci95_low": round(max(0.0, center - margin) * 100, 1),
|
|
158
|
+
"ci95_high": round(min(1.0, center + margin) * 100, 1),
|
|
159
|
+
}
|
|
160
|
+
)
|
|
161
|
+
return rows
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class RULERFull(RULER):
|
|
165
|
+
"""Complete RULER suite for research-scale, explicitly opted-in runs."""
|
|
166
|
+
|
|
167
|
+
name = "ruler-full"
|
|
168
|
+
samples_per_kind = DEFAULT_SAMPLES_PER_KIND
|
|
169
|
+
tasks_per_variant = TASKS_PER_BUCKET
|
|
170
|
+
task_count = tasks_per_variant * len(CONTEXT_BUCKETS)
|
|
171
|
+
list_task_count = f"{tasks_per_variant:,} × 6"
|
|
172
|
+
list_note = "full · 13 tasks × 500 samples · 4k–128k · extremely slow"
|