tuieval 0.2.0.dev3__tar.gz → 0.2.0.dev4__tar.gz

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.
Files changed (71) hide show
  1. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/CHANGELOG.md +1 -0
  2. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/PKG-INFO +1 -1
  3. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/_version.py +2 -2
  4. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/tune.py +4 -1
  5. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/tests/test_tuieval.py +21 -4
  6. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/.gitignore +0 -0
  7. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/LICENSE +0 -0
  8. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/README.md +0 -0
  9. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/RELEASING.md +0 -0
  10. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/docs/images/brand/README.md +0 -0
  11. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/docs/images/brand/favicon.ico +0 -0
  12. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/docs/images/brand/readme-header.png +0 -0
  13. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/docs/images/brand/social-preview.png +0 -0
  14. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/docs/images/brand/tuieval-icon-1024.png +0 -0
  15. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/docs/images/brand/tuieval-icon-128.png +0 -0
  16. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/docs/images/brand/tuieval-icon-16.png +0 -0
  17. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/docs/images/brand/tuieval-icon-16.svg +0 -0
  18. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/docs/images/brand/tuieval-icon-256.png +0 -0
  19. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/docs/images/brand/tuieval-icon-32.png +0 -0
  20. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/docs/images/brand/tuieval-icon-48.png +0 -0
  21. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/docs/images/brand/tuieval-icon-512.png +0 -0
  22. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/docs/images/brand/tuieval-icon-64.png +0 -0
  23. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/docs/images/brand/tuieval-icon-animated.svg +0 -0
  24. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/docs/images/brand/tuieval-icon.svg +0 -0
  25. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/docs/images/tui-setup.png +0 -0
  26. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/docs/models.md +0 -0
  27. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/docs/writing-packs.md +0 -0
  28. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/pyproject.toml +0 -0
  29. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/__init__.py +0 -0
  30. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/__main__.py +0 -0
  31. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/cli.py +0 -0
  32. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/client.py +0 -0
  33. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/compare.py +0 -0
  34. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/engine.py +0 -0
  35. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/export.py +0 -0
  36. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/graders/__init__.py +0 -0
  37. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/graders/answer.py +0 -0
  38. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/graders/code.py +0 -0
  39. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/graders/rag.py +0 -0
  40. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/graders/reply.py +0 -0
  41. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/graders/tool_call.py +0 -0
  42. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/machines.py +0 -0
  43. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/packs.py +0 -0
  44. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/profiles.py +0 -0
  45. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/remove.py +0 -0
  46. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/run_evals.py +0 -0
  47. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/scaffold.py +0 -0
  48. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/selftest.py +0 -0
  49. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/templates/models.toml +0 -0
  50. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/templates/packs/answer/pack.toml +0 -0
  51. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/templates/packs/answer/system.txt +0 -0
  52. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/templates/packs/answer/tests.yaml +0 -0
  53. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/templates/packs/code/pack.toml +0 -0
  54. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/templates/packs/code/system.txt +0 -0
  55. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/templates/packs/code/tests.yaml +0 -0
  56. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/templates/packs/rag/pack.toml +0 -0
  57. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/templates/packs/rag/system.txt +0 -0
  58. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/templates/packs/rag/tests.yaml +0 -0
  59. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/templates/packs/reply/pack.toml +0 -0
  60. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/templates/packs/reply/system.txt +0 -0
  61. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/templates/packs/reply/tests.yaml +0 -0
  62. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/templates/packs/tool_call/pack.toml +0 -0
  63. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/templates/packs/tool_call/system.txt +0 -0
  64. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/templates/packs/tool_call/tests.yaml +0 -0
  65. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/templates/packs/tool_call/tools.yaml +0 -0
  66. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/tui.py +0 -0
  67. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/verdict.py +0 -0
  68. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/watch_proxy.py +0 -0
  69. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/workspace.py +0 -0
  70. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/src/tuieval/yamlout.py +0 -0
  71. {tuieval-0.2.0.dev3 → tuieval-0.2.0.dev4}/tests/mock_server.py +0 -0
