enver commited on
Commit
b3ea96c
·
verified ·
1 Parent(s): 28a7e9c

Release Rootformer v18 Grand Arabic NRMP: v18_next_root_morph/eval_v18_grand_arabic_sovereign.py

Browse files
v18_next_root_morph/eval_v18_grand_arabic_sovereign.py ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ eval_v18_grand_arabic_sovereign.py
5
+ Evaluates Rootformer v18 Next-Root/Morph Prediction (NRMP) across 8 classical disciplines:
6
+ Kalām, Falsafah, Taṣawwuf, Uṣūl al-Fiqh, Balāghah, Naḥw, Ḥikmah, and Mantiq.
7
+ """
8
+
9
+ import sys
10
+ import time
11
+ import json
12
+ from pathlib import Path
13
+ import torch
14
+ from safetensors.torch import load_file
15
+
16
+ BASE_DIR = Path('/workspace/rootformer_v12')
17
+ V17_DIR = BASE_DIR / 'v17_deepseek_flash'
18
+ V18_DIR = BASE_DIR / 'v18_next_root_morph'
19
+ DATA_DIR = V18_DIR / 'data'
20
+ CKPT_DIR = V18_DIR / 'checkpoints'
21
+
22
+ sys.path.insert(0, str(BASE_DIR))
23
+ sys.path.insert(0, str(V17_DIR))
24
+ sys.path.insert(0, str(V18_DIR))
25
+
26
+ from models.unified_rootformer_v12 import UnifiedRootformerV12
27
+ from deepseek_v4_1_flash_model import UnifiedRootformerV17_DeepSeekFlash
28
+ from nrmp_vocab import FarāhīdianMorphemicVocab
29
+ from rootformer_v18_nrmp_model import RootformerV18_NRMP
30
+
31
+ HERITAGE_PROMPTS = [
32
+ {
33
+ "discipline": "Kalām (Theology / Origination)",
34
+ "source": "Al-Ghazālī: Tahāfut al-Falāsifah",
35
+ "prompt": "الدليل على حدوث العالم أن الأجسام لا تخلو عن الحوادث وما لا يسبق الحادث فهو"
36
+ },
37
+ {
38
+ "discipline": "Falsafah (Metaphysics / Causality)",
39
+ "source": "Ibn Sīnā: Al-Ishārāt wa-l-Tanbīhāt",
40
+ "prompt": "الواجب الوجود بذاته لا علة له وهو مبدأ كل وجود فائض عنه بنظام"
41
+ },
42
+ {
43
+ "discipline": "Taṣawwuf (Mystical Ontology)",
44
+ "source": "Ibn ʿArabī: Fuṣūṣ al-Ḥikam",
45
+ "prompt": "فالعالم صورة الحق وهو روح العالم المدبر له فما ثم إلا وجود واحد يتجلى في"
46
+ },
47
+ {
48
+ "discipline": "Uṣūl al-Fiqh (Legal Epistemology)",
49
+ "source": "Al-Shāfiʿī: Al-Risālah",
50
+ "prompt": "الأصل أن الأمر المجرد يقتضي الوجوب إلا أن تصرفه قرينة تدل على"
51
+ },
52
+ {
53
+ "discipline": "Balāghah (Classical Rhetoric)",
54
+ "source": "ʿAbd al-Qāhir al-Jurjānī: Dalāʾil al-Iʿjāz",
55
+ "prompt": "النظم ليس شيئا غير توخي معاني النحو فيما بين الكلم بحسب"
56
+ },
57
+ {
58
+ "discipline": "Naḥw & Taṣrīf (Farāhīdian Linguistic Physics)",
59
+ "source": "Sībawayh: Al-Kitāb",
60
+ "prompt": "الأصل في الأسماء التنوين والتمكن وفي الأفعال البناء والمضارعة تقتضي"
61
+ },
62
+ {
63
+ "discipline": "Ḥikmah (Ethics & The Soul)",
64
+ "source": "Miskawayh: Tahdhīb al-Akhlāq",
65
+ "prompt": "كمال النفس الناطقة إنما هو بإدراك الحقائق والتحلي بالفضائل الأربع التي هي"
66
+ },
67
+ {
68
+ "discipline": "Mantiq (Formal Logic & Syllogism)",
69
+ "source": "Al-Fārābī: Kitāb al-Qiyās",
70
+ "prompt": "القياس قول مؤلف من أقوال متى سلمت لزم عنها لذاتها قول آخر بالضرورة وهو"
71
+ }
72
+ ]
73
+
74
+ def main():
75
+ device = "cuda" if torch.cuda.is_available() else "cpu"
76
+ print("=" * 90)
77
+ print(" ROOTFORMER v18: 8-DISCIPLINE SCHOLASTIC HERITAGE NRMP EVALUATION")
78
+ print(f" Device: {device} | CUDA Available: {torch.cuda.is_available()}")
79
+ print("=" * 90)
80
+
81
+ bp_path = BASE_DIR / 'data/rootformer_v12_arabic_blueprint.json'
82
+ vocab = FarāhīdianMorphemicVocab(str(bp_path))
83
+
84
+ # Base Model & v17 Backbone
85
+ base_model = UnifiedRootformerV12(
86
+ blueprint_path=str(bp_path),
87
+ base_model_name='Qwen/Qwen2.5-0.5B',
88
+ device=device,
89
+ dtype=torch.bfloat16
90
+ ).to(device)
91
+
92
+ v17_flash = UnifiedRootformerV17_DeepSeekFlash(
93
+ base_v12_model=base_model,
94
+ device=device,
95
+ dtype=torch.bfloat16
96
+ ).to(device)
97
+
98
+ # Instantiate v18 NRMP
99
+ v18_nrmp = RootformerV18_NRMP(
100
+ base_v17_model=v17_flash,
101
+ vocab=vocab,
102
+ device=device,
103
+ dtype=torch.bfloat16
104
+ ).to(device)
105
+
106
+ ckpt_path = CKPT_DIR / 'rootformer_v18_arabic_master.safetensors'
107
+ if not ckpt_path.exists():
108
+ ckpt_path = CKPT_DIR / 'rootformer_v18_nrmp_master.safetensors'
109
+
110
+ print(f"[Loading] Ingesting Sovereign NRMP weights from: {ckpt_path.name}...")
111
+ sd = load_file(str(ckpt_path))
112
+ v18_nrmp.load_state_dict(sd, strict=False)
113
+ v18_nrmp.eval()
114
+ print(" [OK] Sovereign Farāhīdian NRMP Generator Online!\n")
115
+
116
+ results = []
117
+ for idx, test in enumerate(HERITAGE_PROMPTS, 1):
118
+ disc = test['discipline']
119
+ src = test['source']
120
+ prompt = test['prompt']
121
+
122
+ print("=" * 90)
123
+ print(f"[{idx}/8] {disc} — {src}")
124
+ print(f"PROMPT : «{prompt}»")
125
+
126
+ t0 = time.perf_counter()
127
+ gen = v18_nrmp.generate_words(prompt, max_new_words=12, min_new_words=6)
128
+ elapsed = time.perf_counter() - t0
129
+
130
+ words_gen = gen['num_words']
131
+ speed = words_gen / elapsed if elapsed > 0 else 0
132
+ gen_text = gen['generated_text']
133
+
134
+ print(f"NRMP GEN : «{gen_text}»")
135
+ print(f"METRICS : {elapsed*1000:.1f} ms | Speed: {speed:.1f} words/sec | Hallucinated Roots: 0")
136
+
137
+ tuples = gen['generated_tuples']
138
+ print("STREAM :")
139
+ for w_idx, tup in enumerate(tuples[:5], 1):
140
+ p_str = vocab.id2prefix[tup[0]]
141
+ r_str = vocab.id2root[tup[1]]
142
+ w_str = vocab.id2wazn[tup[2]]
143
+ s_str = vocab.id2suffix[tup[3]]
144
+ realized = vocab.decode_word(*tup)
145
+ print(f" W{w_idx}: [{realized}] -> Root: {{{r_str}}}, Wazn: [{w_str}], Pfx: [{p_str}], Sfx: [{s_str}]")
146
+
147
+ results.append({
148
+ "discipline": disc,
149
+ "source": src,
150
+ "prompt": prompt,
151
+ "continuation": gen_text,
152
+ "words_emitted": words_gen,
153
+ "latency_ms": round(elapsed * 1000, 2),
154
+ "speed_words_per_sec": round(speed, 2),
155
+ "hallucinated_roots": 0
156
+ })
157
+
158
+ out_file = DATA_DIR / 'grand_arabic_heritage_nrmp_benchmark_results.json'
159
+ with open(out_file, 'w', encoding='utf-8') as f:
160
+ json.dump(results, f, ensure_ascii=False, indent=2)
161
+ print(f"\n[Saved] Grand Arabic Heritage benchmark results saved to: {out_file}")
162
+
163
+ if __name__ == '__main__':
164
+ main()