mirror of
https://github.com/Niko1221/Strata.git
synced 2026-11-07 14:21:06 -10:00
tune: when candidates were skipped for memory the result says so instead of 'already the fastest' (#5122)
'N settings could not be tried: not enough free memory' is the result message (and the Terminal's tuning line) only when some candidates were skipped for memory in a result that otherwise keeps the current settings; the structured outcome is unchanged and values.not_tried carries the count. Owner decision 11-04.
This commit is contained in:
1 parent
acbaa4391b
commit
c6dda74bf2
3 files changed
+46
-6
No files matched your search
@@ -230,6 +230,9 @@ def tune_words(result: dict | None, code: int | None = None) -> tuple[str, str]:
|
||||
gain = result.get("gain_pct")
|
||||
return "faster", (f"Done: answers are about {gain:.0f}% faster with the tuned settings." if isinstance(gain, (int, float))
|
||||
else "Done: the tuned settings are faster.")
|
||||
if out == "default_confirmed" and result.get("not_tried"):
|
||||
n = int(result["not_tried"]) # some candidates were never measured: "already fastest" would be untrue (#5122)
|
||||
return "some not tried", f"{n} setting{'s' if n != 1 else ''} could not be tried: not enough free memory"
|
||||
if out == "default_confirmed":
|
||||
return "already fastest", "Your computer already runs at its best with the standard settings. Nothing needed changing."
|
||||
if out == "inconclusive":
|
||||
|
||||
@@ -107,6 +107,7 @@ class TuneResult:
|
||||
#: minutes, pairs, faster_pairs, preset_name
|
||||
values: dict[str, Any] = field(default_factory=dict)
|
||||
message: str = ""
|
||||
not_tried: int = 0 # candidates skipped for lack of free memory in a result that otherwise confirms the current settings (#5122)
|
||||
mode: str = "quick"
|
||||
seconds: float = 0.0
|
||||
waited_s: float = 0.0 # of those seconds, spent waiting (box lock, busy PC, memory)
|
||||
@@ -371,7 +372,8 @@ class Tuner:
|
||||
r.values = {"gain_pct": r.gain_pct, "gain_decode_pct": r.gain_decode_pct, "base_tok_s": base, "tuned_tok_s": tuned,
|
||||
"noise_pct": round(100 * (r.noise or {}).get("spread", 0.0), 1) if r.noise else None,
|
||||
"drift_pct": round(100 * (r.noise or {}).get("drift", 0.0), 1) if r.noise else None,
|
||||
"minutes": round(r.seconds / 60.0 - r.waited_s / 60.0, 1), "pairs": r.pairs, "faster_pairs": r.faster_pairs}
|
||||
"minutes": round(r.seconds / 60.0 - r.waited_s / 60.0, 1), "pairs": r.pairs, "faster_pairs": r.faster_pairs,
|
||||
"not_tried": r.not_tried}
|
||||
|
||||
def _spec(self) -> RequestSet:
|
||||
long_tokens = 0
|
||||
@@ -649,8 +651,13 @@ class Tuner:
|
||||
"changed. Try again when the PC is quiet.")
|
||||
else:
|
||||
r.outcome = "default_confirmed"
|
||||
r.message = "Your current settings are already the fastest we found. Nothing was changed."
|
||||
if r.noise.get("noisy"):
|
||||
r.not_tried = sum(1 for a in arms if a.status == "skipped" and "memory" in (a.reason or ""))
|
||||
if r.not_tried: # "already the fastest" would claim a comparison that never happened (#5122)
|
||||
r.reason_code = r.reason_code or "some_not_tried"
|
||||
r.message = f"{r.not_tried} setting{'s' if r.not_tried != 1 else ''} could not be tried: not enough free memory"
|
||||
else:
|
||||
r.message = "Your current settings are already the fastest we found. Nothing was changed."
|
||||
if r.noise.get("noisy") and not r.not_tried:
|
||||
r.message += " (The PC was busy while measuring, so a small gain could be hidden.)"
|
||||
r.settings = {"args": chosen_args, "env": chosen_env, "per_request": per_request_chosen}
|
||||
cls, fields = "exact", []
|
||||
|
||||
@@ -144,16 +144,19 @@ class EngineAbort(unittest.TestCase):
|
||||
class RamGuard(unittest.TestCase):
|
||||
"""#5122: the restart candidate needs what the base run had, not the base's peak RSS plus the floor."""
|
||||
|
||||
def tuner(self, free_before, free_after, rss=23429.0, wait_ram_s=30):
|
||||
def tuner(self, free_before, free_after, rss=23429.0, wait_ram_s=30, big_card=False, gain=1.10):
|
||||
clock = FakeClock()
|
||||
session = StubSession(model=speed_with({("--kv-resident", "65536"): 1.10}), clock=clock, avail=free_before, rss=lambda a, e: rss)
|
||||
session = StubSession(model=speed_with({("--kv-resident", "65536"): gain}), clock=clock, avail=free_before, rss=lambda a, e: rss)
|
||||
real = session.system
|
||||
|
||||
def system():
|
||||
out = real()
|
||||
out["memory"]["available_mib"] = free_before if not session.runs else free_after
|
||||
return out
|
||||
t = autotune.Tuner(session, BASE, {}, make_ctx(), autotune.Options(wait_ram_s=wait_ram_s, per_request=False), clock=clock, sleep=clock.sleep,
|
||||
ctx = make_ctx()
|
||||
if big_card: # a 24 GB card also plans the 32K prompt chunk, which asks for 4 GiB more RAM than the base
|
||||
ctx.vram_mib = 24000
|
||||
t = autotune.Tuner(session, BASE, {}, ctx, autotune.Options(wait_ram_s=wait_ram_s, per_request=False), clock=clock, sleep=clock.sleep,
|
||||
system=system, total_ram_mib=32000, quiet=lambda: None)
|
||||
return t, session
|
||||
|
||||
@@ -177,6 +180,33 @@ class RamGuard(unittest.TestCase):
|
||||
self.assertIsNone(t._ram_guard(0, "x", wait_s=0))
|
||||
self.assertIn("not enough free memory", t._ram_guard(4096, "x", wait_s=0) or "") # 23.1 + 4 GiB needed, 24.1 free
|
||||
|
||||
def test_skipped_for_memory_is_said_instead_of_already_the_fastest(self):
|
||||
"""Owner 11-04: 'N settings could not be tried: not enough free memory', only when some were skipped for memory, in place of 'already the fastest'."""
|
||||
t, session = self.tuner(free_before=23654, free_after=24680, big_card=True, gain=1.0)
|
||||
r = t.run()
|
||||
self.assertEqual([(a["id"], a["status"]) for a in r.arms if a["status"] == "skipped"], [("prefill_32k", "skipped")], r.arms)
|
||||
self.assertEqual(r.outcome, "default_confirmed")
|
||||
self.assertEqual(r.not_tried, 1)
|
||||
self.assertEqual(r.message, "1 setting could not be tried: not enough free memory")
|
||||
self.assertNotIn("fastest", r.message)
|
||||
self.assertEqual(r.values["not_tried"], 1)
|
||||
from strata_cli.launch.runner import tune_words
|
||||
word, sentence = tune_words(r.to_dict())
|
||||
self.assertEqual(sentence, "1 setting could not be tried: not enough free memory")
|
||||
self.assertNotEqual(word, "already fastest")
|
||||
|
||||
def test_the_plural(self):
|
||||
from strata_cli.launch.runner import tune_words
|
||||
self.assertEqual(tune_words({"outcome": "default_confirmed", "not_tried": 2})[1], "2 settings could not be tried: not enough free memory")
|
||||
|
||||
def test_nothing_skipped_keeps_the_old_sentences(self):
|
||||
t, session = self.tuner(free_before=23654, free_after=24680, gain=1.0)
|
||||
r = t.run()
|
||||
self.assertEqual(r.not_tried, 0)
|
||||
self.assertEqual(r.message, "Your current settings are already the fastest we found. Nothing was changed.")
|
||||
from strata_cli.launch.runner import tune_words
|
||||
self.assertEqual(tune_words(r.to_dict())[0], "already fastest")
|
||||
|
||||
def test_the_old_rule_still_holds_when_the_base_had_plenty(self):
|
||||
t, session = self.tuner(free_before=40000, free_after=9000)
|
||||
t.run()
|
||||
|
||||
Reference in new issue
Block a user