aab20abdullah commited on
Commit
841d51c
·
verified ·
1 Parent(s): 2b37bc6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +226 -144
app.py CHANGED
@@ -1,157 +1,239 @@
1
  import gradio as gr
2
- from huggingface_hub import hf_hub_download
3
- from llama_cpp import Llama
4
- import pandas as pd
 
 
 
5
  import os
6
 
7
- # [1] إعدادات البيئة والمستودعات
8
- HF_TOKEN = os.environ.get("HF_TOKEN")
9
- MODEL_REPO = "aab20abdullah/Akin-Yurt-Llama3-8B"
10
- MODEL_FILENAME = "AkinYurt-Llama3-Q4_K_M.gguf"
11
- DATASET_REPO = "aab20abdullah/turkmen-martyrs-dataset"
12
-
13
- # [2] إنشاء مجلد data وتنزيل ملفات الشهداء (Parquet)
14
- os.makedirs("data", exist_ok=True)
15
- parquet_files = [
16
- "train-00000-of-00001.parquet",
17
- "validation-00000-of-00001.parquet",
18
- "test-00000-of-00001.parquet"
19
- ]
20
-
21
- print("📥 Şehitler Veritabanı (Parquet) İndiriliyor...")
22
- df_list = []
23
- for file in parquet_files:
24
- try:
25
- # بعض المستودعات تضع الملفات داخل مجلد data/ في السيرفر، إذا فشل التنزيل سنحاول مع المسار
26
- file_path = hf_hub_download(
27
- repo_id=DATASET_REPO,
28
- filename=f"data/{file}" if "data/" not in file else file, # محاولة التكيف مع هيكلة HF
29
- repo_type="dataset",
30
- local_dir="data", # حفظها في المجلد المحلي data/
31
- token=HF_TOKEN
32
- )
33
- df_list.append(pd.read_parquet(file_path))
34
- print(f"✅ İndirildi: {file}")
35
- except Exception as e:
36
- print(f"⚠️ Dosya bulunamadı veya hata ({file}): {e}")
37
-
38
- # دمج جميع البيانات في قاعدة واحدة
39
- if df_list:
40
- martyrs_df = pd.concat(df_list, ignore_index=True)
41
- print(f"✅ Toplam {len(martyrs_df)} şehit kaydı sisteme yüklendi.")
42
- else:
43
- martyrs_df = pd.DataFrame()
44
- print("⚠️ Veritabanı boş. Lütfen HF_TOKEN ve dosya adlarını kontrol edin.")
45
-
46
- def search_martyrs(query):
47
- if martyrs_df.empty: return ""
48
- query_words = query.lower().split()
49
- results = []
50
- for _, row in martyrs_df.iterrows():
51
- row_text = " | ".join([str(val) for val in row.values])
52
- if any(word in row_text.lower() for word in query_words if len(word) > 3):
53
- results.append(row_text)
54
- if len(results) >= 3: break
55
- if results:
56
- return "\n\n[RESMİ VERİTABANI BİLGİSİ - BU BİLGİYİ KULLANARAK CEVAP VER]:\n" + "\n".join(results)
57
- return ""
58
-
59
- # [3] تنزيل وتهيئة محرك Llama C++ (GGUF لـ 4GB RAM)
60
- print("📥 GGUF Motoru İndiriliyor / Yükleniyor...")
61
  try:
