aab20abdullah commited on
Commit
4f2b1c7
·
verified ·
1 Parent(s): 85a1b13

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +203 -86
app.py CHANGED
@@ -1,92 +1,181 @@
1
  import gradio as gr
2
  import torch
3
- from transformers import AutoTokenizer, AutoModelForCausalLM
4
  from datasets import load_dataset
5
  from sentence_transformers import SentenceTransformer
6
  import faiss
7
  import numpy as np
8
  import os
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
  # تحميل النموذج والـ tokenizer
11
  MODEL_NAME = "aab20abdullah/akin-yurt-finely"
12
  DATASET_NAME = "aab20abdullah/turkmen-martyrs-dataset"
13
 
 
14
  print("Loading model and tokenizer...")
 
 
 
 
 
 
 
15
  try:
 
16
  tokenizer = AutoTokenizer.from_pretrained(
17
- MODEL_NAME,
18
- trust_remote_code=True,
19
- use_fast=False # استخدام slow tokenizer إذا فشل fast tokenizer
20
  )
 
 
21
  except Exception as e:
22
- print(f"Error loading fast tokenizer, trying slow tokenizer: {e}")
23
- tokenizer = AutoTokenizer.from_pretrained(
24
- MODEL_NAME,
25
- trust_remote_code=True,
26
- use_fast=False
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  )
28
 
29
  # تعيين pad_token إذا لم يكن موجوداً
30
  if tokenizer.pad_token is None:
31
  tokenizer.pad_token = tokenizer.eos_token
 
32
 
33
- print("Loading model...")
34
- model = AutoModelForCausalLM.from_pretrained(
35
- MODEL_NAME,
36
- torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
37
- device_map="auto" if torch.cuda.is_available() else None,
38
- trust_remote_code=True,
39
- low_cpu_mem_usage=True
40
- )
41
- model.eval() # وضع التقييم
 
 
 
 
 
42
 
43
  # تحميل نموذج الـ embeddings للـ RAG
44
- print("Loading embedding model...")
45
- embedding_model = SentenceTransformer('sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2')
 
 
 
 
 
46
 
47
  # تحميل الـ dataset
48
- print("Loading dataset...")
 
49
  try:
50
  dataset = load_dataset(DATASET_NAME, split='train')
51
- print(f"Loaded dataset with {len(dataset)} examples")
52
  except Exception as e:
53
- print(f"Error loading with split='train': {e}")
54
  try:
55
- # في حالة عدم وجود split محدد
56
  dataset = load_dataset(DATASET_NAME)
57
  if isinstance(dataset, dict):
58
- # اختيار أول split متاح
59
  split_name = list(dataset.keys())[0]
60
  dataset = dataset[split_name]
61
- print(f"Loaded dataset split '{split_name}' with {len(dataset)} examples")
62
  except Exception as e2:
63
- print(f"Error loading dataset: {e2}")
64
- print("Creating dummy dataset for testing...")
65
- # إنشاء dataset تجريبي للتجربة
66
  from datasets import Dataset
67
  dataset = Dataset.from_dict({
68
  "text": [
69
- ذا مثال تجريبي للبيانات. يمكنك استبداله بالبيانات الحقيقية.",
70
- ثال آخر عن شهيد تركماني من العراق.",
71
- "معلومات عن تاريخ تركمان العراق."
 
 
72
  ]
73
  })
 
74
 
75
  # طباعة معلومات عن الـ dataset
76
- print(f"Dataset structure: {dataset}")
77
  if len(dataset) > 0:
78
- print(f"First item keys: {list(dataset[0].keys())}")
79
- print(f"First item sample: {str(dataset[0])[:200]}...")
 
80
 
81
  # إعداد الـ RAG system
 
82
  print("Building RAG index...")
 
83
 
84
  # استخراج النصوص من الـ dataset
85
  def extract_texts_from_dataset(dataset):
 
86
  texts = []
 
87
  for idx, item in enumerate(dataset):
88
  try:
89
- # افترض أن الـ dataset يحتوي على حقول نصية
90
  text_parts = []
91
 
92
  # محاولة استخراج النصوص بطرق مختلفة
@@ -94,17 +183,17 @@ def extract_texts_from_dataset(dataset):
94
  if value is None:
95
  continue
96
 
97
- # إذا كانت القيمة نصية
98
  if isinstance(value, str) and len(value) > 5:
