tuieval 0.2.0.dev87__py3-none-any.whl → 0.2.0.dev89__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.
- tuieval/_version.py +2 -2
- tuieval/engine.py +12 -5
- tuieval/packs.py +14 -7
- tuieval/templates/packs/answer/pack.toml +1 -0
- tuieval/tui.py +4 -1
- {tuieval-0.2.0.dev87.dist-info → tuieval-0.2.0.dev89.dist-info}/METADATA +1 -1
- {tuieval-0.2.0.dev87.dist-info → tuieval-0.2.0.dev89.dist-info}/RECORD +10 -10
- {tuieval-0.2.0.dev87.dist-info → tuieval-0.2.0.dev89.dist-info}/WHEEL +0 -0
- {tuieval-0.2.0.dev87.dist-info → tuieval-0.2.0.dev89.dist-info}/entry_points.txt +0 -0
- {tuieval-0.2.0.dev87.dist-info → tuieval-0.2.0.dev89.dist-info}/licenses/LICENSE +0 -0
tuieval/_version.py
CHANGED
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.2.0.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 2, 0, '
|
|
21
|
+
__version__ = version = '0.2.0.dev89'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 2, 0, 'dev89')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
tuieval/engine.py
CHANGED
|
@@ -646,8 +646,9 @@ def serves(ids, name):
|
|
|
646
646
|
|
|
647
647
|
|
|
648
648
|
def pack_min_context(pack):
|
|
649
|
-
"""Rough context a pack needs: its longest prompt (~4 chars/token) plus room to answer
|
|
650
|
-
|
|
649
|
+
"""Rough context a pack needs: its longest prompt (~4 chars/token) plus room to answer (the
|
|
650
|
+
pack's own max_tokens when it sets one)."""
|
|
651
|
+
return max(len(t["input"]) for t in pack.tests) // 4 + (pack.max_tokens or 4096)
|
|
651
652
|
|
|
652
653
|
|
|
653
654
|
class Cancelled(Exception):
|
|
@@ -872,7 +873,8 @@ class Engine:
|
|
|
872
873
|
needs_tools = m.get("tools") is not False and any("tools" in p.needs for p in self.packs.values())
|
|
873
874
|
ep = choose_endpoint(eps, m["model"], effective_sampling(self.cfg, m), needs_tools, previous)
|
|
874
875
|
ep = ep and {"tag": ep["tag"], "provider": ep.get("provider_name"),
|
|
875
|
-
"quantization": ep.get("quantization") or "unknown"
|
|
876
|
+
"quantization": ep.get("quantization") or "unknown",
|
|
877
|
+
"max_output": ep.get("max_completion_tokens")}
|
|
876
878
|
except (OSError, ValueError):
|
|
877
879
|
# offline: assume the endpoint earlier results used (the run itself will need the network)
|
|
878
880
|
ep = {"tag": previous, "provider": None, "quantization": previous_quant} if previous else None
|
|
@@ -1196,6 +1198,9 @@ class Engine:
|
|
|
1196
1198
|
elif (sv.ctx or 10**9) < pack_min_context(pack):
|
|
1197
1199
|
job.status, job.note = "skipped", \
|
|
1198
1200
|
f"needs ~{pack_min_context(pack) // 1024}k context, {sv.ctx // 1024}k fits on {sv.machine.id}"
|
|
1201
|
+
elif pack.max_tokens and pack.max_tokens > ((self.endpoint(m) or {}).get("max_output") or 10**9):
|
|
1202
|
+
job.status, job.note = "skipped", \
|
|
1203
|
+
f"needs {pack.max_tokens:,} output tokens, endpoint allows {self.endpoint(m)['max_output']:,}"
|
|
1199
1204
|
elif missing:
|
|
1200
1205
|
job.status, job.note = "skipped", f"{', '.join(missing)} not installed in tuieval's Python"
|
|
1201
1206
|
elif status and status.startswith("outdated"):
|
|
@@ -2037,7 +2042,8 @@ class Engine:
|
|
|
2037
2042
|
def _body(self, job, test, rep=0):
|
|
2038
2043
|
s = job.sampling
|
|
2039
2044
|
body = {"model": job.model["served_name"], "messages": self._messages(job, test),
|
|
2040
|
-
"temperature": s["temperature"], "top_p": s["top_p"],
|
|
2045
|
+
"temperature": s["temperature"], "top_p": s["top_p"],
|
|
2046
|
+
"max_tokens": job.pack.max_tokens or s["max_tokens"]}
|
|
2041
2047
|
for k in ("top_k", "min_p", "presence_penalty", "repeat_penalty", "seed", "reasoning_effort"):
|
|
2042
2048
|
if k in s:
|
|
2043
2049
|
body[k] = s[k]
|
|
@@ -2380,7 +2386,8 @@ class Engine:
|
|
|
2380
2386
|
"model": {**{k: m.get(k) for k in ("label", "served_name", "server", "model", "tags", "vision", "mmproj")},
|
|
2381
2387
|
**{k: m[k] for k in ("tools", "max_context", "thinking") if k in m}},
|
|
2382
2388
|
"pack": {"name": job.pack.name, "label": job.pack.label, "group": job.pack.group,
|
|
2383
|
-
"fingerprint": job.pack.fingerprint, "tests": len(job.pack.tests)
|
|
2389
|
+
"fingerprint": job.pack.fingerprint, "tests": len(job.pack.tests),
|
|
2390
|
+
**({"max_tokens": job.pack.max_tokens} if job.pack.max_tokens else {})},
|
|
2384
2391
|
"settings": job.sampling,
|
|
2385
2392
|
"serving": job.settings.get("serving"),
|
|
2386
2393
|
"settings_fingerprint": settings_fingerprint(job.settings),
|
tuieval/packs.py
CHANGED
|
@@ -50,6 +50,7 @@ class Pack:
|
|
|
50
50
|
screen: int # tests in a screening run
|
|
51
51
|
certify_repeat: int # repeats in a certification run (0 = models.toml default)
|
|
52
52
|
stop_early: bool = False # stop the pack once its FAIL is certain (pack.toml stop_early)
|
|
53
|
+
max_tokens: int = 0 # output budget for this pack's answers (0 = [sampling] max_tokens)
|
|
53
54
|
|
|
54
55
|
@property
|
|
55
56
|
def modules(self):
|
|
@@ -135,12 +136,15 @@ NOT_FINGERPRINTED = {"reference", "wrong", "description", "category", "critical"
|
|
|
135
136
|
DIFFICULTIES = ("easy", "medium", "hard")
|
|
136
137
|
|
|
137
138
|
|
|
138
|
-
def _fingerprint(system, tools, grader, tests, images):
|
|
139
|
-
"""Hash of what the model sees and what decides pass/fail.
|
|
139
|
+
def _fingerprint(system, tools, grader, tests, images, max_tokens=0):
|
|
140
|
+
"""Hash of what the model sees and what decides pass/fail. A pack's own max_tokens counts
|
|
141
|
+
(it decides what gets cut off); packs without one keep the fingerprint they always had."""
|
|
140
142
|
h = hashlib.sha256()
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
143
|
+
what = {"system": system, "tools": tools, "grader": grader,
|
|
144
|
+
"tests": [{k: v for k, v in t.items() if k not in NOT_FINGERPRINTED} for t in tests]}
|
|
145
|
+
if max_tokens:
|
|
146
|
+
what["max_tokens"] = max_tokens
|
|
147
|
+
h.update(json.dumps(what, sort_keys=True, default=str).encode())
|
|
144
148
|
for path in sorted(images):
|
|
145
149
|
with open(path, "rb") as f:
|
|
146
150
|
h.update(f.read())
|
|
@@ -217,13 +221,16 @@ def load_pack(path):
|
|
|
217
221
|
if tools and "tools" not in needs:
|
|
218
222
|
needs = list(needs) + ["tools"]
|
|
219
223
|
gate = {"min_accuracy": 0.8, **meta.get("gate", {})}
|
|
224
|
+
max_tokens = meta.get("max_tokens", 0)
|
|
225
|
+
if "max_tokens" in meta and (isinstance(max_tokens, bool) or not isinstance(max_tokens, int) or max_tokens < 1):
|
|
226
|
+
raise PackError(f"{meta_path}: max_tokens must be a whole number above 0, not {max_tokens!r}")
|
|
220
227
|
return Pack(name=name, path=path, label=meta.get("label", name), group=meta.get("group", "Other"),
|
|
221
228
|
description=meta.get("description", ""), grader=meta.get("grader", "answer"),
|
|
222
229
|
system=system, needs=list(needs), tools=tools, tests=tests,
|
|
223
|
-
fingerprint=_fingerprint(system, tools, meta.get("grader", "answer"), tests, images),
|
|
230
|
+
fingerprint=_fingerprint(system, tools, meta.get("grader", "answer"), tests, images, max_tokens),
|
|
224
231
|
gate=gate, screen=int(meta.get("screen", 10)),
|
|
225
232
|
certify_repeat=int(meta.get("certify", {}).get("repeat", 0)),
|
|
226
|
-
stop_early=bool(meta.get("stop_early", False)))
|
|
233
|
+
stop_early=bool(meta.get("stop_early", False)), max_tokens=max_tokens)
|
|
227
234
|
|
|
228
235
|
|
|
229
236
|
def load_packs(packs_dir=None, errors=None):
|
|
@@ -6,6 +6,7 @@ grader = "answer" # how answers are scored (answer, rag, reply, t
|
|
|
6
6
|
system = "system.txt" # the system prompt sent with every question
|
|
7
7
|
order = 100 # position in the list
|
|
8
8
|
screen = 6 # tests in a Screen run
|
|
9
|
+
# max_tokens = 32768 # this pack's output budget, instead of models.toml [sampling] max_tokens
|
|
9
10
|
|
|
10
11
|
[certify]
|
|
11
12
|
repeat = 3 # times each question is asked in a Certify run
|
tuieval/tui.py
CHANGED
|
@@ -531,7 +531,8 @@ class AnswerScreen(ModalScreen):
|
|
|
531
531
|
partial = " [cyan](pack still running or unfinished: not in scores yet)[/cyan]" if entry.get("partial") else ""
|
|
532
532
|
quant = f" [magenta]{rec['quantization']}[/magenta]" if rec.get("quantization") else ""
|
|
533
533
|
finish = rec.get("finish") or "?"
|
|
534
|
-
|
|
534
|
+
limit = f"this pack's max_tokens, {pack.max_tokens:,}" if pack and pack.max_tokens else "max_tokens"
|
|
535
|
+
finish = f"[bold red]{finish} (cut off at {limit})[/]" if finish == "length" else finish
|
|
535
536
|
toks = rec.get("completion_tokens")
|
|
536
537
|
split = ", ".join(f"{k} {rec[k + '_tokens']:,}" for k in ("reasoning", "answer")
|
|
537
538
|
if rec.get(k + "_tokens") is not None)
|
|
@@ -709,6 +710,8 @@ class SetupScreen(Screen):
|
|
|
709
710
|
count = (f"[b cyan]{len(picked)}/{len(pk.tests)} tests picked[/]" if picked
|
|
710
711
|
else f"[dim]{len(pk.tests)} tests[/dim]")
|
|
711
712
|
needs = f" [magenta]{', '.join(pk.needs)}[/magenta]" if pk.needs else ""
|
|
713
|
+
if pk.max_tokens:
|
|
714
|
+
needs += f" [dim]max_tokens {pk.max_tokens:,}[/dim]"
|
|
712
715
|
mix = {lvl: sum(t.get("difficulty") == lvl for t in pk.tests) for lvl in ("easy", "medium", "hard")}
|
|
713
716
|
mixed = " ".join(f"[{DIFF_STYLE[l]}]{n}{l[0].upper()}[/]" for l, n in mix.items() if n)
|
|
714
717
|
packs.add_option(Selection(f"[dim]{pk.group} ·[/dim] {pk.label} {count} {mixed}{needs}",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: tuieval
|
|
3
|
-
Version: 0.2.0.
|
|
3
|
+
Version: 0.2.0.dev89
|
|
4
4
|
Summary: Evaluate local and frontier LLMs on your own questions: accuracy, speed, tokens and PASS/FAIL verdicts, in the terminal.
|
|
5
5
|
Project-URL: Homepage, https://github.com/ashe-wb/tuieval
|
|
6
6
|
Project-URL: Issues, https://github.com/ashe-wb/tuieval/issues
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
tuieval/__init__.py,sha256=myVXVX7htbwezW6k3x_FuKgn1RSZ2WcTaDEMByGn6Wg,312
|
|
2
2
|
tuieval/__main__.py,sha256=E6Gls0DNz8GQK2K-kOUIx8cYhgANW_CH54VKrfCfs14,52
|
|
3
|
-
tuieval/_version.py,sha256=
|
|
3
|
+
tuieval/_version.py,sha256=XiUzkOIwjrCyySM-wvAr3iW2t63wQjeKE_BTt6XJQng,535
|
|
4
4
|
tuieval/builtin.toml,sha256=Kxw22RZCJhURUyu5Wz8tj5Y1nM85A8hFVRbA4ocoPUg,4293
|
|
5
5
|
tuieval/cli.py,sha256=VwiaU1F9bZtU8C-gEowJq58kPeYQY4t6SY_HwrV-qgc,4702
|
|
6
6
|
tuieval/client.py,sha256=kpsyLEZKfxCsvIGBHBbBy83TpI97CvnGCDq-4AbJS4Y,9986
|
|
7
7
|
tuieval/compare.py,sha256=uXU_Yzf4zDSHoupHQrTmBhsfc8wCyI1nMaZQN81ybiA,30522
|
|
8
8
|
tuieval/doctor.py,sha256=j2MdDORstsAGPnRmpsnxau1_fR6sTc_oEFGM5zugTJU,7246
|
|
9
|
-
tuieval/engine.py,sha256=
|
|
9
|
+
tuieval/engine.py,sha256=BS2BXLaxtw3RFI6-5PDvhV5VLh5v0m0cB_F3fPC5MtM,125105
|
|
10
10
|
tuieval/export.py,sha256=dbHQgL_ubWtIPM1sLzAew_gETnrDJyd0zgqVA5vkpXM,9657
|
|
11
11
|
tuieval/logs.py,sha256=01gZK6tf53dIThaIrs1bEsz9eqKYVlcxpyaLnSPTVxo,8127
|
|
12
12
|
tuieval/machines.py,sha256=t9tu6CZeXZON4EtOVnEwP4VtaynpVLf9Cz8TNjf7jtY,20124
|
|
13
13
|
tuieval/onboard.py,sha256=IYETVDWCCo9vF0Dtj4_rr9VanYeCky8PwP3-2g5A_l0,6215
|
|
14
|
-
tuieval/packs.py,sha256=
|
|
14
|
+
tuieval/packs.py,sha256=ZgaZ1m2ePYvDjmddSc3nafnMEn7kTq9WcDpCaJSZleQ,12026
|
|
15
15
|
tuieval/profiles.py,sha256=soeLxjdB-l-OxSY8jZ4yjwfdSnsBV-QICcwKxRJS7nQ,3663
|
|
16
16
|
tuieval/pta.py,sha256=i5oPj-Pz3N9u7bzzuZwsQvMGdxWdAncww2nR15K6PHY,12108
|
|
17
17
|
tuieval/remove.py,sha256=Vwh43nm9lVb9U9aN-h6CMYbkTwdR3UWfZObwweF72n0,5157
|
|
18
18
|
tuieval/run_evals.py,sha256=FU3bvu3jt9ZWg3YLsXNINbdeClXMioyc4zQ4yEhmBQs,47855
|
|
19
19
|
tuieval/scaffold.py,sha256=YBOqniJpf_GtKKAFF3_OHxxMGbmTWdFjcClGcOnrrKE,12130
|
|
20
20
|
tuieval/selftest.py,sha256=nExkrOidgymlmvkxImEBfrQG5iTUN5WuRMIKtqusCCs,9835
|
|
21
|
-
tuieval/tui.py,sha256=
|
|
21
|
+
tuieval/tui.py,sha256=yD-3pQJ7I71r8lg49m0aWD5SlfA_Bk9BIz6XUJj8_UM,177016
|
|
22
22
|
tuieval/tune.py,sha256=azxxthgJeag8JyoQUgaRxq6oI1XvEgzb9vkszjJZH7w,39645
|
|
23
23
|
tuieval/verdict.py,sha256=3SM8qrVdWNIFDENagaR5ZPBYEnjsBtkYB9WS5TDVssU,20517
|
|
24
24
|
tuieval/watch_proxy.py,sha256=bnDO1i6n6yUs1hODoUWcMppJMGPavoQqs6aNYrIxpT8,11416
|
|
@@ -31,7 +31,7 @@ tuieval/graders/rag.py,sha256=j_gEjmaXmY_hgKu7-7pVQpQ8Cwb49gadnwFurih-1Hw,1447
|
|
|
31
31
|
tuieval/graders/reply.py,sha256=BdkL7EWSSMoyjwCOFa97TTQMR1QyrpMH-ntcgjzDPEg,2199
|
|
32
32
|
tuieval/graders/tool_call.py,sha256=_QXURtOk4ZKBnxXVMzFL1c9jWLWksRlLZ4VqOCL0t90,3578
|
|
33
33
|
tuieval/templates/models.toml,sha256=0RsHR_oCNmkkUdPBemLahNIwaOOPKqT97hA97TJFDYw,1021
|
|
34
|
-
tuieval/templates/packs/answer/pack.toml,sha256=
|
|
34
|
+
tuieval/templates/packs/answer/pack.toml,sha256=8tKQZ-4y9p7I6LjtcJ6CKmqL8M8ZsPna0TT-6mWtmcI,1274
|
|
35
35
|
tuieval/templates/packs/answer/system.txt,sha256=m4V6X1i49Bas2HowZMWgfdDSPDHTObb_WxHXt0xw1Yo,248
|
|
36
36
|
tuieval/templates/packs/answer/tests.yaml,sha256=WiYPOknPcO9E6f1wXhLcfA0W5v-oK8MgZV956uWtcUQ,2660
|
|
37
37
|
tuieval/templates/packs/code/pack.toml,sha256=nnrUVSWlIHAoORTIc4W3emoniwWOcfx2z-ipqIqU3ks,457
|
|
@@ -47,8 +47,8 @@ tuieval/templates/packs/tool_call/pack.toml,sha256=n4bx0lGJHSmW41uVqhfIXJ2BWZpmT
|
|
|
47
47
|
tuieval/templates/packs/tool_call/system.txt,sha256=mKxu-lB-0YjLHXdgeFJa8x2C180OvcNz5cHv2N5Bg3U,254
|
|
48
48
|
tuieval/templates/packs/tool_call/tests.yaml,sha256=Nv7c4syrzJ9cU8EBKSK_1ZSFx9V02aCjW4-2TBCPT7s,1859
|
|
49
49
|
tuieval/templates/packs/tool_call/tools.yaml,sha256=HgxCkh0On2VwbHSsjAGM8tNCK7ZtKLGrs7lMCn3Fprs,1048
|
|
50
|
-
tuieval-0.2.0.
|
|
51
|
-
tuieval-0.2.0.
|
|
52
|
-
tuieval-0.2.0.
|
|
53
|
-
tuieval-0.2.0.
|
|
54
|
-
tuieval-0.2.0.
|
|
50
|
+
tuieval-0.2.0.dev89.dist-info/METADATA,sha256=t3hBuHdUYssk-1LBJ7YfWAHkTPjsTXR9CnErwPjDKo8,14580
|
|
51
|
+
tuieval-0.2.0.dev89.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
52
|
+
tuieval-0.2.0.dev89.dist-info/entry_points.txt,sha256=7eIhi1GpFxBP2OLJV02Nn8LwsNuO512eKOGt1IBbj04,45
|
|
53
|
+
tuieval-0.2.0.dev89.dist-info/licenses/LICENSE,sha256=7wfRgGtBGH1aXhZkIn47oUznqKC18kEPMvUVgol7Ffc,1077
|
|
54
|
+
tuieval-0.2.0.dev89.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|