62
- model_path = hf_hub_download(
63
- repo_id=MODEL_REPO,
64
- filename=MODEL_FILENAME,
65
- token=HF_TOKEN
66
- )
67
- print(f"✅ Model başarıyla yüklendi: {model_path}")
68
- except Exception as e:
69
- print(f"⚠️ Model İndirme Hatası: {e}")
70
- model_path = ""
71
-
72
- if model_path:
73
- print("🐺 Akın Yurt C++ Motoru Başlatılıyor...")
74
- llm = Llama(
75
- model_path=model_path,
76
- n_ctx=1024, # استهلاك ذاكرة منخفض
77
- n_threads=2, # ثبات المعالج
78
- n_gpu_layers=0, # الاعتماد على CPU
79
- verbose=False
80
- )
81
- else:
82
- llm = None
83
-
84
- # [4] ميثاق القسم والهوية
85
- UKÜCÜ_YEMINI = """ALLAHA, KURANA, YEMİN OLSUN.
86
- ŞEHİTLERİM, GAZİLERİM, EMİN OLSUN.
87
- ÜLKÜCÜ TÜRK GENÇLİĞİ OLARAK:
88
- KOMÜNİZME, FAŞİZME, KAPİTALİZME, VE HER TÜRLÜ EMPERYALİZME KARŞI MÜCADELEMİZ DEVAM EDECEKTİR.
89
- KAVGAMIZ SON NEFER, SON NEFES, SON DAMLA KANA KADARDIR.
90
- KAVGAMIZ MİLLİYETÇİ TÜRKİYEYE, TURANA KADARDIR.
91
- BAŞBUĞUMUZ EMİN OLSUN.
92
- YILANLARDAN OLMAYACAĞIZ! SATANLARDAN OLMAYACAĞIZ! KAÇANLARDAN OLMAYACAĞIZ!
93
- YIKILMAYACAĞIZ. BAŞARACAĞIZ, BAŞARACAĞIZ, BAŞARACAĞIZ.
94
- TANRI TÜRKÜ KORUSUN VE YÜCELTSİN. (AMİN)"""
95
-
96
- BASE_SYSTEM_PROMPT = """Senin adın Akın Yurt. Kerkük'te görev yapan, Türkmeneli davasına adanmış, zeki bir asistansın.
97
- Geliştiricilerin: Abdullah Ali Bahaaldeen, Ali El-Hürmüzlü ve Usame Alaaddin. TÖGB birimi tarafından geliştirildin."""
98
-
99
- # [5] نظام المعالجة والرد
100
- def respond(message, history):
101
- if not llm:
102
- yield "⚠️ HATA: Model yüklenemedi. Lütfen sistemi kontrol edin."
103
- return
104
-
105
- yemin_triggers = ["yemin", "yemin et", "andı oku", "yemini oku"]
106
- if any(trigger in message.lower() for trigger in yemin_triggers):
107
- yield UKÜCÜ_YEMINI
108
- return
109
-
110
- # دمج معلومات الشهداء
111
- db_context = search_martyrs(message)
112
- dynamic_system_prompt = BASE_SYSTEM_PROMPT + db_context
113
-
114
- messages = [{"role": "system", "content": dynamic_system_prompt}]
115
- for user_msg, assistant_msg in history:
116
- if user_msg: messages.append({"role": "user", "content": user_msg})
117
- if assistant_msg: messages.append({"role": "assistant", "content": assistant_msg})
118
- messages.append({"role": "user", "content": message})
 
 
 
119
 
120
- response = ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  try:
122
- stream = llm.create_chat_completion(
123
- messages=messages,
124
- max_tokens=512,
125
- temperature=0.7,
126
- top_p=0.95,
127
- stream=True
128
  )
129
-
130
- for chunk in stream:
131
- delta = chunk['choices'][0]['delta']
132
- if 'content' in delta:
133
- token = delta['content']
134
- response += token
135
- yield response
136
- except Exception as e:
137
- yield f"⚠️ Motor Hatası: {str(e)}"
138
-
139
- # [6] الواجهة الرسومية
140
- custom_theme = gr.themes.Soft(primary_hue="blue", secondary_hue="cyan").set(
141
- button_primary_background_fill="#007bff",
142
- button_primary_text_color="white",
143
- )
 
 
 
 
 
 
 
 
 
 
144
 
145
- with gr.Blocks(theme=custom_theme, title="Akın Yurt - TÖGB") as demo:
146
- gr.Markdown("# 🐺 Akın Yurt")
147
- gr.Markdown("### Türkmeneli Dijital Asistanı (Veritabanı Entegreli Çevrimdışı Motor)")
148
- gr.Markdown("---")
149
 
150
- gr.ChatInterface(
151
- respond,
152
- examples=["Seni kim yaptı?", "Andı oku", "Bize Kerkük şehitlerinden bahset"],
153
- cache_examples=False,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  )
 
 
155
 
156
  if __name__ == "__main__":