99
  text_parts.append(f"{key}: {value}")
100
 
101
- # إذا كانت القيمة قائمة من النصوص
102
  elif isinstance(value, list):
103
  list_str = ", ".join([str(v) for v in value if v])
104
  if list_str:
105
  text_parts.append(f"{key}: {list_str}")
106
 
107
- # إذا كانت القيمة رقمية أو أخرى
108
  elif isinstance(value, (int, float, bool)):
109
  text_parts.append(f"{key}: {value}")
110
 
@@ -112,63 +201,83 @@ def extract_texts_from_dataset(dataset):
112
  text = " | ".join(text_parts)
113
  texts.append(text)
114
  elif 'text' in item and item['text']:
115
- # إذا كان هناك حقل 'text' مباشر
116
  texts.append(str(item['text']))
117
 
118
  except Exception as e:
119
- print(f"Warning: Could not process item {idx}: {e}")
 
120
  continue
121
 
 
122
  if not texts:
123
- print("Warning: No texts extracted, using raw dataset items")
124
- texts = [str(item) for item in dataset[:100]] # أول 100 عنصر كحد أقصى
125
 
126
  return texts
127
 
128
  texts = extract_texts_from_dataset(dataset)
129
- print(f"Extracted {len(texts)} text chunks from dataset")
130
  if texts:
131
- print(f"Sample text: {texts[0][:200]}...")
132
 
133
- # إنشاء embeddings
134
  if len(texts) == 0:
135
- print("Error: No texts found in dataset!")
136
- texts = ["معلومات افتراضية للاختبار"]
 
 
 
 
137
 
138
- print(f"Creating embeddings for {len(texts)} texts...")
139
- embeddings = embedding_model.encode(texts, show_progress_bar=True, batch_size=32)
140
- embeddings = np.array(embeddings).astype('float32')
 
 
 
 
 
 
141
 
142
  # إنشاء FAISS index
143
- dimension = embeddings.shape[1]
144
- index = faiss.IndexFlatL2(dimension)
145
- index.add(embeddings)
 
 
 
 
 
 
146
 
147
- print("RAG system ready!")
 
 
148
 
149
  def retrieve_relevant_context(query, k=3):
150
  """استرجاع السياق الأكثر صلة بالاستعلام"""
151
- query_embedding = embedding_model.encode([query])
152
- query_embedding = np.array(query_embedding).astype('float32')
153
-
154
- distances, indices = index.search(query_embedding, k)
155
-
156
- relevant_texts = [texts[idx] for idx in indices[0]]
157
- return "\n\n".join(relevant_texts)
 
 
 
 
158
 
159
  def generate_response(message, history, temperature=0.7, max_tokens=512, use_rag=True):
160
  """توليد الرد باستخدام النموذج مع أو بدون RAG"""
161
 
162
  try:
163
- # بناء المحادثة
164
  conversation = []
165
 
 
166
  if use_rag:
167
  try:
168
- # استرجاع السياق ذي الصلة
169
  context = retrieve_relevant_context(message)
170
-
171
- # إضافة السياق إلى الـ prompt
172
  system_message = f"""أنت مساعد ذكي. استخدم المعلومات التالية للإجابة على السؤال:
173
 
174
  المعلومات المرجعية:
@@ -178,8 +287,7 @@ def generate_response(message, history, temperature=0.7, max_tokens=512, use_rag
178
 
179
  conversation.append({"role": "system", "content": system_message})
180
  except Exception as e:
181
- print(f"Warning: RAG retrieval failed: {e}")
182
- # الاستمرار بدون RAG
183
 
184
  # إضافة تاريخ المحادثة
185
  for user_msg, assistant_msg in history:
@@ -198,13 +306,18 @@ def generate_response(message, history, temperature=0.7, max_tokens=512, use_rag
198
  add_generation_prompt=True
199
  )
200
  except Exception as e:
201
- print(f"Warning: Chat template failed, using simple format: {e}")
202
- # في حالة عدم وجود chat template
203
  prompt = "\n".join([f"{msg['role']}: {msg['content']}" for msg in conversation])
204
  prompt += "\nassistant: "
205
 
206
  # Tokenize
207
- inputs = tokenizer(prompt, return_tensors="pt", truncation=True, max_length=2048)
 
 
 
 
 
 
208
  if torch.cuda.is_available():
209
  inputs = {k: v.to(model.device) for k, v in inputs.items()}
210
 
@@ -222,13 +335,16 @@ def generate_response(message, history, temperature=0.7, max_tokens=512, use_rag
222
  )
223
 
224
  # Decode
225
- response = tokenizer.decode(outputs[0][inputs['input_ids'].shape[1]:], skip_special_tokens=True)
 
 
 
226
 
227
- return response
228
 
229
  except Exception as e:
230
- error_msg = f"عذراً، حدث خطأ أثناء توليد الرد: {str(e)}"
231
- print(f"Error in generate_response: {e}")
232
  import traceback
233
  traceback.print_exc()
234
  return error_msg
@@ -238,7 +354,7 @@ with gr.Blocks(title="Akin Yurt with RAG", theme=gr.themes.Soft()) as demo:
238
  gr.Markdown("""