@@ -2,6 +2,7 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ - Warm-start tuning recognises fine-tunes whose GGUF describes the MTP draft layer differently (e.g. listing KV heads per layer) as the same model shape, so they start from an already-tuned sibling instead of tuning in full.
5
6
  - The fit check (context sized from the GGUF header, llama.cpp's memory use) only applies to servers whose command takes `{ctx}`. Servers that size their own memory keep the model's `max_context` instead of an estimate that didn't apply to them; `fit_check = true|false` on a server overrides it.
6
7
  - `tuieval export pi` has no default presets path any more: set `[export.pi] presets` to your llama.cpp router's `--models-preset` file.
7
8
  - A new README screenshot from a demo workspace.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: tuieval
3
- Version: 0.2.0.dev3
3
+ Version: 0.2.0.dev4
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
@@ -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.dev3'
22
- __version_tuple__ = version_tuple = (0, 2, 0, 'dev3')
21
+ __version__ = version = '0.2.0.dev4'
22
+ __version_tuple__ = version_tuple = (0, 2, 0, 'dev4')
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -315,8 +315,11 @@ def family(path):
315
315
  i = machines.read_gguf(engine_mod.expand(path))
316
316
  except (OSError, ValueError):
317
317
  return None
318
+ # The MTP (nextn) draft layers at the end are left out: GGUFs of the same model describe them
319
+ # differently, and whether draft-mtp is offered is decided per model (knobs) anyway.
320
+ heads = i["kv_heads_per_layer"][:len(i["kv_heads_per_layer"]) - i["mtp_layers"]]
318
321
  return (i["architecture"], i["layers"], i["embedding"], i["experts"], i["experts_used"],
319
- i["head_dim_k"], i["head_dim_v"], tuple(i["kv_heads_per_layer"]))
322
+ i["head_dim_k"], i["head_dim_v"], tuple(heads))
320
323
 
321
324
 
322
325
  @dataclasses.dataclass
@@ -225,17 +225,25 @@ class Units(unittest.TestCase):
225
225
  self.assertEqual(p.modules, ["some_missing_module"])
226
226
 
227
227
 
228
- def fake_gguf(path, embedding=5120, size=0):
229
- """A GGUF header with just the keys machines.read_gguf reads, padded to size bytes."""
228
+ def fake_gguf(path, embedding=5120, size=0, kv_heads=4):
229
+ """A GGUF header with just the keys machines.read_gguf reads, padded to size bytes. kv_heads: a
230
+ number, or one per layer (a list, as some GGUFs store it)."""
230
231
  import struct
231
232
  s = lambda t: struct.pack("<Q", len(t)) + t.encode() # noqa: E731
232
233
  kv = [("general.architecture", 8, "qwen35"), ("qwen35.block_count", 4, 64),
233
234
  ("qwen35.embedding_length", 4, embedding), ("qwen35.attention.head_count", 4, 24),
234
- ("qwen35.attention.head_count_kv", 4, 4), ("qwen35.attention.key_length", 4, 256),
235
+ ("qwen35.attention.head_count_kv", 9 if isinstance(kv_heads, list) else 4, kv_heads),
236
+ ("qwen35.attention.key_length", 4, 256),
235
237
  ("qwen35.full_attention_interval", 4, 4), ("qwen35.nextn_predict_layers", 4, 1)]
236
238
  out = b"GGUF" + struct.pack("<IQQ", 3, 0, len(kv))
237
239
  for key, t, v in kv:
238
- out += s(key) + struct.pack("<I", t) + (s(v) if t == 8 else struct.pack("<I", v))
240
+ out += s(key) + struct.pack("<I", t)
241
+ if t == 8:
242
+ out += s(v)
243
+ elif t == 9: # an array of uint32
244
+ out += struct.pack("<IQ", 4, len(v)) + b"".join(struct.pack("<I", x) for x in v)
245
+ else:
246
+ out += struct.pack("<I", v)
239
247
  with open(path, "wb") as f:
240
248
  f.write(out + b"\0" * max(0, size - len(out)))
241
249
 
@@ -316,6 +324,15 @@ class WarmTune(unittest.TestCase):
316
324
  self.tune.measure = self.orig
317
325
  self.tmp.cleanup()
318
326
 
327
+ def test_family_ignores_the_mtp_layer(self):
328
+ # one GGUF lists KV heads per layer, none on the MTP (last) layer; the other gives one number
329
+ d = self.tmp.name
330
+ per_layer = [4 if (i + 1) % 4 == 0 else 0 for i in range(63)] + [0]
331
+ fake_gguf(f"{d}/listed.gguf", kv_heads=per_layer)
332
+ self.assertEqual(self.tune.family(f"{d}/listed.gguf"), self.tune.family(f"{d}/new.gguf"))
333
+ fake_gguf(f"{d}/other-shape.gguf", kv_heads=[8 if (i + 1) % 4 == 0 else 0 for i in range(64)])
334
+ self.assertNotEqual(self.tune.family(f"{d}/other-shape.gguf"), self.tune.family(f"{d}/new.gguf"))
335
+
319
336
  def test_option_index(self):
320
337
  opts = self.KNOBS["spec"]
321
338
  self.assertEqual(self.tune.option_index(opts, ["-t", "6", "--spec-type", "draft-mtp"]), 2)
File without changes
File without changes
File without changes
File without changes