Ouaill commited on
Commit
0cadf33
·
verified ·
1 Parent(s): 7fbcaf7

Upload eval_darijabert_mix.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. eval_darijabert_mix.py +132 -0
eval_darijabert_mix.py ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3 -u
2
+ """eval_darijabert_mix.py — Evaluate DarijaBERT-mix on the same test set and append to external_comparison.csv."""
3
+
4
+ import json, os, csv, gc, warnings
5
+ from dataclasses import dataclass, asdict
6
+
7
+ import numpy as np
8
+ import regex
9
+ warnings.filterwarnings("ignore")
10
+
11
+ BASE = "/root/oiq_cc_tokenizer/results"
12
+ CORPORA = os.path.join(BASE, "corpora")
13
+ PLOTS_DIR = os.path.join(BASE, "plots")
14
+
15
+ HF_TOKEN = os.environ.get("HF_TOKEN", "")
16
+
17
+ _WORD_PAT = regex.compile(r"[\p{L}\p{M}\p{N}]+", regex.UNICODE)
18
+ _AR_PAT = regex.compile(r"[\u0600-\u06FF\u0750-\u077F]")
19
+ _SPECIAL = {"<unk>", "<s>", "</s>", "[CLS]", "[SEP]", "[PAD]", "[UNK]", "<pad>",
20
+ "<|endoftext|>", "<|im_start|>", "<|im_end|>"}
21
+
22
+ def segment_words(t): return _WORD_PAT.findall(t)
23
+ def count_graphemes(t): return len(regex.findall(r"\X", t))
24
+ def detect_script(t): return "ar" if len(_AR_PAT.findall(t)) > len(t) * 0.3 else "az"
25
+ def filter_sp(tokens): return [t for t in tokens if t not in _SPECIAL]
26
+ def normalize_decode(s):
27
+ s = s.replace("##", "")
28
+ s = " ".join(s.split())
29
+ return s
30
+
31
+
32
+ @dataclass
33
+ class M:
34
+ name: str = ""
35
+ source: str = ""
36
+ algorithm: str = ""
37
+ architecture: str = ""
38
+ vocab_size: int = 0
39
+ fertility_ar: float = 0.0
40
+ fertility_az: float = 0.0
41
+ fertility_overall: float = 0.0
42
+ disparity: float = 0.0
43
+ cpt_ar: float = 0.0
44
+ cpt_az: float = 0.0
45
+ exact_match_ar: float = 0.0
46
+ exact_match_az: float = 0.0
47
+
48
+
49
+ def evaluate(tok, name, source, algo, arch, vsz, texts):
50
+ m = M(name=name, source=source, algorithm=algo, architecture=arch, vocab_size=vsz)
51
+ ar_f, az_f, all_f = [], [], []
52
+ ar_c, az_c = [], []
53
+ ar_ok, az_ok, ar_n, az_n = 0, 0, 0, 0
54
+
55
+ for i, text in enumerate(texts):
56
+ if (i + 1) % 5000 == 0:
57
+ print(f" [{i+1}/{len(texts)}] {name}", flush=True)
58
+ try:
59
+ ids = tok.encode(text, add_special_tokens=False)
60
+ tokens = tok.convert_ids_to_tokens(ids)
61
+ content = filter_sp(tokens)
62
+ words = segment_words(text)
63
+ if not words:
64
+ continue
65
+ fert = len(content) / len(words)
66
+ all_f.append(fert)
67
+ cpt = count_graphemes(text) / max(len(content), 1)
68
+ try:
69
+ dec = tok.decode(ids, skip_special_tokens=True)
70
+ exact = normalize_decode(dec) == normalize_decode(text)
71
+ except:
72
+ exact = False
73
+ script = detect_script(text)
74
+ if script == "ar":
75
+ ar_f.append(fert); ar_c.append(cpt); ar_n += 1
76
+ if exact: ar_ok += 1
77
+ else:
78
+ az_f.append(fert); az_c.append(cpt); az_n += 1
79
+ if exact: az_ok += 1
80
+ except:
81
+ pass
82
+
83
+ m.fertility_ar = float(np.mean(ar_f)) if ar_f else 0
84
+ m.fertility_az = float(np.mean(az_f)) if az_f else 0
85
+ m.fertility_overall = float(np.mean(all_f)) if all_f else 0
86
+ mx = max(m.fertility_ar, m.fertility_az, 1e-9)
87
+ m.disparity = abs(m.fertility_ar - m.fertility_az) / mx
88
+ m.cpt_ar = float(np.mean(ar_c)) if ar_c else 0
89
+ m.cpt_az = float(np.mean(az_c)) if az_c else 0
90
+ m.exact_match_ar = ar_ok / max(ar_n, 1)
91
+ m.exact_match_az = az_ok / max(az_n, 1)
92
+ return m
93
+
94
+
95
+ def main():
96
+ from transformers import AutoTokenizer
97
+
98
+ # Load test texts
99
+ texts = []
100
+ for s in ("test_ar", "test_az", "test_mi"):
101
+ p = os.path.join(CORPORA, f"{s}.txt")
102
+ if os.path.exists(p):
103
+ with open(p) as f:
104
+ texts.extend(l.strip() for l in f if l.strip())
105
+ print(f"{len(texts)} test texts", flush=True)
106
+
107
+ # Load DarijaBERT-mix
108
+ repo = "SI2M-Lab/DarijaBERT-mix"
109
+ print(f"\nLoading {repo} ...", flush=True)
110
+ tok = AutoTokenizer.from_pretrained(repo, trust_remote_code=True)
111
+ vsz = tok.vocab_size
112
+ print(f" vocab_size = {vsz}", flush=True)
113
+
114
+ # Evaluate
115
+ print(f"\nEvaluating DarijaBERT-mix ...", flush=True)
116
+ r = evaluate(tok, "DarijaBERT-mix", "external_darija", "WordPiece", "shared", vsz, texts)
117
+ print(f" F={r.fertility_overall:.3f} F_ar={r.fertility_ar:.3f} F_az={r.fertility_az:.3f}", flush=True)
118
+ print(f" D={r.disparity:.3f} CPT_ar={r.cpt_ar:.3f} CPT_az={r.cpt_az:.3f}", flush=True)
119
+ print(f" EM_ar={r.exact_match_ar:.2%} EM_az={r.exact_match_az:.2%}", flush=True)
120
+
121
+ # Append to external_comparison.csv
122
+ csv_path = os.path.join(BASE, "external_comparison.csv")
123
+ with open(csv_path, "a", newline="") as f:
124
+ w = csv.DictWriter(f, fieldnames=list(asdict(r).keys()))
125
+ w.writerow(asdict(r))
126
+ print(f"\nAppended to {csv_path}", flush=True)
127
+
128
+ print("DONE!", flush=True)
129
+
130
+
131
+ if __name__ == "__main__":
132
+ main()