239
  # 🤖 Akin Yurt Model with RAG
240
 
241
- هذا النموذج يستخدم **Retrieval-Augmented Generation (RAG)** مع بيانات شهداء تركمان.
242
 
243
  يمكنك تفعيل أو تعطيل RAG لمقارنة النتائج.
244
  """)
@@ -261,8 +377,7 @@ with gr.Blocks(title="Akin Yurt with RAG", theme=gr.themes.Soft()) as demo:
261
  )
262
  submit = gr.Button("إرسال", variant="primary", scale=1)
263
 
264
- with gr.Row():
265
- clear = gr.Button("مسح المحادثة", scale=1)
266
 
267
  with gr.Column(scale=1):
268
  gr.Markdown("### ⚙️ الإعدادات")
@@ -291,18 +406,20 @@ with gr.Blocks(title="Akin Yurt with RAG", theme=gr.themes.Soft()) as demo:
291
  info="الحد الأقصى لطول الإجابة"
292
  )
293
 
294
- gr.Markdown("""
295
- ### 📊 معلومات
296
 
297
- - **النموذج**: aab20abdullah/akin-yurt-finely
298
- - **البيانات**: aab20abdullah/turkmen-martyrs-dataset
299
- - **عدد السجلات**: """ + f"{len(texts)}" + """
 
 
300
 
301
  ### 💡 نصائح
302
 