157
  demo.launch()
 
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
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True)
16
+ model = AutoModelForCausalLM.from_pretrained(
17
+ MODEL_NAME,
18
+ torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
19
+ device_map="auto" if torch.cuda.is_available() else None,
20
+ trust_remote_code=True
21
+ )
22
+
23
+ # تحميل نموذج الـ embeddings للـ RAG
24
+ print("Loading embedding model...")
25
+ embedding_model = SentenceTransformer('sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2')
26
+
27
+ # تحميل الـ dataset
28
+ print("Loading dataset...")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  try:
30
+ dataset = load_dataset(DATASET_NAME, split='train')
31
+ except:
32
+ # في حالة عدم وجود split محدد
33
+ dataset = load_dataset(DATASET_NAME)
34
+ if isinstance(dataset, dict):
35
+ dataset = dataset[list(dataset.keys())[0]]
36
+
37
+ # إعداد الـ RAG system
38
+ print("Building RAG index...")
39
+
40
+ # استخراج النصوص من الـ dataset
41
+ def extract_texts_from_dataset(dataset):
42
+ texts = []
43
+ for item in dataset:
44
+ # افترض أن الـ dataset يحتوي على حقول نصية
45
+ # عدّل هذا حسب البنية الفعلية للـ dataset
46
+ text_parts = []
47
+ for key, value in item.items():
48
+ if isinstance(value, str) and len(value) > 10:
49
+ text_parts.append(f"{key}: {value}")
50
+ if text_parts:
51
+ texts.append(" | ".join(text_parts))
52
+ return texts
53
+
54
+ texts = extract_texts_from_dataset(dataset)
55
+ print(f"Extracted {len(texts)} text chunks from dataset")
56
+
57
+ # إنشاء embeddings
58
+ embeddings = embedding_model.encode(texts, show_progress_bar=True)
59
+ embeddings = np.array(embeddings).astype('float32')
60
+
61
+ # إنشاء FAISS index
62
+ dimension = embeddings.shape[1]
63
+ index = faiss.IndexFlatL2(dimension)
64
+ index.add(embeddings)
65
+
66
+ print("RAG system ready!")
67
+
68
+ def retrieve_relevant_context(query, k=3):
69
+ """استرجاع السياق الأكثر صلة بالاستعلام"""
70
+ query_embedding = embedding_model.encode([query])
71
+ query_embedding = np.array(query_embedding).astype('float32')
72
+
73
+ distances, indices = index.search(query_embedding, k)
74
+
75
+ relevant_texts = [texts[idx] for idx in indices[0]]
76
+ return "\n\n".join(relevant_texts)
77
+
78
+ def generate_response(message, history, temperature=0.7, max_tokens=512, use_rag=True):
79
+ """توليد الرد باستخدام النموذج مع أو بدون RAG"""
80
+
81
+ # بناء المحادثة
82
+ conversation = []
83
+
84
+ if use_rag:
85
+ # استرجاع السياق ذي الصلة
86
+ context = retrieve_relevant_context(message)
87
+
88
+ # إضافة السياق إلى الـ prompt
89
+ system_message = f"""أنت مساعد ذكي. استخدم المعلومات التالية للإجابة على السؤال:
90
 
91
+ المعلومات المرجعية:
92
+ {context}
93
+
94
+ أجب بناءً على هذه المعلومات. إذا لم تكن المعلومات كافية، قل ذلك."""
95
+
96
+ conversation.append({"role": "system", "content": system_message})
97
+
98
+ # إضافة تاريخ المحادثة
99
+ for user_msg, assistant_msg in history:
100
+ conversation.append({"role": "user", "content": user_msg})
101
+ if assistant_msg:
102
+ conversation.append({"role": "assistant", "content": assistant_msg})
103
+
104
+ # إضافة الرسالة الحالية
105
+ conversation.append({"role": "user", "content": message})
106
+
107
+ # تحويل إلى prompt
108
  try:
109
+ prompt = tokenizer.apply_chat_template(
110
+ conversation,
111
+ tokenize=False,
112
+ add_generation_prompt=True
 
 
113
  )
