adyoi commited on
Commit
b05971d
·
verified ·
1 Parent(s): d6b45dd

Upload eval.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. eval.py +95 -0
eval.py ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import argparse
2
+ import time
3
+ from pathlib import Path
4
+
5
+ import torch
6
+
7
+ from indigo.common import (
8
+ build_tokenizer,
9
+ load_meta,
10
+ load_wordlist,
11
+ read_clean,
12
+ word_known_ratio,
13
+ )
14
+ from indigo.model import GPT, GPTConfig
15
+
16
+
17
+ def muat(path):
18
+ from safetensors.torch import load_file
19
+
20
+ meta = load_meta(path)
21
+ model = GPT(GPTConfig(**meta["config"]))
22
+ missing, unexpected = model.load_state_dict(load_file(path), strict=False)
23
+ if missing or unexpected:
24
+ raise SystemExit(f"bobot tidak cocok untuk {path}: {missing[:3]} {unexpected[:3]}")
25
+ model.eval()
26
+ tokenizer = build_tokenizer(meta.get("tokenizer") or {"type": "char"}, meta.get("vocab"))
27
+ return model, tokenizer, meta
28
+
29
+
30
+ @torch.no_grad()
31
+ def nats_per_token(model, ids, block_size, device):
32
+ total_nll = 0.0
33
+ total_tok = 0
34
+ for i in range(0, max(0, len(ids) - 1), block_size):
35
+ potongan = ids[i : i + block_size + 1]
36
+ if len(potongan) < 2:
37
+ break
38
+ x = torch.tensor([potongan[:-1]], dtype=torch.long, device=device)
39
+ y = torch.tensor([potongan[1:]], dtype=torch.long, device=device)
40
+ logits, _ = model(x)
41
+ logp = torch.log_softmax(logits[0].float(), dim=-1)
42
+ total_nll += float(-logp[torch.arange(len(y[0])), y[0]].sum())
43
+ total_tok += len(potongan) - 1
44
+ return total_nll / max(1, total_tok), total_tok
45
+
46
+
47
+ def main():
48
+ ap = argparse.ArgumentParser(
49
+ description="Skor checkpoint pada set uji tetap agar antar-run dapat dibandingkan"
50
+ )
51
+ ap.add_argument("--ckpt", nargs="+", required=True)
52
+ ap.add_argument("--test", default="data/sample.txt")
53
+ ap.add_argument("--device", default="cpu", choices=["cpu", "cuda"])
54
+ ap.add_argument("--guard", default=None, help="kamus opsional untuk metrik rasio ejaan")
55
+ ap.add_argument("--seed", type=int, default=42)
56
+ args = ap.parse_args()
57
+
58
+ teks = read_clean(args.test)
59
+ n_karakter = len(teks.encode("utf-8"))
60
+ wordset = prefiks = sufiks = None
61
+ if args.guard:
62
+ root = Path(__file__).resolve().parent
63
+ wordset = load_wordlist(args.guard)
64
+ p, s = root / "data" / "prefiks.txt", root / "data" / "sufiks.txt"
65
+ prefiks = load_wordlist(str(p)) if p.exists() else None
66
+ sufiks = load_wordlist(str(s)) if s.exists() else None
67
+
68
+ print(f"set uji: {args.test} ({n_karakter:,} karakter)")
69
+ print(f"{'checkpoint':44s} {'nats/tok':>9s} {'nat/kar':>8s} {'kamus':>7s}")
70
+ baris = []
71
+ for path in args.ckpt:
72
+ model, tokenizer, meta = muat(path)
73
+ ids = tokenizer.encode(teks)
74
+ npt, n_tok = nats_per_token(model, ids, meta["config"]["block_size"], args.device)
75
+ kompresi = n_karakter / max(1, n_tok)
76
+ npc = npt / kompresi
77
+ rasio = ""
78
+ if wordset:
79
+ t0 = time.time()
80
+ out = model.generate(
81
+ torch.tensor([[0]], dtype=torch.long, device=args.device),
82
+ 120,
83
+ temperature=0.8,
84
+ top_k=40,
85
+ )
86
+ del t0
87
+ teks_out = tokenizer.decode(out[0].tolist())
88
+ rasio = f"{word_known_ratio(teks_out, wordset, prefiks, sufiks):6.0%}"
89
+ nama = Path(path).parent.parent.name + "/" + Path(path).name
90
+ print(f"{nama:44s} {npt:9.3f} {npc:8.3f} {rasio:>7s}")
91
+ baris.append({"ckpt": str(path), "nats_per_token": round(npt, 4), "nats_per_char": round(npc, 4)})
92
+
93
+
94
+ if __name__ == "__main__":
95
+ main()