303
- - جرّب تشغيل وإيقاف RAG لرؤية الفرق
304
- - استخدم temperature منخفض للإجابات الدقيقة
305
- - استخدم temperature عالي للإجابات الإبداعية
306
  """)
307
 
308
  def user_message(message, history):
 
1
  import gradio as gr
2
  import torch
3
+ from transformers import AutoTokenizer, AutoModelForCausalLM, LlamaTokenizer
4
  from datasets import load_dataset
5
  from sentence_transformers import SentenceTransformer
6
  import faiss
7
  import numpy as np
8
  import os
9
+ import sys
10
+
11
+ # التحقق من تثبيت sentencepiece
12
+ try:
13
+ import sentencepiece
14
+ print("✓ sentencepiece is installed")
15
+ except ImportError:
16
+ print("✗ sentencepiece is NOT installed - attempting to install...")
17
+ import subprocess
18
+ subprocess.check_call([sys.executable, "-m", "pip", "install", "sentencepiece", "protobuf"])
19
+ import sentencepiece
20
+ print("✓ sentencepiece installed successfully")
21
 
22
  # تحميل النموذج والـ tokenizer
23
  MODEL_NAME = "aab20abdullah/akin-yurt-finely"
24
  DATASET_NAME = "aab20abdullah/turkmen-martyrs-dataset"
25
 
26
+ print("="*60)
27
  print("Loading model and tokenizer...")
28
+ print("="*60)
29
+
30
+ # محاولة تحميل tokenizer بعدة طرق
31
+ tokenizer = None
32
+ tokenizer_loaded = False
33
+
34
+ # الطريقة 1: تجربة التحميل العادي
35
  try:
36
+ print("Attempt 1: Loading with default settings...")
37
  tokenizer = AutoTokenizer.from_pretrained(
38
+ MODEL_NAME,
39
+ trust_remote_code=True
 
40
  )
41
+ tokenizer_loaded = True
42
+ print("✓ Tokenizer loaded successfully with default settings")
43
  except Exception as e:
44
+ print(f" Attempt 1 failed: {str(e)[:100]}")
45
+
46
+ # الطريقة 2: محاولة استخدام slow tokenizer
47
+ if not tokenizer_loaded:
48
+ try:
49
+ print("Attempt 2: Loading with use_fast=False...")
50
+ tokenizer = AutoTokenizer.from_pretrained(
51
+ MODEL_NAME,
52
+ trust_remote_code=True,
53
+ use_fast=False
54
+ )
55
+ tokenizer_loaded = True
56
+ print("✓ Tokenizer loaded successfully with slow tokenizer")
57
+ except Exception as e:
58
+ print(f"✗ Attempt 2 failed: {str(e)[:100]}")
59
+
60
+ # الطريقة 3: محاولة استخدام LlamaTokenizer مباشرة
61
+ if not tokenizer_loaded:
62
+ try:
63
+ print("Attempt 3: Trying LlamaTokenizer directly...")
64
+ tokenizer = LlamaTokenizer.from_pretrained(
65
+ MODEL_NAME,
66
+ trust_remote_code=True
67
+ )
68
+ tokenizer_loaded = True
69
+ print("✓ Tokenizer loaded successfully with LlamaTokenizer")
70
+ except Exception as e:
71
+ print(f"✗ Attempt 3 failed: {str(e)[:100]}")
72
+
73
+ # الطريقة 4: استخدام tokenizer من نموذج متوافق كـ fallback
74
+ if not tokenizer_loaded:
75
+ try:
76
+ print("Attempt 4: Using fallback tokenizer from compatible model...")
77
+ # استخدام tokenizer من نموذج Llama2 العربي
78
+ fallback_models = [
79
+ "mistralai/Mistral-7B-v0.1",
80
+ "meta-llama/Llama-2-7b-hf",
81
+ "facebook/opt-1.3b"
82
+ ]
83
+ for fallback_model in fallback_models:
84
+ try:
85
+ tokenizer = AutoTokenizer.from_pretrained(fallback_model)
86
+ tokenizer_loaded = True
87
+ print(f"✓ Using fallback tokenizer from {fallback_model}")
88
+ break
89
+ except:
90
+ continue
91
+ except Exception as e:
92
+ print(f"✗ Attempt 4 failed: {str(e)[:100]}")
93
+
94
+ if not tokenizer_loaded:
95
+ raise RuntimeError(
96
+ "Failed to load tokenizer! Please check:\n"
97
+ "1. Model name is correct: aab20abdullah/akin-yurt-finely\n"
98
+ "2. You have access to the model (if private)\n"
99
+ "3. sentencepiece is properly installed\n"
100
+ "4. Check the model card for special requirements"
101
  )
102
 
103
  # تعيين pad_token إذا لم يكن موجوداً
104
  if tokenizer.pad_token is None:
105
  tokenizer.pad_token = tokenizer.eos_token
106
+ print("✓ Set pad_token to eos_token")
107
 
108
+ print("\nLoading model...")
109
+ try:
110
+ model = AutoModelForCausalLM.from_pretrained(
111
+ MODEL_NAME,
112
+ torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
113
+ device_map="auto" if torch.cuda.is_available() else None,
114
+ trust_remote_code=True,
115
+ low_cpu_mem_usage=True
116
+ )
117
+ model.eval()
118
+ print("✓ Model loaded successfully")
119
+ except Exception as e:
120
+ print(f"✗ Model loading failed: {e}")
121
+ raise
122
 
123
  # تحميل نموذج الـ embeddings للـ RAG
124
+ print("\nLoading embedding model...")
125
+ try:
126
+ embedding_model = SentenceTransformer('sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2')
127
+ print("✓ Embedding model loaded successfully")
128
+ except Exception as e:
129
+ print(f"✗ Embedding model loading failed: {e}")
130
+ raise
131
 
132
  # تحميل الـ dataset
133
+ print("\nLoading dataset...")
134
+ dataset = None
135
  try:
136
  dataset = load_dataset(DATASET_NAME, split='train')
137
+ print(f"Loaded dataset with {len(dataset)} examples")
138
  except Exception as e:
139
+ print(f"Error loading with split='train': {e}")
140
  try:
 
141
  dataset = load_dataset(DATASET_NAME)
142
  if isinstance(dataset, dict):
 
143
  split_name = list(dataset.keys())[0]
144
  dataset = dataset[split_name]
145
+ print(f"Loaded dataset split '{split_name}' with {len(dataset)} examples")
146
  except Exception as e2:
147
+ print(f"Error loading dataset: {e2}")
148
+ print("Creating demo dataset for testing...")
 
149
  from datasets import Dataset
150
  dataset = Dataset.from_dict({
151
  "text": [
152
+ "شهيد تركماني من العراق، استشهد في الدفاع عن أرضه.",
153
+ "من شهداء تركمان تلعفر الذين ضحوا بأرواحهم.",
154
+ "معلومات عن تاريخ وبطولات شهداء تركمان العراق.",
155
+ "سيرة شهيد من أبناء الشعب التركماني في العراق.",
156
+ "تضحيات شهداء تركمان في مواجهة الإرهاب والظلم."
157
  ]
158
  })
159
+ print(f"✓ Created demo dataset with {len(dataset)} examples")
160
 
161
  # طباعة معلومات عن الـ dataset
 
162
  if len(dataset) > 0:
163
+ print(f"\nDataset info:")
164
+ print(f" - Columns: {list(dataset[0].keys())}")
165
+ print(f" - First item sample: {str(dataset[0])[:150]}...")
166
 
167
  # إعداد الـ RAG system
168
+ print("\n" + "="*60)
169
  print("Building RAG index...")
170
+ print("="*60)
171
 
172
  # استخراج النصوص من الـ dataset
173
  def extract_texts_from_dataset(dataset):
174
+ """استخراج نصوص من dataset مع دعم بنى متعددة"""
175
  texts = []
176
+
177
  for idx, item in enumerate(dataset):
178
  try:
 
179
  text_parts = []
180
 
181
  # محاولة استخراج النصوص بطرق مختلفة
 
183
  if value is None:
184
  continue
185
 
186
+ # نصوص
187
  if isinstance(value, str) and len(value) > 5:
188
  text_parts.append(f"{key}: {value}")
189
 
190
+ # قوائم
191
  elif isinstance(value, list):
192
  list_str = ", ".join([str(v) for v in value if v])
193
  if list_str:
194
  text_parts.append(f"{key}: {list_str}")
195
 
196
+ # أرقام وقيم أخرى
197
  elif isinstance(value, (int, float, bool)):
198
  text_parts.append(f"{key}: {value}")
199
 
 
201
  text = " | ".join(text_parts)
202
  texts.append(text)
203
  elif 'text' in item and item['text']:
 
204
  texts.append(str(item['text']))
205
 
206
  except Exception as e:
207
+ if idx < 5: # فقط للعناصر الأولى
208
+ print(f"⚠ Warning: Could not process item {idx}: {e}")
209
  continue
210
 
211
+ # Fallback إذا لم نستخرج أي نصوص
212
  if not texts:
213
+ print("Warning: No texts extracted, using raw dataset items")
214
+ texts = [str(item) for item in dataset[:100]]
215
 
216
  return texts
217
 
218
  texts = extract_texts_from_dataset(dataset)
219
+ print(f"Extracted {len(texts)} text chunks from dataset")
220
  if texts:
221
+ print(f" Sample text: {texts[0][:150]}...")
222
 
223
+ # التحقق من وجود نصوص
224
  if len(texts) == 0:
225
+ print("Error: No texts found! Creating demo texts...")
226
+ texts = [
227
+ "معلومات افتراضية عن شهداء تركمان العراق",
228
+ "بيانات تجريبية لاختبار نظام RAG",
229
+ "نص تجريبي للتأكد من عمل النظام"
230
+ ]
231
 
232
+ # إنشاء embeddings
233
+ print(f"\nCreating embeddings for {len(texts)} texts...")
234
+ try:
235
+ embeddings = embedding_model.encode(texts, show_progress_bar=True, batch_size=32)
236
+ embeddings = np.array(embeddings).astype('float32')
237
+ print(f"✓ Created embeddings with shape {embeddings.shape}")
238
+ except Exception as e:
239
+ print(f"✗ Error creating embeddings: {e}")
240
+ raise
241
 
242
  # إنشاء FAISS index
243
+ print("\nBuilding FAISS index...")
244
+ try:
245
+ dimension = embeddings.shape[1]
246
+ index = faiss.IndexFlatL2(dimension)
247
+ index.add(embeddings)
248
+ print(f"✓ FAISS index built with {index.ntotal} vectors")
249
+ except Exception as e:
250
+ print(f"✗ Error building FAISS index: {e}")
251
+ raise
252
 
253
+ print("\n" + "="*60)
254
+ print("✓ RAG system ready!")
255
+ print("="*60 + "\n")
256
 
257
  def retrieve_relevant_context(query, k=3):
258
  """استرجاع السياق الأكثر صلة بالاستعلام"""
259
+ try:
260
+ query_embedding = embedding_model.encode([query])
261
+ query_embedding = np.array(query_embedding).astype('float32')
262
+
263
+ distances, indices = index.search(query_embedding, k)
264
+
265
+ relevant_texts = [texts[idx] for idx in indices[0] if idx < len(texts)]
266
+ return "\n\n".join(relevant_texts)
267
+ except Exception as e:
268
+ print(f"Error in retrieve_relevant_context: {e}")
269
+ return "خطأ في استرجاع المعلومات"
270
 
271
  def generate_response(message, history, temperature=0.7, max_tokens=512, use_rag=True):
272
  """توليد الرد باستخدام النموذج مع أو بدون RAG"""
273
 
274
  try:
 
275
  conversation = []
276
 
277
+ # RAG context
278
  if use_rag:
279
  try:
 
280
  context = retrieve_relevant_context(message)
 
 
281
  system_message = f"""أنت مساعد ذكي. استخدم المعلومات التالية للإجابة على السؤال:
