apak commited on
Commit
6c62cc5
·
verified ·
1 Parent(s): 4067fe0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +148 -155
app.py CHANGED
@@ -15,21 +15,34 @@ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
15
 
16
  # --- 1. MODELLERİN HAZIRLANMASI ---
17
  ner_pipe = pipeline("ner", model="xlm-roberta-large-finetuned-conll03-english", aggregation_strategy="simple", device=-1)
 
 
18
  model_id = "Qwen/Qwen2.5-7B-Instruct"
19
- tokenizer = AutoTokenizer.from_pretrained(model_id)
20
 
21
- # LLM modelini yükle - RUNTIME ERROR KESİN ÇÖZÜMÜ
 
 
 
 
 
 
 
 
 
 
 
22
  llm_model = None
23
  IS_LLM_ENABLED = False
24
 
25
  try:
26
- print("📦 LLM modeli yükleniyor...")
 
27
 
28
- # Modeli doğrudan CPU'da yükle
29
  llm_model = AutoModelForCausalLM.from_pretrained(
30
- model_id,
31
- torch_dtype=torch.float32,
32
- device_map="cpu", # Doğrudan CPU'ya map et
33
  trust_remote_code=True,
34
  low_cpu_mem_usage=True
35
  )
@@ -37,19 +50,19 @@ try:
37
  # Modeli evaluation moduna al
38
  llm_model.eval()
39
 
40
- # Device'ı kontrol et
41
  device = next(llm_model.parameters()).device
42
- print(f"✅ LLM modeli yüklendi! Device: {device}")
43
  print(f" Model dtype: {next(llm_model.parameters()).dtype}")
44
 
45
  IS_LLM_ENABLED = True
46
 
47
  except Exception as e:
48
  IS_LLM_ENABLED = False
49
- print(f"⚠️ LLM yüklenemedi: {e}")
50
  print(traceback.format_exc())
51
 
52
- # --- 2. WIKIPEDIA API (DOĞRUDAN API KULLANIMI) ---
53
 
54
  def get_wiki_summary(term):
55
  """Türkçe Wikipedia'dan doğrudan API ile özet getirir"""
@@ -69,6 +82,10 @@ def get_wiki_summary(term):
69
  "Nobel": "Nobel Ödülü",
70
  "Amerika": "Amerika",
71
  "1984": "1984 (roman)",
 
 
 
 
72
  }
73
 
74
  # Arama terimlerini hazırla
@@ -78,7 +95,6 @@ def get_wiki_summary(term):
78
  search_terms = [value, term]
79
  break
80
 
81
- # Eğer özel durum yoksa, çoğul ve tekil dene
82
  if len(search_terms) == 1:
83
  if term.endswith("lar") or term.endswith("ler"):
84
  search_terms.append(term[:-3])
@@ -88,7 +104,6 @@ def get_wiki_summary(term):
88
 
89
  print(f"📝 Aranacak terimler: {search_terms}")
90
 
