AhmedBenElsayedBenAhmed commited on
Commit
283d83a
·
1 Parent(s): 4205540
Files changed (1) hide show
  1. app.py +103 -41
app.py CHANGED
@@ -12,6 +12,7 @@ from flask import Flask, request, jsonify
12
  from flask_cors import CORS
13
  import threading, torch, json
14
  from datasets import Dataset
 
15
 
16
  # ===============================
17
  # 2️⃣ إعداد المتغيرات
@@ -33,7 +34,7 @@ device = "cuda" if torch.cuda.is_available() else "cpu"
33
  print("🔹 Using device:", device)
34
 
35
  # ===============================
36
- # 4️⃣ تحميل الموديل الأساسي بأمان
37
  # ===============================
38
  print("🔄 Loading base model...")
39
  tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
@@ -108,58 +109,129 @@ users_db = {
108
  @app.route("/generate", methods=["POST"])
109
  def generate():
110
  try:
111
- data = request.json
112
- prompt = data.get("prompt", "").strip()
113
  user_id = str(data.get("userId", "")).strip()
 
 
114
 
115
  user_info = users_db.get(user_id)
116
- if not user_info:
117
- return jsonify({"error": "User not found"}), 404
118
 
119
- user_name = user_info["name"]
 
120
 
 
 
 
121
  if current_dataset is None:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  return jsonify({
123
  "messages": [
124
- {"role": "assistant", "content": f"⚖️ أهلاً {user_name}! أنا زين، مساعدك الذكي. برجاء طرح سؤال قانوني."}
125
- ]
 
 
126
  })
127
 
128
- # Search in dataset
 
 
 
129
  for item in current_dataset:
130
- lines = item["text"].split("\n")
131
- for line in lines:
132
- if line.lower().startswith("user:") and prompt in line:
133
- response_messages = []
134
- for l in lines:
135
- if ":" in l:
136
- role, content = l.split(":", 1)
137
- response_messages.append({
138
- "role": role.strip().lower(),
139
- "content": content.strip()
140
- })
141
- response_messages.insert(0, {"role": "assistant", "content": f"أهلاً {user_name} 👋"})
142
- return jsonify({"messages": response_messages})
143
-
144
- # Fallback: generate
145
- inputs = tokenizer(prompt, return_tensors="pt").to(device)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  outputs = model.generate(
147
  **inputs,
148
- max_new_tokens=150,
149
- temperature=0.7,
150
- do_sample=True
 
 
 
151
  )
152
- reply = tokenizer.decode(outputs[0], skip_special_tokens=True)
 
153
 
154
  return jsonify({
155
  "messages": [
156
  {"role": "assistant", "content": f"أهلاً {user_name} 👋"},
157
  {"role": "assistant", "content": reply}
158
- ]
 
 
 
 
 
159
  })
160
 
161
  except Exception as e:
162
- return jsonify({"messages": [{"role": "assistant", "content": f"خطأ: {str(e)}"}]})
163
 
164
  # ===============================
165
  # 7b️⃣ تحميل الداتا
@@ -172,7 +244,6 @@ def load_dataset():
172
  data = json.load(f)
173
  except:
174
  data = []
175
-
176
  if data:
177
  formatted = []
178
  for item in data:
@@ -203,7 +274,6 @@ def train():
203
  epochs = 1
204
  batch_size = 1
205
 
206
- # 1️⃣ JSON مباشر
207
  if request.is_json:
208
  body = request.get_json()
209
  if isinstance(body, list):
@@ -215,8 +285,6 @@ def train():
215
 
216
  epochs = int(body.get("epochs", 1)) if isinstance(body, dict) else 1
217
  batch_size = int(body.get("batch_size", 1)) if isinstance(body, dict) else 1
218
-
219
- # 2️⃣ form-data ملف
220
  else:
221
  file = request.files.get("file")
222
  if file:
@@ -226,7 +294,6 @@ def train():
226
  else:
227
  return jsonify({"error": "No file uploaded or JSON provided"}), 400
228
 
229
- # دمج وإزالة التكرارات حسب محتوى الرسائل
230
  old_data = []
231
  if os.path.exists(DATASET_FILE):
232
  with open(DATASET_FILE, "r", encoding="utf-8") as f:
@@ -248,11 +315,9 @@ def train():
248
  seen_texts.add(text_key)
249
  unique_data.append(item)
250
 
251
- # الحفظ
252
  with open(DATASET_FILE, "w", encoding="utf-8") as f:
253
  json.dump(unique_data, f, ensure_ascii=False, indent=2)
254
 
255
- # تجهيز Dataset للتدريب
256
  formatted = []
257
  for item in unique_data:
258
  if "messages" in item:
@@ -262,7 +327,6 @@ def train():
262
  formatted.append({"text": conversation.strip()})
263
  elif "text" in item:
264
  formatted.append({"text": item["text"]})
265
-
266
  current_dataset = Dataset.from_list(formatted)
267
 
268
  def tokenize_function(examples):
@@ -282,7 +346,6 @@ def train():
282
 
283
  trainer = Trainer(model=model, args=training_args, train_dataset=tokenized_dataset)
284
 
285
- # تشغيل التدريب في Thread منفصل
286
  def run_training():
287
  print("🔄 Training started...")
288
  trainer.train()
@@ -301,7 +364,6 @@ def train():
301
  except Exception as e:
302
  return jsonify({"error": str(e)})
303
 
304
-
305
  # ===============================
306
  # 8️⃣ تشغيل Flask
307
  # ===============================
 
12
  from flask_cors import CORS
13
  import threading, torch, json
14
  from datasets import Dataset
15
+ import difflib
16
 
17
  # ===============================
18
  # 2️⃣ إعداد المتغيرات
 
34
  print("🔹 Using device:", device)
35
 
36
  # ===============================
37
+ # 4️⃣ تحميل الموديل الأساسي
38
  # ===============================
39
  print("🔄 Loading base model...")
40
  tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
 
109
  @app.route("/generate", methods=["POST"])
110
  def generate():
111
  try:
112
+ data = request.json or {}
113
+ prompt = str(data.get("prompt", "")).strip()
114
  user_id = str(data.get("userId", "")).strip()
115
+ focus_level = float(data.get("focus_level", 0.5))
116
+ n_examples = int(data.get("n_examples", 2))
117
 
118
  user_info = users_db.get(user_id)
119
+ user_name = user_info["name"] if user_info else "مستخدم"
 
120
 
121
+ if not prompt:
122
+ return jsonify({"messages": [{"role": "assistant", "content": "⚠️ الرجاء ارسال سؤال أو استفسار صحيح."}]}), 400
123
 
124
+ # =====================
125
+ # حالة: لا يوجد داتا تدريبية
126
+ # =====================
127
  if current_dataset is None:
128
+ base_prompt = (
129
+ f"أنت مساعد قانوني ذكي اسمه زين 👨‍⚖️.\n"
130
+ f"مهمة زين: الإجابة على الأسئلة القانونية بأسلوب واضح ومبسط "
131
+ f"مع الحفاظ على الدقة القانونية.\n\n"
132
+ f"السؤال:\n{prompt}\n\nالإجابة:"
133
+ )
134
+
135
+ inputs = tokenizer(base_prompt, return_tensors="pt", truncation=True, max_length=1024)
136
+ inputs = {k: v.to(model.device) for k, v in inputs.items()}
137
+ input_len = inputs["input_ids"].shape[-1]
138
+
139
+ outputs = model.generate(
140
+ **inputs,
141
+ max_new_tokens=200,
142
+ temperature=0.7,
143
+ top_p=0.9,
144
+ do_sample=True,
145
+ pad_token_id=tokenizer.eos_token_id,
146
+ repetition_penalty=1.1
147
+ )
148
+
149
+ reply = tokenizer.decode(outputs[0][input_len:], skip_special_tokens=True).strip()
150
+
151
  return jsonify({
152
  "messages": [
153
+ {"role": "assistant", "content": f"أهلاً {user_name} 👋"},
154
+ {"role": "assistant", "content": reply}
155
+ ],
156
+ "meta": {"mode": "base"}
157
  })
158
 
159
+ # =====================
160
+ # حالة: يوجد داتا تدريبية
161
+ # =====================
162
+ candidates = []
163
  for item in current_dataset:
164
+ text = item.get("text", "")
165
+ ratio = difflib.SequenceMatcher(None, prompt.lower(), text.lower()).ratio()
166
+ candidates.append((ratio, text))
167
+
168
+ candidates.sort(reverse=True, key=lambda x: x[0])
169
+ top_texts = [t for r, t in candidates[:n_examples] if r > 0.05]
170
+
171
+ context_parts = []
172
+ for t in top_texts:
173
+ lines = t.split("\n")
174
+ u_lines, a_lines = [], []
175
+ for l in lines:
176
+ if ":" in l:
177
+ role, content = l.split(":", 1)
178
+ role = role.strip().lower()
179
+ if role.startswith("user"):
180
+ u_lines.append(content.strip())
181
+ elif role.startswith("assistant") or role.startswith("ai") or role.startswith("system"):
182
+ a_lines.append(content.strip())
183
+ if u_lines or a_lines:
184
+ context_parts.append("User: " + " ".join(u_lines) + "\nAssistant: " + " ".join(a_lines))
185
+
186
+ context_text = "\n\n---\n\n".join(context_parts)
187
+
188
+ instruction = (
189
+ "التعليمات: استعن بالأمثلة التدريبية كمرجع أساسي، "
190
+ "لكن أجب بأسلوبك الخاص وبكلمات مختلفة. "
191
+ "حافظ على صحة المعلومة القانونية ولا تنسخ النصوص كما هي."
192
+ )
193
+
194
+ if context_text and focus_level > 0.0:
195
+ emphasis = "ركز بشكل كبير على الأمثلة" if focus_level > 0.7 else "خذ الأمثلة كمرجع فقط"
196
+ final_prompt = (
197
+ f"{instruction}\n\n{emphasis}\n\n"
198
+ f"أمثلة تدريبية (مستوى التركيز={focus_level}):\n{context_text}\n\n"
199
+ f"السؤال:\n{prompt}\n\nالإجابة:"
200
+ )
201
+ else:
202
+ final_prompt = f"{instruction}\n\nالسؤال:\n{prompt}\n\nالإجابة:"
203
+
204
+ # ==== توليد
205
+ inputs = tokenizer(final_prompt, return_tensors="pt", truncation=True, max_length=1024)
206
+ inputs = {k: v.to(model.device) for k, v in inputs.items()}
207
+ input_len = inputs["input_ids"].shape[-1]
208
+
209
  outputs = model.generate(
210
  **inputs,
211
+ max_new_tokens=200,
212
+ temperature=0.6,
213
+ top_p=0.9,
214
+ do_sample=True,
215
+ pad_token_id=tokenizer.eos_token_id,
216
+ repetition_penalty=1.1
217
  )
218
+
219
+ reply = tokenizer.decode(outputs[0][input_len:], skip_special_tokens=True).strip()
220
 
221
  return jsonify({
222
  "messages": [
223
  {"role": "assistant", "content": f"أهلاً {user_name} 👋"},
224
  {"role": "assistant", "content": reply}
225
+ ],
226
+ "meta": {
227
+ "mode": "trained",
228
+ "used_examples": len(context_parts),
229
+ "focus_level": focus_level
230
+ }
231
  })
232
 
233
  except Exception as e:
234
+ return jsonify({"messages": [{"role": "assistant", "content": f"❌ خطأ: {str(e)}"}]})
235
 
236
  # ===============================
237
  # 7b️⃣ تحميل الداتا
 
244
  data = json.load(f)
245
  except:
246
  data = []
 
247
  if data:
248
  formatted = []
249
  for item in data:
 
274
  epochs = 1
275
  batch_size = 1
276
 
 
277
  if request.is_json:
278
  body = request.get_json()
279
  if isinstance(body, list):
 
285
 
286
  epochs = int(body.get("epochs", 1)) if isinstance(body, dict) else 1
287
  batch_size = int(body.get("batch_size", 1)) if isinstance(body, dict) else 1
 
 
288
  else:
289
  file = request.files.get("file")
290
  if file:
 
294
  else:
295
  return jsonify({"error": "No file uploaded or JSON provided"}), 400
296
 
 
297
  old_data = []
298
  if os.path.exists(DATASET_FILE):
299
  with open(DATASET_FILE, "r", encoding="utf-8") as f:
 
315
  seen_texts.add(text_key)
316
  unique_data.append(item)
317
 
 
318
  with open(DATASET_FILE, "w", encoding="utf-8") as f:
319
  json.dump(unique_data, f, ensure_ascii=False, indent=2)
320
 
 
321
  formatted = []
322
  for item in unique_data:
323
  if "messages" in item:
 
327
  formatted.append({"text": conversation.strip()})
328
  elif "text" in item:
329
  formatted.append({"text": item["text"]})
 
330
  current_dataset = Dataset.from_list(formatted)
331
 
332
  def tokenize_function(examples):
 
346
 
347
  trainer = Trainer(model=model, args=training_args, train_dataset=tokenized_dataset)
348
 
 
349
  def run_training():
350
  print("🔄 Training started...")
351
  trainer.train()
 
364
  except Exception as e:
365
  return jsonify({"error": str(e)})
366
 
 
367
  # ===============================
368
  # 8️⃣ تشغيل Flask
369
  # ===============================