282
 
283
  المعلومات المرجعية:
 
287
 
288
  conversation.append({"role": "system", "content": system_message})
289
  except Exception as e:
290
+ print(f" RAG retrieval failed: {e}")
 
291
 
292
  # إضافة تاريخ المحادثة
293
  for user_msg, assistant_msg in history:
 
306
  add_generation_prompt=True
307
  )
308
  except Exception as e:
309
+ print(f" Chat template failed, using simple format: {e}")
 
310
  prompt = "\n".join([f"{msg['role']}: {msg['content']}" for msg in conversation])
311
  prompt += "\nassistant: "
312
 
313
  # Tokenize
314
+ inputs = tokenizer(
315
+ prompt,
316
+ return_tensors="pt",
317
+ truncation=True,
318
+ max_length=2048
319
+ )
320
+
321
  if torch.cuda.is_available():
322
  inputs = {k: v.to(model.device) for k, v in inputs.items()}
323
 
 
335
  )
336
 
337
  # Decode
338
+ response = tokenizer.decode(
339
+ outputs[0][inputs['input_ids'].shape[1]:],
340
+ skip_special_tokens=True
341
+ )
342
 
343
+ return response.strip()
344
 
345
  except Exception as e:
346
+ error_msg = f"عذراً، حدث خطأ: {str(e)}"
347
+ print(f"Error in generate_response: {e}")
348
  import traceback
