abdelkader-dev commited on
Commit
024fb70
·
verified ·
1 Parent(s): b953c16

Upload 8 files

Browse files
interface.py ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import torch
3
+ from transformers import PreTrainedTokenizerFast, GPT2LMHeadModel
4
+
5
+ class ModelRunner:
6
+ def __init__(self, model_dir="./math_gpt3_final"):
7
+ """
8
+ تهيئة مفسر الرموز والنموذج من المجلد المحفوظ.
9
+ """
10
+ if not os.path.exists(model_dir):
11
+ raise FileNotFoundError(f"المجلد {model_dir} غير موجود. تأكد من مسار الحفظ الصحيح.")
12
+
13
+ print(f"جاري تحميل النموذج من: {model_dir} ...")
14
+ self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
15
+
16
+ # تحميل الـ Tokenizer والنموذج
17
+ self.tokenizer = PreTrainedTokenizerFast.from_pretrained(model_dir)
18
+ self.model = GPT2LMHeadModel.from_pretrained(model_dir).to(self.device)
19
+ self.model.eval() # وضع النموذج في طور التشغيل/التقييم
20
+
21
+ print(f"تم تحميل النموذج بنجاح على جهاز: {self.device}\n")
22
+
23
+ def predict(self, prompt, max_new_tokens=1024, temperature=0.6):
24
+ """
25
+ تأخذ السؤال وتُرجع الحل فقط بدون تكرار السؤال.
26
+ """
27
+ # إضافة رمز البداية إذا لم يكن موجوداً
28
+ if "<ans>" not in prompt:
29
+ prompt = prompt + "<ans>"
30
+
31
+ input_ids = self.tokenizer.encode(prompt, return_tensors="pt").to(self.device)
32
+
33
+ # نستخدم طريقتين للتوليد:
34
+ # إذا كان الـ temperature منخفض جداً نستخدم Greedy Search لضمان الدقة الحسابية العالية
35
+ with torch.no_grad():
36
+ output_ids = self.model.generate(
37
+ input_ids=input_ids,
38
+ max_new_tokens=max_new_tokens,
39
+ do_sample=True if temperature > 0 else False,
40
+ temperature=temperature if temperature > 0 else None,
41
+ eos_token_id=self.tokenizer.eos_token_id,
42
+ pad_token_id=self.tokenizer.pad_token_id,
43
+ top_p=0.9 if temperature > 0 else None
44
+ )
45
+
46
+ # فك التشفير
47
+ full_tokens = self.tokenizer.convert_ids_to_tokens(output_ids[0])
48
+ full_text = "".join(full_tokens)
49
+
50
+ # تنظيف المخرج لعزل الإجابة فقط
51
+ if "<ans>" in full_text:
52
+ answer = full_text.split("<ans>")[1]
53
+ else:
54
+ answer = full_text
55
+
56
+ # إزالة الـ <eos> والـ <pad> من النهاية لجمالية المخرج
57
+ answer = answer.replace("<eos>", "").replace("<pad>", "").strip()
58
+ return answer
59
+
60
+ # ==========================================
61
+ # تجربة تشغيل البرنامج كملف مستقل لتجربته فوراً
62
+ # ==========================================
63
+ if __name__ == "__main__":
64
+ # يمكنك تغيير المسار إلى مجلد النموذج الحالي لديك لتجربته
65
+ # مثلاً: "./math_gpt3_final"
66
+ try:
67
+ runner = ModelRunner(model_dir="./math_gpt3_final")
68
+
69
+ print("--- برنامج حل المعادلات من الدرجة الثانية ---")
70
+ print("اكتب 'exit' للخروج من البرنامج.\n")
71
+
72
+ while True:
73
+ user_input = input("أدخل المعادلة (مثال: 1x²-5x+6=0): ")
74
+ if user_input.lower() == 'exit':
75
+ break
76
+
77
+ if not user_input.strip():
78
+ continue
79
+
80
+ # تشغيل النموذج
81
+ solution = runner.predict(user_input, temperature=0.1)
82
+ print(f"🤖 الحل المشتق من النموذج:\n{solution}")
83
+ print("-" * 40)
84
+
85
+ except Exception as e:
86
+ print(f"حدث خطأ: {e}")
main_gpt3.py ADDED
@@ -0,0 +1,273 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+ import math
3
+ import torch
4
+ from torch.utils.data import Dataset
5
+ from sympy import symbols, expand
6
+ from tokenizers import Tokenizer, models, pre_tokenizers, decoders
7
+ from transformers import (
8
+ GPT2Config, GPT2LMHeadModel,
9
+ PreTrainedTokenizerFast,
10
+ Trainer, TrainingArguments,
11
+ DataCollatorForLanguageModeling
12
+ )
13
+
14
+ # =========================
15
+ # 1. DATA GENERATION
16
+ # =========================
17
+
18
+ x = symbols("x")
19
+
20
+ def generate_data_with_steps(n=25000):
21
+ data = []
22
+
23
+ while len(data) < n:
24
+ # 1. اختيار المعاملات عشوائياً (لتجنب التعقيد سنركز على المعاملات التي تعطيك دلتا موجب)
25
+ a = random.choice([-5, -4, -3, -2, -1, 1, 2, 3, 4, 5])
26
+ b = random.randint(-15, 15)
27
+ c = random.randint(-15, 15)
28
+
29
+ # حساب الدلتا حاسوبياً أولاً للتحقق
30
+ delta = b**2 - 4*a*c
31
+
32
+ # سنكتفي حالياً بالمعادلات التي تملك حلولاً حقيقية (delta >= 0) لتسهيل التعلم على النموذج
33
+ if delta < 0:
34
+ continue
35
+
36
+ sqrt_d = math.sqrt(delta)
37
+
38
+ # حساب الجذور وتقريبها لمرتبة عشرية واحدة أو اثنتين لتسهيل النص
39
+ x1 = round((-b + sqrt_d) / (2 * a), 2)
40
+ x2 = round((-b - sqrt_d) / (2 * a), 2)
41
+
42
+ # 2. صياغة السؤال (المعالمة) بشكل نظيف مع الإشارات
43
+ # استخدام b:+ و c:+ يضمن ظهور إشارة الزائد تلقائياً للأعداد الموجبة
44
+ question = f"{a}x²{b:+}x{c:+}=0"
45
+
46
+ # 3. صياغة "خطوات الحل التفصيلية" (Chain of Thought)
47
+ # سنقسمها إلى خطوات واضحة يفهم النموذج تتابعها المنطقي
48
+ step_a_b_c = f"a={a};b={b};c={c}"
49
+
50
+ # خطوة حساب الدلتا: القانون -> التعويض -> الناتج النهائي
51
+ step_delta = f"d=({b})²-4*({a})*({c})={b**2}-({4*a*c})={delta}"
52
+
53
+ # خطوة حساب الجذور بالتفصيل
54
+ if delta > 0:
55
+ step_roots = f"x1=(-({b})+{round(sqrt_d, 2)})/(2*{a})={x1};x2=(-({b})-{round(sqrt_d, 2)})/(2*{a})={x2}"
56
+ else: # delta == 0
57
+ step_roots = f"x1=x2=-({b})/(2*{a})={x1}"
58
+
59
+ # دمج كل الخطوات بفواصل واضحة (مثلاً استخدام كلمة step أو رموز ثابتة)
60
+ answer = f"{step_a_b_c}|step1:{step_delta}|step2:{step_roots}<eos>"
61
+
62
+ # إضافة السلسلة الكاملة للنص
63
+ data.append(question + "<ans>" + answer)
64
+
65
+ return data
66
+
67
+ # معاينة سريعة لشكل البيانات الجديدة
68
+ texts = generate_data_with_steps(n=3)
69
+ for text in texts:
70
+ print(text)
71
+ print("-" * 50)
72
+
73
+ texts = generate_data_with_steps(n=25000) # <--- هذا السطر الذي كان ينقصك!
74
+ # =========================
75
+ # 2. BUILD TOKENIZER
76
+ # =========================
77
+
78
+ special_tokens = ["<pad>", "<eos>", "<ans>"]
79
+
80
+ # Collect all characters and special tokens
81
+ chars = set()
82
+ for t in texts:
83
+ chars.update(list(t))
84
+ chars.update(special_tokens)
85
+ chars = sorted(chars)
86
+
87
+ # Create vocabulary mapping
88
+ vocab = {c: i for i, c in enumerate(chars)}
89
+
90
+ # Build a WordLevel tokenizer with this vocab
91
+ base_tokenizer = Tokenizer(models.WordLevel(vocab, unk_token=None))
92
+ base_tokenizer.pre_tokenizer = pre_tokenizers.Split("", behavior="removed") # character-level
93
+
94
+
95
+ # Wrap into PreTrainedTokenizerFast
96
+ tokenizer = PreTrainedTokenizerFast(
97
+ tokenizer_object=base_tokenizer,
98
+ pad_token="<pad>",
99
+ eos_token="<eos>",
100
+ unk_token=None,
101
+ additional_special_tokens=["<ans>"]
102
+ )
103
+
104
+ # Add special tokens (they already exist, but ensures proper config)
105
+ tokenizer.add_special_tokens({"pad_token": "<pad>", "eos_token": "<eos>", "additional_special_tokens": ["<ans>"]})
106
+
107
+ PAD_IDX = tokenizer.pad_token_id
108
+ EOS_IDX = tokenizer.eos_token_id
109
+ VOCAB_SIZE = tokenizer.vocab_size
110
+
111
+ print(f"Vocabulary size: {VOCAB_SIZE}")
112
+ print(f"PAD ID: {PAD_IDX}, EOS ID: {EOS_IDX}")
113
+
114
+ # Quick test
115
+ test_enc = tokenizer.encode("1x²-5x+6=0<ans>")
116
+ print("Encoded tokens:", tokenizer.convert_ids_to_tokens(test_enc))
117
+ print("Decoded:", tokenizer.decode(test_enc))
118
+
119
+ # =========================
120
+ # 3. DATASET
121
+ # =========================
122
+
123
+ class MathDataset(Dataset):
124
+ def __init__(self, texts, tokenizer, max_length=128):
125
+ self.texts = texts
126
+ self.tokenizer = tokenizer
127
+ self.max_length = max_length
128
+
129
+ def __len__(self):
130
+ return len(self.texts)
131
+
132
+ def __getitem__(self, idx):
133
+ text = self.texts[idx]
134
+ encoding = self.tokenizer(
135
+ text,
136
+ truncation=True,
137
+ max_length=self.max_length,
138
+ padding="max_length",
139
+ return_tensors="pt"
140
+ )
141
+ input_ids = encoding["input_ids"].squeeze(0)
142
+ labels = input_ids.clone()
143
+
144
+ # استبدال معرف الـ pad بـ -100 لحجبه عن الـ Loss
145
+ labels[labels == self.tokenizer.pad_token_id] = -100
146
+
147
+ return {"input_ids": input_ids, "labels": labels}
148
+
149
+ dataset = MathDataset(texts, tokenizer, max_length=128)
150
+
151
+ # =========================
152
+ # 4. MODEL
153
+ # =========================
154
+
155
+ config = GPT2Config(
156
+ vocab_size=VOCAB_SIZE,
157
+ n_positions=128,
158
+ n_embd=512,
159
+ n_layer=6,
160
+ n_head=8,
161
+ pad_token_id=PAD_IDX,
162
+ eos_token_id=EOS_IDX,
163
+ bos_token_id=None,
164
+ n_inner=1024
165
+ )
166
+
167
+ model = GPT2LMHeadModel(config)
168
+ print(f"Model parameters: {model.num_parameters()}")
169
+
170
+ # =========================
171
+ # 5. TRAINING (بدون overwrite_output_dir)
172
+ # =========================
173
+
174
+ training_args = TrainingArguments(
175
+ output_dir="./math_gpt3",
176
+ num_train_epochs=8,
177
+ per_device_train_batch_size=32,
178
+ learning_rate=2e-4,
179
+ weight_decay=0.01,
180
+ warmup_steps=500,
181
+ logging_steps=100,
182
+ save_steps=500,
183
+ save_total_limit=2,
184
+ fp16=torch.cuda.is_available(),
185
+ report_to="none",
186
+ remove_unused_columns=False,
187
+ )
188
+
189
+ data_collator = DataCollatorForLanguageModeling(
190
+ tokenizer=tokenizer,
191
+ mlm=False
192
+ )
193
+
194
+ trainer = Trainer(
195
+ model=model,
196
+ args=training_args,
197
+ train_dataset=dataset,
198
+ data_collator=data_collator,
199
+ )
200
+
201
+ print("Starting training...")
202
+ trainer.train()
203
+
204
+ # Save model
205
+ trainer.save_model("./math_gpt3_final")
206
+ tokenizer.save_pretrained("./math_gpt3_final")
207
+
208
+ # =========================
209
+ # 6. GENERATION
210
+ # =========================
211
+
212
+ def generate(prompt, max_new_tokens=60, temperature=0.7):
213
+ model.eval()
214
+ input_ids = tokenizer.encode(prompt, return_tensors="pt").to(model.device)
215
+ output_ids = model.generate(
216
+ input_ids=input_ids,
217
+ max_new_tokens=max_new_tokens,
218
+ do_sample=True,
219
+ temperature=temperature,
220
+ eos_token_id=EOS_IDX,
221
+ pad_token_id=PAD_IDX,
222
+ top_k=0,
223
+ top_p=0.9
224
+ )
225
+ # فك التشفير يدوياً دون مسافات
226
+ tokens = tokenizer.convert_ids_to_tokens(output_ids[0])
227
+ text = "".join(tokens) # يدمج الحروف كما هي
228
+ return text
229
+
230
+ # =========================
231
+ # 7. TEST
232
+ # =========================
233
+
234
+ print("\nGenerated:")
235
+ print(generate("2x²+3x-2=0<ans>"))
236
+
237
+ # =========================
238
+ # اختبارات جاهزة بعد التدريب
239
+ # =========================
240
+
241
+ test_prompts = [
242
+ # معادلات بسيطة (a=1)
243
+ "1x²-5x+6=0<ans>", # x1=2, x2=3
244
+ "1x²+0x-4=0<ans>", # x1=2, x2=-2
245
+ "1x²-7x+12=0<ans>", # x1=3, x2=4
246
+ "1x²+3x+2=0<ans>", # x1=-1, x2=-2
247
+
248
+ # معادلات بمعامل a ≠ 1
249
+ "2x²-5x+2=0<ans>", # x1=2, x2=0.5 (أو كسور)
250
+ "3x²-7x+2=0<ans>", # x1=2, x2=1/3
251
+ "4x²-4x+1=0<ans>", # x1=0.5, x2=0.5 (جذر مزدوج)
252
+
253
+ # معادلات بمعامل سالب
254
+ "-1x²+5x-6=0<ans>", # نفس جذور x²-5x+6 لكن بإشارة معكوسة
255
+ "-2x²+8x-6=0<ans>", # x1=1, x2=3
256
+
257
+ # حالة المميز صفر
258
+ "1x²-4x+4=0<ans>", # x1=2, x2=2
259
+
260
+ # معادلات عشوائية إضافية
261
+ "1x²-3x+2=0<ans>", # x1=1, x2=2
262
+ "2x²+3x-2=0<ans>", # x1=0.5, x2=-2 (اختبارك السابق)
263
+ ]
264
+
265
+ print("=" * 60)
266
+ print("اختبار النموذج على معادلات متنوعة:")
267
+ print("=" * 60)
268
+
269
+ for prompt in test_prompts:
270
+ generated = generate(prompt, max_new_tokens=120, temperature=0.7)
271
+ print(f"\nالمدخل: {prompt}")
272
+ print(f"المخرج: {generated}")
273
+ print("-" * 60)
math_gpt2_final/config.json ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "activation_function": "gelu_new",
3
+ "add_cross_attention": false,
4
+ "architectures": [
5
+ "GPT2LMHeadModel"
6
+ ],
7
+ "attn_pdrop": 0.1,
8
+ "bos_token_id": null,
9
+ "dtype": "float32",
10
+ "embd_pdrop": 0.1,
11
+ "eos_token_id": 21,
12
+ "initializer_range": 0.02,
13
+ "layer_norm_epsilon": 1e-05,
14
+ "model_type": "gpt2",
15
+ "n_embd": 512,
16
+ "n_head": 8,
17
+ "n_inner": 1024,
18
+ "n_layer": 6,
19
+ "n_positions": 128,
20
+ "pad_token_id": 22,
21
+ "reorder_and_upcast_attn": false,
22
+ "resid_pdrop": 0.1,
23
+ "scale_attn_by_inverse_layer_idx": false,
24
+ "scale_attn_weights": true,
25
+ "summary_activation": null,
26
+ "summary_first_dropout": 0.1,
27
+ "summary_proj_to_labels": true,
28
+ "summary_type": "cls_index",
29
+ "summary_use_proj": true,
30
+ "tie_word_embeddings": true,
31
+ "transformers_version": "5.10.2",
32
+ "use_cache": false,
33
+ "vocab_size": 38
34
+ }
math_gpt2_final/generation_config.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_from_model_config": true,
3
+ "eos_token_id": 21,
4
+ "output_attentions": false,
5
+ "output_hidden_states": false,
6
+ "pad_token_id": 22,
7
+ "transformers_version": "5.10.2",
8
+ "use_cache": true
9
+ }
math_gpt2_final/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f98ea302e62b9c491dd8b390aff3a09c9ea0828a3bf76b758eb1d07a4e3fb898
3
+ size 50818432
math_gpt2_final/tokenizer.json ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "version": "1.0",
3
+ "truncation": {
4
+ "direction": "Right",
5
+ "max_length": 128,
6
+ "strategy": "LongestFirst",
7
+ "stride": 0
8
+ },
9
+ "padding": {
10
+ "strategy": {
11
+ "Fixed": 128
12
+ },
13
+ "direction": "Right",
14
+ "pad_to_multiple_of": null,
15
+ "pad_id": 22,
16
+ "pad_type_id": 0,
17
+ "pad_token": "<pad>"
18
+ },
19
+ "added_tokens": [
20
+ {
21
+ "id": 20,
22
+ "content": "<ans>",
23
+ "single_word": false,
24
+ "lstrip": false,
25
+ "rstrip": false,
26
+ "normalized": false,
27
+ "special": true
28
+ },
29
+ {
30
+ "id": 21,
31
+ "content": "<eos>",
32
+ "single_word": false,
33
+ "lstrip": false,
34
+ "rstrip": false,
35
+ "normalized": false,
36
+ "special": true
37
+ },
38
+ {
39
+ "id": 22,
40
+ "content": "<pad>",
41
+ "single_word": false,
42
+ "lstrip": false,
43
+ "rstrip": false,
44
+ "normalized": false,
45
+ "special": true
46
+ }
47
+ ],
48
+ "normalizer": null,
49
+ "pre_tokenizer": {
50
+ "type": "Split",
51
+ "pattern": {
52
+ "String": ""
53
+ },
54
+ "behavior": "Removed",
55
+ "invert": false
56
+ },
57
+ "post_processor": {
58
+ "type": "TemplateProcessing",
59
+ "single": [
60
+ {
61
+ "Sequence": {
62
+ "id": "A",
63
+ "type_id": 0
64
+ }
65
+ }
66
+ ],
67
+ "pair": [
68
+ {
69
+ "Sequence": {
70
+ "id": "A",
71
+ "type_id": 0
72
+ }
73
+ },
74
+ {
75
+ "Sequence": {
76
+ "id": "B",
77
+ "type_id": 1
78
+ }
79
+ }
80
+ ],
81
+ "special_tokens": {}
82
+ },
83
+ "decoder": null,
84
+ "model": {
85
+ "type": "WordLevel",
86
+ "vocab": {
87
+ "(": 0,
88
+ ")": 1,
89
+ "*": 2,
90
+ "+": 3,
91
+ "-": 4,
92
+ ".": 5,
93
+ "/": 6,
94
+ "0": 7,
95
+ "1": 8,
96
+ "2": 9,
97
+ "3": 10,
98
+ "4": 11,
99
+ "5": 12,
100
+ "6": 13,
101
+ "7": 14,
102
+ "8": 15,
103
+ "9": 16,
104
+ ":": 17,
105
+ ";": 18,
106
+ "<": 19,
107
+ "<ans>": 20,
108
+ "<eos>": 21,
109
+ "<pad>": 22,
110
+ "=": 23,
111
+ ">": 24,
112
+ "a": 25,
113
+ "b": 26,
114
+ "c": 27,
115
+ "d": 28,
116
+ "e": 29,
117
+ "n": 30,
118
+ "o": 31,
119
+ "p": 32,
120
+ "s": 33,
121
+ "t": 34,
122
+ "x": 35,
123
+ "|": 36,
124
+ "²": 37
125
+ },
126
+ "unk_token": "<unk>"
127
+ }
128
+ }
math_gpt2_final/tokenizer_config.json ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "backend": "tokenizers",
3
+ "eos_token": "<eos>",
4
+ "extra_special_tokens": [
5
+ "<ans>"
6
+ ],
7
+ "model_max_length": 1000000000000000019884624838656,
8
+ "pad_token": "<pad>",
9
+ "tokenizer_class": "TokenizersBackend",
10
+ "unk_token": null
11
+ }
math_gpt2_final/training_args.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4da88ec270b42a4123c990ef99aa37f3c788b3094b3993bdf4409e424772f81a
3
+ size 5137