91
- # Headers
92
  headers = {
93
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
94
  'Accept': 'application/json',
@@ -99,8 +114,9 @@ def get_wiki_summary(term):
99
  print(f"🔎 '{search_term}' aranıyor...")
100
 
101
  try:
102
- # 1. Önce sayfayı doğrudan kontrol et
103
  url = "https://tr.wikipedia.org/w/api.php"
 
 
104
  params = {
105
  "action": "query",
106
  "format": "json",
@@ -124,12 +140,11 @@ def get_wiki_summary(term):
124
  extract = page_info.get('extract', '')
125
  if extract and len(extract) > 20:
126
  print(f"✅ Doğrudan sayfa bulundu: '{search_term}'")
127
- print(f" {extract[:100]}...")
128
  return extract
129
- except json.JSONDecodeError:
130
- print(f"⚠️ JSON hatası, devam ediliyor...")
131
 
132
- # 2. Doğrudan bulunamazsa arama yap
133
  search_params = {
134
  "action": "query",
135
  "format": "json",
@@ -147,49 +162,38 @@ def get_wiki_summary(term):
147
  search_data = search_response.json()
148
  search_results = search_data.get('query', {}).get('search', [])
149
 
150
- if search_results:
151
- print(f"📊 '{search_term}' -> {len(search_results)} sonuç")
152
-
153
- for result in search_results:
154
- title = result.get('title', '')
155
- if title:
156
- print(f"📄 '{title}' deneniyor...")
157
-
158
- # Sayfa özetini al
159
- summary_params = {
160
- "action": "query",
161
- "format": "json",
162
- "titles": title,
163
- "prop": "extracts",
164
- "exintro": True,
165
- "explaintext": True,
166
- "exsentences": 3,
167
- "origin": "*"
168
- }
169
-
170
- summary_response = requests.get(url, params=summary_params, headers=headers, timeout=10, verify=False)
171
-
172
- if summary_response.status_code == 200:
173
- try:
174
- summary_data = summary_response.json()
175
- pages = summary_data.get('query', {}).get('pages', {})
176
-
177
- for page_id, page_info in pages.items():
178
- if page_id != "-1":
179
- extract = page_info.get('extract', '')
180
- if extract and len(extract) > 20:
181
- print(f"✅ '{search_term}' -> '{title}' bulundu")
182
- print(f" {extract[:100]}...")
183
- return extract
184
- except json.JSONDecodeError:
185
- print(f"⚠️ JSON hatası")
186
-
187
- except json.JSONDecodeError:
188
- print(f"⚠️ Arama JSON hatası")
189
 
190
- except requests.exceptions.RequestException as e:
191
- print(f"⚠️ Request hatası: {str(e)[:50]}")
192
- continue
193
  except Exception as e:
194
  print(f"⚠️ Hata: {str(e)[:50]}")
195
  continue
@@ -233,7 +237,7 @@ def test_wikipedia_connection():
233
  break
234
  else:
235
  logs.append(f"⚠️ Sayfa bulunamadı")
236
- except json.JSONDecodeError:
237
  logs.append(f"❌ JSON parse hatası")
238
  else:
239
  logs.append(f"❌ API hatası: {response.status_code}")
@@ -243,26 +247,24 @@ def test_wikipedia_connection():
243
 
244
  return "\n".join(logs)
245
 
246
- # --- 3. LLM ANALİZ FONKSİYONU (RUNTIME ERROR KESİN ÇÖZÜM) ---
247
 
248
  @spaces.GPU
249
  def refine_label_with_llm(entity_text, full_sentence, wiki_context, custom_label_definitions):
250
- """LLM ile etiket analizi yapar - RuntimeError kesin çözüm"""
251
- global llm_model, IS_LLM_ENABLED
252
 
253
  if not IS_LLM_ENABLED or llm_model is None:
254
  return "MISC", "LLM Aktif Değil"
255
 
256
  try:
257
- print(f"\n🧠 LLM analizi: '{entity_text}'")
258
 
259
- # Modelin CPU'da olduğundan emin ol
260
- try:
261
- # Modeli CPU'ya taşı (güvenlik için)
262
  llm_model.to("cpu")
263
- torch.cuda.empty_cache() if torch.cuda.is_available() else None
264
- except:
265
- pass
266
 
267
  # Etiket Tanımları
268
  label_rules = ""
@@ -270,101 +272,90 @@ def refine_label_with_llm(entity_text, full_sentence, wiki_context, custom_label
270
  anahtar_kelimeler = ', '.join(v['anahtar_kelimeler'])
271
  label_rules += f"### {k}\n- TANIM: {v['tanim']}\n- ANAHTARLAR: {anahtar_kelimeler}\n\n"
272
 
273
- # Prompt oluştur
274
- prompt = f"""Sen yüksek hassasiyetli bir semantik analiz uzmanısın.
275
- Görevin, '[[{entity_text}]]' varlığını aşağıdaki 4 adımlı Sistematik CoT protokolüne göre sınıflandırmaktır.
 
 
 
 
 
 
 
276
 
277
- ETİKET TANIMLARI:
278
  {label_rules}
279
 
280
- SİSTEMATİK CoT ADIMLARI:
281
- 1. **Sentaktik İnceleme:** Cümle içinde varlığın sağındaki ve solundaki kelimeleri (niteleyicileri) tespit et.
282
- 2. **Bilgi Entegrasyonu:** Wikipedia verisindeki genel tanımı oku.
283
- 3. **Çelişki ve Hiyerarşi Denetimi:** Wikipedia bilgisi ile cümledeki kullanım amacı çelişiyor mu?
284
- 4. **Etiket Eşleşmesi:** Elde edilen nihai kanıtları, 'ETİKET TANIMLARI'ndaki en yakın kategoriyle eşleştir.
285
-
286
- REFERANS ANALİZLER (FEW-SHOT):
287
- Örnek 1 (Tam Uyum):
288
- VARLIK: 'Inception'
289
- CÜMLE: "Dün gece Inception filmini tekrar izledim."
290
- WIKI: "Inception, Christopher Nolan tarafından yönetilen 2010 yapımı bilimkurgu filmidir."
291
- ANALİZ:
292
- - Adım 1: Cümlede 'film' ve 'izlemek' kelimeleri görsel esere işaret ediyor.
293
- - Adım 2: Wiki verisi varlığın bir film olduğunu doğruluyor.
294
- - Adım 3: Kaynaklar arasında çelişki yok.
295
- - Adım 4: MOVIE etiketi uygundur.
296
- CEVAP: MOVIE
297
-
298
- Örnek 2 (Kritik Çelişki):
299
- VARLIK: 'Gizli Bahçe'
300
- CÜMLE: "Yazar son romanı 'Gizli Bahçe' ile ödül aldı."
301
- WIKI: "Gizli Bahçe: 1993 yapımı bir dram filmidir."
302
- ANALİZ:
303
- - Adım 1: Cümlede 'roman' ve 'yazar' kelimeleri varlığı doğrudan kitap olarak niteliyor.
304
- - Adım 2: Wiki verisi bu ismi bir film (movie) olarak gösteriyor.
305
- - Adım 3: ÇELİŞKİ TESPİT EDİLDİ. Kaynak hiyerarşisi gereği cümledeki 'roman' ifadesi Wikipedia'dan daha önceliklidir.
306
- - Adım 4: BOOK etiketi uygundur.
307
- CEVAP: BOOK
308
-
309
- GÜNCEL GÖREV:
310
- - HEDEF VARLIK: {entity_text}
311
- - ORİJİNAL CÜMLE: "{full_sentence}"
312
- - HARİCİ BİLGİ (Wikipedia): "{wiki_context}"
313
-
314
- ÇIKTI KURALLARI:
315
- - Cevabında asla yıldız (*) veya markdown kullanma.
316
- - Analiz adımlarını yukarıdaki 4 adımlı protokole göre yaz.
317
-
318
- ÇIKTI FORMATI:
319
- Analiz: [4 Adımlı CoT Analizi]
320
- Cevap: [SADECE_ETIKET_ADI]"""
321
 
322
- # Tokenize et
323
- messages = [{"role": "user", "content": prompt}]
324
- text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
325
-
326
- # Tokenizer'ı CPU'da çalıştır
327
- model_inputs = tokenizer([text], return_tensors="pt", padding=True, truncation=True)
328
- model_inputs = {k: v.to("cpu") for k, v in model_inputs.items()}
329
 
330
- print(f"🔄 LLM generate başlatılıyor... (CPU)")
 
 
 
 
 
 
 
 
331
 
332
- # Generate işlemi - CPU'da
333
  with torch.no_grad():
334
- generated_ids = llm_model.generate(
335
- model_inputs.input_ids,
336
- max_new_tokens=450,
337
  do_sample=False,
338
  temperature=0.1,
 
339
  pad_token_id=tokenizer.eos_token_id,
340
  eos_token_id=tokenizer.eos_token_id,
341
  repetition_penalty=1.1
342
  )
343
 
344
  # Çıktıyı decode et
345
- response_ids = generated_ids[0][len(model_inputs.input_ids[0]):]
346
- full_output = tokenizer.decode(response_ids, skip_special_tokens=True).strip()
 
 
 
 
 
 
 
347
 
348
- print(f"✅ LLM çıktısı alındı")
349
- print(f"📝 Çıktı: {full_output[:100]}...")
350
 
351
  # Etiket Ayıklama
352
- clean_output = full_output.replace("*", "")
353
  final_label = "MISC"
354
  valid_keys = list(custom_label_definitions.keys())
355
- match = re.search(r"Cevap:\s*([A-Z_]+)", clean_output, re.IGNORECASE)
356
 
357
- if match:
358
- extracted = match.group(1).upper().strip()
359
- if extracted in valid_keys:
360
- final_label = extracted
361
- print(f"🏷️ Etiket: {final_label}")
362
- else:
363
- print(f"⚠️ Geçersiz etiket: {extracted}")
364
- else:
365
- print(f"⚠️ Etiket bulunamadı, MISC atanıyor")
366
-
367
- return final_label, clean_output
 
 
 
 
 
 
368
 
369
  except RuntimeError as e:
370
  print(f"❌ RuntimeError: {str(e)}")
@@ -448,13 +439,13 @@ def process_ner(text):
448
 
449
  if wiki_text and IS_LLM_ENABLED:
450
  try:
451
- current_logs.append(f"🧠 <b>LLM analizi başlatılıyor:</b> '{word}'")
452
  yield "<br>".join(current_logs), [[r["Varlık"], r["İlk Etiket"], r["Nihai Etiket"], r["Kaynak"]] for r in final_results]
453
 
454
  new_label, cot_text = refine_label_with_llm(word, text, wiki_text, custom_labels)
455
 
456
  cot_preview = cot_text[:300] + "..." if len(cot_text) > 300 else cot_text
457
- current_logs.append(f"🧠 <b>CoT Analizi:</b> {cot_preview}")
458
 
459
  res = {"Varlık": word, "İlk Etiket": label, "Nihai Etiket": new_label, "Kaynak": "RAG+LLM"}
460
  current_logs.append(f"🏷️ <b>Nihai Etiket:</b> {new_label}")
@@ -503,9 +494,9 @@ def test_single_term(term):
503
  return "\n".join(logs)
504
 
505
  def check_llm_status():
506
- global IS_LLM_ENABLED, llm_model
507
 
508
- logs = ["=== LLM DURUM KONTROLÜ ==="]
509
  logs.append(f"LLM Aktif: {IS_LLM_ENABLED}")
510
  logs.append(f"Model: {model_id}")
511
 
@@ -516,17 +507,19 @@ def check_llm_status():
516
  logs.append(f"Device: {device}")
517
  logs.append(f"Dtype: {dtype}")
518
  logs.append(f"CUDA Kullanılabilir: {torch.cuda.is_available()}")
 
519
  except Exception as e:
520
  logs.append(f"Device kontrol hatası: {str(e)}")
521
  else:
522
- logs.append("Model yüklenmemiş!")
523
 
524
  return "\n".join(logs)
525
 
526
  # --- 6. GRADIO ARAYÜZÜ ---
527
 
528
  with gr.Blocks(title="RAG-NER Uzman Karar Destek Sistemi") as demo:
529
- gr.Markdown("# 🚀 RAG-NER Uzman Karar Destek Sistemi (Türkçe Wikipedia)")
 
530
 
531
  with gr.Tab("Metin Analizi"):
532
  input_text = gr.Textbox(
@@ -587,11 +580,11 @@ with gr.Blocks(title="RAG-NER Uzman Karar Destek Sistemi") as demo:
587
  )
588
  single_term_btn.click(test_single_term, inputs=single_term_input, outputs=single_term_output)
589
 
590
- gr.Markdown("### 🧠 LLM Durum Kontrolü")
591
  with gr.Row():
592
- llm_status_btn = gr.Button("LLM Durumunu Kontrol Et", variant="secondary")
593
  llm_status_output = gr.Textbox(
594
- label="LLM Durumu",
595
  lines=8,
596
  interactive=False
597
  )
@@ -608,7 +601,7 @@ if __name__ == "__main__":
608
  test_result = test_wikipedia_connection()
609
  print(test_result)
610
 
611
- print("\n🧠 LLM durumu kontrol ediliyor...")
612
  print(check_llm_status())
613
 
614
  print("\n" + "="*50)
 
15
 
16
  # --- 1. MODELLERİN HAZIRLANMASI ---
17
  ner_pipe = pipeline("ner", model="xlm-roberta-large-finetuned-conll03-english", aggregation_strategy="simple", device=-1)
18
+
19
+ # Qwen modeli
20
  model_id = "Qwen/Qwen2.5-7B-Instruct"
 
21
 
22
+ # Tokenizer'ı yükle
23
+ tokenizer = AutoTokenizer.from_pretrained(
24
+ model_id,
25
+ trust_remote_code=True,
26
+ padding_side="left"
27
+ )
28
+
29
+ # Eğer tokenizer'da pad_token yoksa eos_token'u kullan
30
+ if tokenizer.pad_token is None:
31
+ tokenizer.pad_token = tokenizer.eos_token
32
+
33
+ # LLM modelini yükle
34
  llm_model = None
35
  IS_LLM_ENABLED = False
36
 
37
  try:
38
+ print("📦 Qwen LLM modeli yükleniyor...")
39
+ print("⚠️ Bu işlem 7B model olduğu için biraz zaman alabilir...")
40
 
41
+ # Qwen için özel yükleme
42
  llm_model = AutoModelForCausalLM.from_pretrained(
43
+ model_id,
44
+ torch_dtype=torch.float16, # float16 daha hızlı
45
+ device_map="cpu", # CPU'da çalıştır
46
  trust_remote_code=True,
47
  low_cpu_mem_usage=True
48
  )
 
50
  # Modeli evaluation moduna al
51
  llm_model.eval()
52
 
53
+ # Device kontrolü
54
  device = next(llm_model.parameters()).device
55
+ print(f"✅ Qwen modeli yüklendi! Device: {device}")
56
  print(f" Model dtype: {next(llm_model.parameters()).dtype}")
57
 
58
  IS_LLM_ENABLED = True
59
 
60
  except Exception as e:
61
  IS_LLM_ENABLED = False
62
+ print(f"⚠️ Qwen yüklenemedi: {e}")
63
  print(traceback.format_exc())
64
 
65
+ # --- 2. WIKIPEDIA API ---
66
 
67
  def get_wiki_summary(term):
68
  """Türkçe Wikipedia'dan doğrudan API ile özet getirir"""
 
82
  "Nobel": "Nobel Ödülü",
83
  "Amerika": "Amerika",
84
  "1984": "1984 (roman)",
85
+ "Apple": "Apple (şirket)",
86
+ "Windows": "Microsoft Windows",
87
+ "Linux": "Linux",
88
+ "Python": "Python (programlama dili)",
89
  }
90
 
91
  # Arama terimlerini hazırla
 
95
  search_terms = [value, term]
96
  break
97
 
 
98
  if len(search_terms) == 1:
99
  if term.endswith("lar") or term.endswith("ler"):
100
  search_terms.append(term[:-3])
 
104
 
105
  print(f"📝 Aranacak terimler: {search_terms}")
106
 
 
107
  headers = {
108
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
109
  'Accept': 'application/json',
 
114
  print(f"🔎 '{search_term}' aranıyor...")
115
 
116
  try:
 
117
  url = "https://tr.wikipedia.org/w/api.php"
118
+
119
+ # Doğrudan sayfa kontrolü
120
  params = {
121
  "action": "query",
122
  "format": "json",
 
140
  extract = page_info.get('extract', '')
141
  if extract and len(extract) > 20:
142
  print(f"✅ Doğrudan sayfa bulundu: '{search_term}'")
 
143
  return extract
144
+ except:
145
+ pass
146
 
147
+ # Arama yap
148
  search_params = {
149
  "action": "query",
150
  "format": "json",
 
162
  search_data = search_response.json()
163
  search_results = search_data.get('query', {}).get('search', [])
164
 
165
+ for result in search_results:
166
+ title = result.get('title', '')
167
+ if title:
168
+ summary_params = {
169
+ "action": "query",
170
+ "format": "json",
171
+ "titles": title,
172
+ "prop": "extracts",
173
+ "exintro": True,
174
+ "explaintext": True,
175
+ "exsentences": 3,
176
+ "origin": "*"
177
+ }
178
+
179
+ summary_response = requests.get(url, params=summary_params, headers=headers, timeout=10, verify=False)
180
+
181
+ if summary_response.status_code == 200:
182
+ try:
183
+ summary_data = summary_response.json()
184
+ pages = summary_data.get('query', {}).get('pages', {})
185
+
186
+ for page_id, page_info in pages.items():
187
+ if page_id != "-1":
188
+ extract = page_info.get('extract', '')
189
+ if extract and len(extract) > 20:
190
+ print(f"✅ '{search_term}' -> '{title}' bulundu")
191
+ return extract
192
+ except:
193
+ pass
194
+ except:
195
+ pass
 
 
 
 
 
 
 
 
196
 
 
 
 
197
  except Exception as e:
198
  print(f"⚠️ Hata: {str(e)[:50]}")
199
  continue
 
237
  break
238
  else:
239
  logs.append(f"⚠️ Sayfa bulunamadı")
240
+ except:
241
  logs.append(f"❌ JSON parse hatası")
242
  else:
243
  logs.append(f"❌ API hatası: {response.status_code}")
 
247
 
248
  return "\n".join(logs)
249
 
250
+ # --- 3. LLM ANALİZ FONKSİYONU (QWEN İÇİN OPTİMİZE) ---
251
 
252
  @spaces.GPU
253
  def refine_label_with_llm(entity_text, full_sentence, wiki_context, custom_label_definitions):
254
+ """Qwen ile etiket analizi yapar - RuntimeError çözümlü"""
255
+ global llm_model, IS_LLM_ENABLED, tokenizer
256
 
257
  if not IS_LLM_ENABLED or llm_model is None:
258
  return "MISC", "LLM Aktif Değil"
259
 
260
  try:
261
+ print(f"\n🧠 Qwen LLM analizi: '{entity_text}'")
262
 
263
+ # Modeli CPU'da tut
264
+ if next(llm_model.parameters()).device.type != "cpu":
 
265
  llm_model.to("cpu")
266
+ if torch.cuda.is_available():
267
+ torch.cuda.empty_cache()
 
268
 
269
  # Etiket Tanımları
270
  label_rules = ""
 
272
  anahtar_kelimeler = ', '.join(v['anahtar_kelimeler'])
273
  label_rules += f"### {k}\n- TANIM: {v['tanim']}\n- ANAHTARLAR: {anahtar_kelimeler}\n\n"
274
 
275
+ # Qwen için özel prompt formatı
276
+ prompt = f"""<|im_start|>system
277
+ Sen bir NER (Named Entity Recognition) uzmanısın. Verilen varlığı analiz et ve doğru kategoriyi belirle.
278
+ <|im_end|>
279
+ <|im_start|>user
280
+ Aşağıdaki varlığı analiz et ve hangi kategoriye ait olduğunu söyle.
281
+
282
+ VARLIK: {entity_text}
283
+ CÜMLE: {full_sentence}
284
+ WIKIPEDIA BİLGİSİ: {wiki_context}
285
 
286
+ KATEGORİLER VE TANIMLARI:
287
  {label_rules}
288
 
289
+ Kurallar:
290
+ 1. Cümledeki bağlama göre karar ver
291
+ 2. Wikipedia bilgisiyle karşılaştır
292
+ 3. Çelişki varsa cümledeki kullanıma öncelik ver
293
+ 4. Sadece kategori adını yaz (MOVIE, BOOK, SOFTWARE, AWARD, PRODUCT, NORP, GPE)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
294
 
295
+ CEVAP:
296
+ <|im_end|>
297
+ <|im_start|>assistant
298
+ """
299
+
300
+ print(f"🔄 Qwen generate başlatılıyor...")
 
301
 
302
+ # Tokenize et
303
+ inputs = tokenizer(
304
+ prompt,
305
+ return_tensors="pt",
306
+ truncation=True,
307
+ max_length=2048,
308
+ padding=True
309
+ )
310
+ inputs = {k: v.to("cpu") for k, v in inputs.items()}
311
 
312
+ # Generate - CPU'da
313
  with torch.no_grad():
314
+ outputs = llm_model.generate(
315
+ inputs.input_ids,
316
+ max_new_tokens=200,
317
  do_sample=False,
318
  temperature=0.1,
319
+ top_p=0.9,
320
  pad_token_id=tokenizer.eos_token_id,
321
  eos_token_id=tokenizer.eos_token_id,
322
  repetition_penalty=1.1
323
  )
324
 
325
  # Çıktıyı decode et
326
+ full_output = tokenizer.decode(outputs[0], skip_special_tokens=True)
327
+
328
+ print(f"✅ Qwen çıktısı alındı")
329
+
330
+ # Assistant kısmını bul
331
+ if "<|im_start|>assistant" in full_output:
332
+ response = full_output.split("<|im_start|>assistant")[-1].strip()
333
+ else:
334
+ response = full_output[len(prompt):].strip()
335
 
336
+ print(f"📝 Çıktı: {response[:200]}...")
 
337
 
338
  # Etiket Ayıklama
 
339
  final_label = "MISC"
340
  valid_keys = list(custom_label_definitions.keys())
 
341
 
342
+ # Regex ile etiket bul
343
+ for label in valid_keys:
344
+ if re.search(rf'\b{label}\b', response, re.IGNORECASE):
345
+ final_label = label
346
+ print(f"🏷️ Etiket bulundu: {final_label}")
347
+ break
348
+
349
+ # Eğer bulunamadıysa, tüm kelimeleri kontrol et
350
+ if final_label == "MISC":
351
+ words = re.findall(r'[A-Z_]+', response.upper())
352
+ for word in words:
353
+ if word in valid_keys:
354
+ final_label = word
355
+ print(f"🏷️ Kelime eşleşmesi: {final_label}")
356
+ break
357
+
358
+ return final_label, response
359
 
360
  except RuntimeError as e:
361
  print(f"❌ RuntimeError: {str(e)}")
 
439
 
440
  if wiki_text and IS_LLM_ENABLED:
441
  try:
442
+ current_logs.append(f"🧠 <b>Qwen LLM analizi başlatılıyor:</b> '{word}' (Bu işlem biraz zaman alabilir...)")
443
  yield "<br>".join(current_logs), [[r["Varlık"], r["İlk Etiket"], r["Nihai Etiket"], r["Kaynak"]] for r in final_results]
444
 
445
  new_label, cot_text = refine_label_with_llm(word, text, wiki_text, custom_labels)
446
 
447
  cot_preview = cot_text[:300] + "..." if len(cot_text) > 300 else cot_text
448
+ current_logs.append(f"🧠 <b>LLM Çıktısı:</b> {cot_preview}")
449
 
450
  res = {"Varlık": word, "İlk Etiket": label, "Nihai Etiket": new_label, "Kaynak": "RAG+LLM"}
451
  current_logs.append(f"🏷️ <b>Nihai Etiket:</b> {new_label}")
 
494
  return "\n".join(logs)
495
 
496
  def check_llm_status():
497
+ global IS_LLM_ENABLED, llm_model, model_id
498
 
499
+ logs = ["=== Qwen LLM DURUM KONTROLÜ ==="]
500
  logs.append(f"LLM Aktif: {IS_LLM_ENABLED}")
501
  logs.append(f"Model: {model_id}")
502
 
 
507
  logs.append(f"Device: {device}")
508
  logs.append(f"Dtype: {dtype}")
509
  logs.append(f"CUDA Kullanılabilir: {torch.cuda.is_available()}")
510
+ logs.append(f"Model Boyutu: {sum(p.numel() for p in llm_model.parameters()):,} parametre")
511
  except Exception as e:
512
  logs.append(f"Device kontrol hatası: {str(e)}")
513
  else:
514
+ logs.append("❌ Model yüklenmemiş!")
515
 
516
  return "\n".join(logs)
517
 
518
  # --- 6. GRADIO ARAYÜZÜ ---
519
 
520
  with gr.Blocks(title="RAG-NER Uzman Karar Destek Sistemi") as demo:
521
+ gr.Markdown("# 🚀 RAG-NER Uzman Karar Destek Sistemi (Türkçe Wikipedia + Qwen)")
522
+ gr.Markdown(f"**LLM Modeli:** {model_id}")
523
 
524
  with gr.Tab("Metin Analizi"):
525
  input_text = gr.Textbox(
 
580
  )
581
  single_term_btn.click(test_single_term, inputs=single_term_input, outputs=single_term_output)
582
 
583
+ gr.Markdown("### 🧠 Qwen LLM Durum Kontrolü")
584
  with gr.Row():
585
+ llm_status_btn = gr.Button("Qwen Durumunu Kontrol Et", variant="secondary")
586
  llm_status_output = gr.Textbox(
587
+ label="Qwen Durumu",
588
  lines=8,
589
  interactive=False
590
  )
 
601
  test_result = test_wikipedia_connection()
602
  print(test_result)
603
 
604
+ print("\n🧠 Qwen LLM durumu kontrol ediliyor...")
605
  print(check_llm_status())
606
 
607
  print("\n" + "="*50)