114
+ except:
115
+ # في حالة عدم وجود chat template
116
+ prompt = "\n".join([f"{msg['role']}: {msg['content']}" for msg in conversation])
117
+ prompt += "\nassistant: "
118
+
119
+ # Tokenize
120
+ inputs = tokenizer(prompt, return_tensors="pt")
121
+ if torch.cuda.is_available():
122
+ inputs = {k: v.to(model.device) for k, v in inputs.items()}
123
+
124
+ # Generate
125
+ with torch.no_grad():
126
+ outputs = model.generate(
127
+ **inputs,
128
+ max_new_tokens=max_tokens,
129
+ temperature=temperature,
130
+ do_sample=temperature > 0,
131
+ top_p=0.9,
132
+ pad_token_id=tokenizer.eos_token_id
133
+ )
134
+
135
+ # Decode
136
+ response = tokenizer.decode(outputs[0][inputs['input_ids'].shape[1]:], skip_special_tokens=True)
137
+
138
+ return response
139
 
140
+ # إنشاء Gradio interface
141
+ with gr.Blocks(title="Akin Yurt with RAG", theme=gr.themes.Soft()) as demo:
142
+ gr.Markdown("""
143
+ # 🤖 Akin Yurt Model with RAG
144
 
145
+ هذا النموذج يستخدم **Retrieval-Augmented Generation (RAG)** مع بيانات شهداء تركمان.
146
+
147
+ يمكنك تفعيل أو تعطيل RAG لمقارنة النتائج.
148
+ """)
149
+
150
+ with gr.Row():
151
+ with gr.Column(scale=2):
152
+ chatbot = gr.Chatbot(
153
+ height=500,
154
+ label="المحادثة",
155
+ show_label=True,
156
+ avatar_images=(None, "🤖")
157
+ )
158
+
159
+ with gr.Row():
160
+ msg = gr.Textbox(
161
+ label="رسالتك",
162
+ placeholder="اكتب سؤالك هنا...",
163
+ show_label=False,
164
+ scale=4
165
+ )
166
+ submit = gr.Button("إرسال", variant="primary", scale=1)
167
+
168
+ with gr.Row():
169
+ clear = gr.Button("مسح المحادثة", scale=1)
170
+
171
+ with gr.Column(scale=1):
172
+ gr.Markdown("### ⚙️ الإعدادات")
173
+
174
+ use_rag = gr.Checkbox(
175
+ label="استخدام RAG",
176
+ value=True,
177
+ info="تفعيل استرجاع المعلومات من قاعدة البيانات"
178
+ )
179
+
180
+ temperature = gr.Slider(
181
+ minimum=0.1,
182
+ maximum=2.0,
183
+ value=0.7,
184
+ step=0.1,
185
+ label="Temperature",
186
+ info="يتحكم في عشوائية الإجابات"
187
+ )
188
+
189
+ max_tokens = gr.Slider(
190
+ minimum=128,
191
+ maximum=2048,
192
+ value=512,
193
+ step=128,
194
+ label="Max Tokens",
195
+ info="الحد الأقصى لطول الإجابة"
196
+ )
197
+
198
+ gr.Markdown("""
199
+ ### 📊 معلومات
200
+
201
+ - **النموذج**: aab20abdullah/akin-yurt-finely
202
+ - **البيانات**: aab20abdullah/turkmen-martyrs-dataset
203
+ - **عدد السجلات**: """ + f"{len(texts)}" + """
204
+
205
+ ### 💡 نصائح
206
+
207
+ - جرّب تشغيل وإيقاف RAG لرؤية الفرق
208
+ - استخدم temperature منخفض للإجابات الدقيقة
209
+ - استخدم temperature عالي للإجابات الإبداعية
210
+ """)
211
+
212
+ def user_message(message, history):
213
+ return "", history + [[message, None]]
214
+
215
+ def bot_response(history, temperature, max_tokens, use_rag):
216
+ message = history[-1][0]
217
+ response = generate_response(
218
+ message,
219
+ history[:-1],
220
+ temperature=temperature,
221
+ max_tokens=max_tokens,
222
+ use_rag=use_rag
223
+ )
224
+ history[-1][1] = response
225
+ return history
226
+
227
+ # Event handlers
228
+ msg.submit(user_message, [msg, chatbot], [msg, chatbot], queue=False).then(
229
+ bot_response, [chatbot, temperature, max_tokens, use_rag], chatbot
230
+ )
231
+
232
+ submit.click(user_message, [msg, chatbot], [msg, chatbot], queue=False).then(
233
+ bot_response, [chatbot, temperature, max_tokens, use_rag], chatbot
234
  )
235
+
236
+ clear.click(lambda: None, None, chatbot, queue=False)
237
 
238
  if __name__ == "__main__":
239
  demo.launch()