tuieval 0.2.0.dev50__py3-none-any.whl → 0.2.0.dev56__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 +17 -7
- tuieval/machines.py +4 -4
- tuieval/tui.py +35 -3
- tuieval/watch_proxy.py +7 -0
- {tuieval-0.2.0.dev50.dist-info → tuieval-0.2.0.dev56.dist-info}/METADATA +1 -1
- {tuieval-0.2.0.dev50.dist-info → tuieval-0.2.0.dev56.dist-info}/RECORD +10 -10
- {tuieval-0.2.0.dev50.dist-info → tuieval-0.2.0.dev56.dist-info}/WHEEL +0 -0
- {tuieval-0.2.0.dev50.dist-info → tuieval-0.2.0.dev56.dist-info}/entry_points.txt +0 -0
- {tuieval-0.2.0.dev50.dist-info → tuieval-0.2.0.dev56.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.dev56'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 2, 0, 'dev56')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
tuieval/engine.py
CHANGED
|
@@ -987,16 +987,16 @@ class Engine:
|
|
|
987
987
|
del per_pack[name]
|
|
988
988
|
return {l: p for l, p in out.items() if p}
|
|
989
989
|
|
|
990
|
-
def
|
|
991
|
-
"""(
|
|
990
|
+
def seconds_per_answer(self, jobs, waiting_only=True):
|
|
991
|
+
"""({job key: expected seconds per answer}, borrowed, guessed, thin) for the waiting jobs.
|
|
992
992
|
A pack the model has answered uses its own median time there. Otherwise the median of
|
|
993
993
|
other models' times on that pack, scaled by how much slower or faster this model is than
|
|
994
|
-
them on packs both have answered.
|
|
994
|
+
them on packs both have answered. The sets say which estimates are rough (see estimate_seconds)."""
|
|
995
995
|
times = self.answer_times()
|
|
996
996
|
med = {l: {p: statistics.median(ts) for p, ts in pp.items()} for l, pp in times.items()}
|
|
997
|
-
|
|
997
|
+
spr_of, borrowed, guessed, thin = {}, set(), set(), set()
|
|
998
998
|
for j in jobs:
|
|
999
|
-
if j.status != "waiting":
|
|
999
|
+
if j.status in ("done", "skipped", "failed") or (waiting_only and j.status != "waiting"):
|
|
1000
1000
|
continue
|
|
1001
1001
|
own = med.get(j.label, {})
|
|
1002
1002
|
ref = {p: statistics.median(v[p] for l, v in med.items() if p in v and l != j.label)
|
|
@@ -1013,8 +1013,18 @@ class Engine:
|
|
|
1013
1013
|
else:
|
|
1014
1014
|
spr = statistics.median(own.values()) if own else DEFAULT_SECONDS_PER_REQUEST
|
|
1015
1015
|
guessed.add((j.key, bool(own)))
|
|
1016
|
-
|
|
1017
|
-
|
|
1016
|
+
spr_of[j.key] = spr
|
|
1017
|
+
return spr_of, borrowed, guessed, thin
|
|
1018
|
+
|
|
1019
|
+
def estimate_seconds(self, jobs):
|
|
1020
|
+
"""(seconds, notes): expected run time for the waiting jobs, estimated per pack
|
|
1021
|
+
(seconds_per_answer). notes lists what made the estimate rough ([] = solid)."""
|
|
1022
|
+
spr_of, borrowed, guessed, thin = self.seconds_per_answer(jobs)
|
|
1023
|
+
total = 0.0
|
|
1024
|
+
for j in jobs:
|
|
1025
|
+
if j.key in spr_of:
|
|
1026
|
+
done = len(self._done_keys(j)) if j.merge else 0
|
|
1027
|
+
total += max(0, j.total - done) * spr_of[j.key]
|
|
1018
1028
|
notes = []
|
|
1019
1029
|
if borrowed:
|
|
1020
1030
|
factors = sorted({f for _, f, _ in borrowed if f is not None})
|
tuieval/machines.py
CHANGED
|
@@ -65,10 +65,10 @@ def detect():
|
|
|
65
65
|
# macOS default when unset: about 2/3 of RAM up to 36 GB, 3/4 above.
|
|
66
66
|
limit = wired / 1024 if wired > 0 else ram * (0.75 if ram > 36 else 2 / 3)
|
|
67
67
|
gpu_cores = None
|
|
68
|
-
try:
|
|
69
|
-
out = subprocess.run(["
|
|
70
|
-
timeout=
|
|
71
|
-
m = re.search(r"
|
|
68
|
+
try: # the GPU driver's own count: instant, where system_profiler can take seconds (CI's virtual Macs)
|
|
69
|
+
out = subprocess.run(["ioreg", "-rc", "AGXAccelerator", "-d1"], capture_output=True, text=True,
|
|
70
|
+
timeout=5).stdout
|
|
71
|
+
m = re.search(r'"gpu-core-count"\s*=\s*(\d+)', out)
|
|
72
72
|
gpu_cores = int(m.group(1)) if m else None
|
|
73
73
|
except (OSError, subprocess.TimeoutExpired):
|
|
74
74
|
pass
|
tuieval/tui.py
CHANGED
|
@@ -1855,6 +1855,8 @@ class RunScreen(Screen):
|
|
|
1855
1855
|
self.current = ""
|
|
1856
1856
|
self.req_first = None
|
|
1857
1857
|
self.stats = []
|
|
1858
|
+
self.spr, self.rough = None, set() # job key -> expected seconds per answer (ETA), rough ones
|
|
1859
|
+
self.live = {} # job key -> seconds per answer in this session
|
|
1858
1860
|
self.mem = {}
|
|
1859
1861
|
self.outcome = "" # "Finished" or "Cancelled" once the queue is done
|
|
1860
1862
|
self.ended = None
|
|
@@ -2037,6 +2039,8 @@ class RunScreen(Screen):
|
|
|
2037
2039
|
+ (f" [red]copy of repeat {r['identical_to_repeat'] + 1}[/red]"
|
|
2038
2040
|
if r.get("identical_to_repeat") is not None else ""))
|
|
2039
2041
|
self.stats.append(r)
|
|
2042
|
+
if r.get("total_s"):
|
|
2043
|
+
self.live.setdefault(job.key, []).append(r["total_s"])
|
|
2040
2044
|
self.recent_entries[row_key] = {"model": job.label, "pack": job.pack.name, "record": r,
|
|
2041
2045
|
"pack_fp": job.pack.fingerprint}
|
|
2042
2046
|
if recent.row_count > 500:
|
|
@@ -2187,6 +2191,34 @@ class RunScreen(Screen):
|
|
|
2187
2191
|
("note", short_note(j.note))):
|
|
2188
2192
|
q.update_cell(j.key, col, value, update_width=True)
|
|
2189
2193
|
|
|
2194
|
+
LIVE_ANSWERS = 5 # a pack's own times this session take over from its history after this many
|
|
2195
|
+
|
|
2196
|
+
def eta_seconds(self):
|
|
2197
|
+
"""(seconds, rough): time left, pack by pack: answers left × seconds per answer. A pack's own
|
|
2198
|
+
average this session once it has LIVE_ANSWERS of them, before that its history (Engine.
|
|
2199
|
+
seconds_per_answer: this model's past times there, or other models' scaled). Divided by the
|
|
2200
|
+
models running side by side. rough: some packs have no history of their own yet."""
|
|
2201
|
+
new = [j for j in self.jobs if self.spr is None or (j.key not in self.spr and j.status not in
|
|
2202
|
+
("done", "skipped", "failed"))]
|
|
2203
|
+
if new: # at the start, and for evals added to the run
|
|
2204
|
+
spr, borrowed, guessed, _ = self.app.engine.seconds_per_answer(new, waiting_only=False)
|
|
2205
|
+
self.spr = {**(self.spr or {}), **spr}
|
|
2206
|
+
self.rough |= {k for k, *_ in borrowed} | {k for k, _ in guessed}
|
|
2207
|
+
left, rough, models = 0.0, False, set()
|
|
2208
|
+
for j in self.jobs:
|
|
2209
|
+
if j.status in ("done", "skipped", "failed") or j.done >= j.total:
|
|
2210
|
+
continue
|
|
2211
|
+
live = self.live.get(j.key, [])
|
|
2212
|
+
if len(live) >= self.LIVE_ANSWERS:
|
|
2213
|
+
spr = sum(live) / len(live)
|
|
2214
|
+
else:
|
|
2215
|
+
spr = self.spr.get(j.key, engine.DEFAULT_SECONDS_PER_REQUEST)
|
|
2216
|
+
rough |= j.key in self.rough
|
|
2217
|
+
left += (j.total - j.done) * spr
|
|
2218
|
+
models.add(j.label)
|
|
2219
|
+
lanes = max(1, min(self.parallel or self.app.engine.parallel_models(), len(models)))
|
|
2220
|
+
return left / lanes, rough
|
|
2221
|
+
|
|
2190
2222
|
def update_overall(self):
|
|
2191
2223
|
done = sum(j.done for j in self.jobs)
|
|
2192
2224
|
passed = sum(j.passed for j in self.jobs)
|
|
@@ -2194,9 +2226,9 @@ class RunScreen(Screen):
|
|
|
2194
2226
|
self.query_one("#bar", ProgressBar).update(progress=done)
|
|
2195
2227
|
elapsed = time.time() - self.started
|
|
2196
2228
|
eta = ""
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
eta = f" · ETA {
|
|
2229
|
+
if self.running and self.total > done:
|
|
2230
|
+
left, rough = self.eta_seconds()
|
|
2231
|
+
eta = f" · ETA {'~' if rough else ''}{fmt_secs(left)}"
|
|
2200
2232
|
pct = f"{100 * passed / (passed + failed):.0f}%" if passed + failed else "-"
|
|
2201
2233
|
recent = self.stats[-50:]
|
|
2202
2234
|
tps = [r["gen_tps"] for r in recent if r.get("gen_tps")]
|
tuieval/watch_proxy.py
CHANGED
|
@@ -18,6 +18,7 @@ import http.client
|
|
|
18
18
|
import itertools
|
|
19
19
|
import json
|
|
20
20
|
import os
|
|
21
|
+
import socketserver
|
|
21
22
|
import sys
|
|
22
23
|
import threading
|
|
23
24
|
import time
|
|
@@ -129,6 +130,12 @@ class Proxy:
|
|
|
129
130
|
class Server(ThreadingHTTPServer):
|
|
130
131
|
daemon_threads = True
|
|
131
132
|
|
|
133
|
+
def server_bind(self):
|
|
134
|
+
# HTTPServer looks up its own hostname here (socket.getfqdn), which can take half a
|
|
135
|
+
# minute where DNS is slow; the name is only cosmetic, so use the address.
|
|
136
|
+
socketserver.TCPServer.server_bind(self)
|
|
137
|
+
self.server_name, self.server_port = self.server_address[:2]
|
|
138
|
+
|
|
132
139
|
def handle_error(self, request, client_address):
|
|
133
140
|
err = sys.exc_info()[1]
|
|
134
141
|
if isinstance(err, (BrokenPipeError, ConnectionResetError)):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: tuieval
|
|
3
|
-
Version: 0.2.0.
|
|
3
|
+
Version: 0.2.0.dev56
|
|
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,14 +1,14 @@
|
|
|
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=w3V6noQtCnYcwkOc0Hi3EmCrxSS1deuXpcG9aisclJI,535
|
|
4
4
|
tuieval/builtin.toml,sha256=Kxw22RZCJhURUyu5Wz8tj5Y1nM85A8hFVRbA4ocoPUg,4293
|
|
5
5
|
tuieval/cli.py,sha256=gzGBzhqvR0WKJQQNHB8CudpgViIeIyawrNWa54whmoI,4502
|
|
6
6
|
tuieval/client.py,sha256=kpsyLEZKfxCsvIGBHBbBy83TpI97CvnGCDq-4AbJS4Y,9986
|
|
7
7
|
tuieval/compare.py,sha256=SHN_o_nlppFcHMBqBZRITIkeQDPaR_JxhUZItQLMBwo,26270
|
|
8
8
|
tuieval/doctor.py,sha256=y1C_ggjd8oikXTrovgTBf26wjThP8EoVkfTVeO_n5dQ,6070
|
|
9
|
-
tuieval/engine.py,sha256=
|
|
9
|
+
tuieval/engine.py,sha256=0PuHFus1k02qAY8nlsI6z5iQo7IT82bMwmHDZT6fGtU,114784
|
|
10
10
|
tuieval/export.py,sha256=dbHQgL_ubWtIPM1sLzAew_gETnrDJyd0zgqVA5vkpXM,9657
|
|
11
|
-
tuieval/machines.py,sha256=
|
|
11
|
+
tuieval/machines.py,sha256=tdRrn3WNOmCHwfcxcWz1NuAuOJdI7WnJFR1y6xgF89c,13512
|
|
12
12
|
tuieval/onboard.py,sha256=IYETVDWCCo9vF0Dtj4_rr9VanYeCky8PwP3-2g5A_l0,6215
|
|
13
13
|
tuieval/packs.py,sha256=tiLmxsrX_M5EUMuR4Yvb7pLBLEI15wamHSjflD6wjoY,11299
|
|
14
14
|
tuieval/profiles.py,sha256=soeLxjdB-l-OxSY8jZ4yjwfdSnsBV-QICcwKxRJS7nQ,3663
|
|
@@ -17,10 +17,10 @@ tuieval/remove.py,sha256=Vwh43nm9lVb9U9aN-h6CMYbkTwdR3UWfZObwweF72n0,5157
|
|
|
17
17
|
tuieval/run_evals.py,sha256=5bQEqU533XYiLze9dYcl72c5GSIpohMj1eqJrePRwnc,46450
|
|
18
18
|
tuieval/scaffold.py,sha256=YBOqniJpf_GtKKAFF3_OHxxMGbmTWdFjcClGcOnrrKE,12130
|
|
19
19
|
tuieval/selftest.py,sha256=nExkrOidgymlmvkxImEBfrQG5iTUN5WuRMIKtqusCCs,9835
|
|
20
|
-
tuieval/tui.py,sha256=
|
|
20
|
+
tuieval/tui.py,sha256=xAQnR270m7x-rfTdK7LBPMM9MEQC37zndD1TOTq8EUU,166103
|
|
21
21
|
tuieval/tune.py,sha256=jXwYuSjfdqbLCE3WonP2xaUHwk_FnhI67twB1BaHggI,38992
|
|
22
22
|
tuieval/verdict.py,sha256=Muo1a05mCv781MlEJsXwDsGaKbRi0JS4Lv8HdvK_Aco,19054
|
|
23
|
-
tuieval/watch_proxy.py,sha256=
|
|
23
|
+
tuieval/watch_proxy.py,sha256=bnDO1i6n6yUs1hODoUWcMppJMGPavoQqs6aNYrIxpT8,11416
|
|
24
24
|
tuieval/workspace.py,sha256=V_HhkaN1odr0OpjNsPYradRWLpzDldM7SwpvxohBL4U,895
|
|
25
25
|
tuieval/yamlout.py,sha256=r1IokjLqW-Ztpg1fSn33ZW3VK00v1VvxymmU5Qy7GEw,606
|
|
26
26
|
tuieval/graders/__init__.py,sha256=_YCFY5euaInIQdX4RoQGS3kMuiK6q5J7HF2e4i0ou3Q,5940
|
|
@@ -46,8 +46,8 @@ tuieval/templates/packs/tool_call/pack.toml,sha256=n4bx0lGJHSmW41uVqhfIXJ2BWZpmT
|
|
|
46
46
|
tuieval/templates/packs/tool_call/system.txt,sha256=mKxu-lB-0YjLHXdgeFJa8x2C180OvcNz5cHv2N5Bg3U,254
|
|
47
47
|
tuieval/templates/packs/tool_call/tests.yaml,sha256=Nv7c4syrzJ9cU8EBKSK_1ZSFx9V02aCjW4-2TBCPT7s,1859
|
|
48
48
|
tuieval/templates/packs/tool_call/tools.yaml,sha256=HgxCkh0On2VwbHSsjAGM8tNCK7ZtKLGrs7lMCn3Fprs,1048
|
|
49
|
-
tuieval-0.2.0.
|
|
50
|
-
tuieval-0.2.0.
|
|
51
|
-
tuieval-0.2.0.
|
|
52
|
-
tuieval-0.2.0.
|
|
53
|
-
tuieval-0.2.0.
|
|
49
|
+
tuieval-0.2.0.dev56.dist-info/METADATA,sha256=nUWInJiqgtyGg3hiyaYIUuGD-BYOzoyqi3kRoSloRPk,13881
|
|
50
|
+
tuieval-0.2.0.dev56.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
51
|
+
tuieval-0.2.0.dev56.dist-info/entry_points.txt,sha256=7eIhi1GpFxBP2OLJV02Nn8LwsNuO512eKOGt1IBbj04,45
|
|
52
|
+
tuieval-0.2.0.dev56.dist-info/licenses/LICENSE,sha256=7wfRgGtBGH1aXhZkIn47oUznqKC18kEPMvUVgol7Ffc,1077
|
|
53
|
+
tuieval-0.2.0.dev56.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|