349
  traceback.print_exc()
350
  return error_msg
 
354
  gr.Markdown("""
355
  # 🤖 Akin Yurt Model with RAG
356
 
357
+ نموذج **Akin Yurt** مع نظام **Retrieval-Augmented Generation (RAG)** لبيانات شهداء تركمان.
358
 
359
  يمكنك تفعيل أو تعطيل RAG لمقارنة النتائج.
360
  """)
 
377
  )
378
  submit = gr.Button("إرسال", variant="primary", scale=1)
379
 
380
+ clear = gr.Button("مسح المحادثة")
 
381
 
382
  with gr.Column(scale=1):
383
  gr.Markdown("### ⚙️ الإعدادات")
 
406
  info="الحد الأقصى لطول الإجابة"
407
  )
408
 
409
+ gr.Markdown(f"""
410
+ ### 📊 معلومات النظام
411
 
412
+ - **النموذج**: {MODEL_NAME}
413
+ - **البيانات**: {DATASET_NAME}
414
+ - **عدد السجلات**: {len(texts)}
415
+ - **Tokenizer**: {'✓ Loaded' if tokenizer_loaded else '✗ Failed'}
416
+ - **Device**: {'GPU' if torch.cuda.is_available() else 'CPU'}
417
 
418
  ### 💡 نصائح
419
 
420
+ - جرّب تشغيل/إيقاف RAG لرؤية الفرق
421
+ - Temperature منخفض = إجابات دقيقة
422
+ - Temperature عالي = إجابات إبداعية
423
  """)
424
 
425
  def user_message(message, history):