ember.cpp 0.1.0
C++ inference engine for Llama-family and paperkiln models (CPU, CUDA, WebAssembly)
Loading...
Searching...
No Matches
test_transformer_cpp_gguf.py
Go to the documentation of this file.
1"""Verify a transformer_cpp-trained GGUF end-to-end in the tinyllama.cpp engine.
2
3Loads the GGUF through the pybind11 API (TinyLlamaSession), checks the config
4parsed sanely (word-level tokenizer family, expected dims), runs a handful of
5prompts, and applies mechanical sanity checks to the generations:
6
7 * non-empty output
8 * decoded tokens are words from the embedded vocabulary
9 * not a single token repeated forever (degenerate loop check)
10
11Exit code 0 = engine runs our GGUF; nonzero = something to tinker with.
12
13 python test_transformer_cpp_gguf.py path/to/model.gguf [--steps 30]
14
15(For GGUF loads the engine reads the tokenizer from embedded metadata; the
16tokenizer_path argument is ignored, so we just pass the GGUF path twice.)
17"""
18import argparse
19import sys
20
21
22def main():
24 ap.add_argument("gguf")
25 ap.add_argument("--steps", type=int, default=30)
26 ap.add_argument("--threads", type=int, default=4)
27 args = ap.parse_args()
28
29 tl = None
30 for name in ("tinyllama_bindings", "tinyllama_cpp"):
31 try:
32 mod = __import__(name)
33 if hasattr(mod, "TinyLlamaSession"):
34 tl = mod
35 break
36 except ImportError:
37 continue
38 if tl is None:
39 print("FAIL: no importable module exposing TinyLlamaSession "
40 "(build the bindings or pip install .)")
41 return 2
42
43 print(f"[1/3] loading {args.gguf} (CPU, n_gpu_layers=0)")
45
46 cfg = sess.get_config()
47 print(f"[2/3] config: arch={getattr(cfg, 'architecture', '?')} "
48 f"vocab={getattr(cfg, 'vocab_size', '?')} "
49 f"layers={getattr(cfg, 'num_hidden_layers', '?')} "
50 f"hidden={getattr(cfg, 'hidden_size', '?')}")
51
52 prompts = [
53 "once upon a time there was a little",
54 "the cat sat on the",
55 "tom and lily went to the park to",
56 ]
57 failures = []
58 print(f"[3/3] generating {args.steps} tokens per prompt (greedy-ish, temp 0.1)")
59 for p in prompts:
60 out = sess.generate(p, steps=args.steps, temperature=0.1, top_k=40, top_p=0.9)
61 words = out.split()
62 degenerate = len(words) >= 6 and len(set(words[-6:])) == 1
63 status = "OK"
64 if not words:
65 status = "EMPTY"
66 failures.append((p, out))
67 elif degenerate:
68 status = "DEGENERATE (single-token loop)"
69 failures.append((p, out))
70 print(f" prompt : {p}\n output : {out!r}\n status : {status}\n")
71
72 if failures:
73 print(f"RESULT: {len(failures)}/{len(prompts)} prompts failed sanity checks")
74 return 1
75 print("RESULT: engine runs the transformer_cpp GGUF — all sanity checks passed")
76 return 0
77
78
79if __name__ == "__main__":
80 sys.exit(main())
size_t j