apak commited on
Commit
6e7e856
·
verified ·
1 Parent(s): 0f5d834

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +495 -113
app.py CHANGED
@@ -19,42 +19,33 @@ ner_pipe = pipeline("ner", model="xlm-roberta-large-finetuned-conll03-english",
19
  model_id = "Qwen/Qwen2.5-1.5B-Instruct"
20
  tokenizer = AutoTokenizer.from_pretrained(model_id)
21
 
22
- # LLM modelini global olarak yükle - RUNTIME ERROR ÇÖZÜMÜ
23
  llm_model = None
24
  IS_LLM_ENABLED = False
25
 
26
  try:
27
  print("📦 LLM modeli yükleniyor...")
28
-
29
- # ÖNEMLİ: Modeli doğrudan CPU'da yükle
30
  llm_model = AutoModelForCausalLM.from_pretrained(
31
  model_id,
32
- torch_dtype=torch.float32, # bfloat16 yerine float32 kullan (daha kararlı)
33
- device_map=None, # None kullan, manuel device kontrolü yap
34
  trust_remote_code=True,
35
- low_cpu_mem_usage=True # Memory optimizasyonu
36
  )
37
-
38
- # Modeli CPU'ya taşı
39
  llm_model = llm_model.to("cpu")
40
- llm_model.eval() # Evaluation modu
41
-
42
  IS_LLM_ENABLED = True
43
  print(f"✅ LLM modeli yüklendi! Device: {next(llm_model.parameters()).device}")
44
- print(f" Model dtype: {next(llm_model.parameters()).dtype}")
45
-
46
  except Exception as e:
47
  IS_LLM_ENABLED = False
48
  print(f"⚠️ LLM yüklenemedi: {e}")
49
- print(traceback.format_exc())
50
 
51
- # --- 2. WIKIPEDIA FONKSİYONLARI (SADECE TÜRKÇE) ---
52
 
53
  def test_wikipedia_connection():
54
- """Wikipedia bağlantısını ve fonksiyonelliğini test et - Sadece Türkçe"""
55
  logs = []
56
 
57
- # 1. Modül kontrolü
58
  try:
59
  import wikipedia
60
  logs.append(f"✅ Wikipedia modülü yüklü: {wikipedia.__version__}")
@@ -62,7 +53,6 @@ def test_wikipedia_connection():
62
  logs.append(f"❌ Wikipedia modülü yüklü değil: {e}")
63
  return "\n".join(logs)
64
 
65
- # 2. İnternet bağlantısı kontrolü
66
  try:
67
  response = requests.get("https://tr.wikipedia.org", timeout=5, verify=False)
68
  logs.append(f"✅ İnternet bağlantısı var: {response.status_code}")
@@ -70,114 +60,143 @@ def test_wikipedia_connection():
70
  logs.append(f"❌ İnternet bağlantısı yok: {e}")
71
  return "\n".join(logs)
72
 
73
- # 3. Türkçe Wikipedia'ya erişim
74
  try:
75
  session = requests.Session()
76
  session.verify = False
77
  session.headers.update({
78
- 'User-Agent': 'Mozilla/5.0 (compatible; RAG-NER-System/1.0; +https://huggingface.co/spaces)'
79
  })
80
  wikipedia.wikipedia._session = session
81
 
82
  wikipedia.set_lang("tr")
83
- test_term = "Türkiye"
84
 
85
- logs.append(f"🔍 '{test_term}' aranıyor (Türkçe Wikipedia)...")
86
- search_results = wikipedia.search(test_term)
87
- logs.append(f"📊 Arama sonucu: {len(search_results)} sonuç")
88
-
89
- if search_results:
90
- logs.append(f"📄 İlk sonuç: '{search_results[0]}'")
91
  try:
92
- summary = wikipedia.summary(search_results[0], sentences=2, auto_suggest=False)
93
- logs.append(f"✅ Özet alındı: {summary[:100]}...")
 
 
 
 
 
94
  except Exception as e:
95
- logs.append(f"❌ Özet alınamadı: {str(e)}")
96
- else:
97
- logs.append(f"❌ Arama sonucu boş!")
98
-
99
  except Exception as e:
100
- logs.append(f"❌ Türkçe Wikipedia hatası: {str(e)}")
101
 
102
  return "\n".join(logs)
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  def get_wiki_summary(term):
105
- """Varlık için Türkçe Wikipedia özeti getirir - Sadece Türkçe"""
106
  import wikipedia
107
- import traceback
108
 
109
  print(f"\n{'='*50}")
110
- print(f"🔍 Türkçe Wikipedia sorgusu başladı: '{term}'")
111
 
112
  try:
113
  # Özel session oluştur
114
  session = requests.Session()
115
  session.verify = False
116
  session.headers.update({
117
- 'User-Agent': 'Mozilla/5.0 (compatible; RAG-NER-System/1.0; +https://huggingface.co/spaces)'
118
  })
119
-
120
- # Wikipedia modülünün session'ını değiştir
121
  wikipedia.wikipedia._session = session
122
-
123
- # Sadece Türkçe Wikipedia
124
  wikipedia.set_lang("tr")
125
- print(f"🌐 Dil: Türkçe")
126
 
127
- # 1. YÖNTEM: Doğrudan sayfa kontrolü
128
- try:
129
- print(f"📖 Doğrudan sayfa aranıyor: '{term}'")
130
- page = wikipedia.page(term, auto_suggest=False)
131
- if page:
132
- summary = page.summary
133
- sentences = summary.split('.')[:3]
134
- result = '.'.join(sentences) + '.'
135
- if len(result) > 20:
136
- print(f"✅ Doğrudan sayfa bulundu: {result[:100]}...")
137
- return result
138
- except wikipedia.exceptions.DisambiguationError as e:
139
- print(f"⚠️ Anlam karmaşası: {e.options[:3]}")
140
- for option in e.options[:3]:
141
  try:
142
- page = wikipedia.page(option, auto_suggest=False)
143
- summary = page.summary
144
- sentences = summary.split('.')[:3]
145
- result = '.'.join(sentences) + '.'
146
- if len(result) > 20:
147
- print(f"✅ Anlam karmaşası çözüldü: '{option}' -> {result[:100]}...")
148
- return result
 
 
149
  except:
150
- continue
151
- except wikipedia.exceptions.PageError:
152
- print(f"⚠️ Sayfa bulunamadı, arama yapılıyor...")
153
-
154
- # 2. YÖNTEM: Arama yap
155
- print(f"🔎 Arama yapılıyor: '{term}'")
156
- search_results = wikipedia.search(term, results=5)
157
- print(f"📊 Arama sonuçları: {len(search_results)} adet")
158
-
159
- if search_results:
160
- print(f"📄 İlk sonuç: '{search_results[0]}'")
161
- for title in search_results:
162
- try:
163
- page = wikipedia.page(title, auto_suggest=False)
164
- summary = page.summary
165
- sentences = summary.split('.')[:3]
166
- result = '.'.join(sentences) + '.'
167
- if len(result) > 20:
168
- print(f"✅ Arama sonucu özet alındı: '{title}' -> {result[:100]}...")
169
- return result
170
- except Exception as e:
171
- print(f"⚠️ '{title}' alınamadı: {str(e)[:50]}")
172
- continue
 
 
173
 
 
174
  print(f"❌ '{term}' için Türkçe Wikipedia'da sonuç bulunamadı")
175
  return None
176
 
177
  except Exception as e:
178
- print(f"❌ BEKLENMEYEN HATA: {type(e).__name__}")
179
- print(f" Mesaj: {str(e)}")
180
- print(f" Traceback: {traceback.format_exc()}")
181
  return None
182
  finally:
183
  print(f"{'='*50}\n")
@@ -189,39 +208,402 @@ def refine_label_with_llm(entity_text, full_sentence, wiki_context, custom_label
189
  """LLM ile etiket analizi yapar - RuntimeError tamamen çözüldü"""
190
  global llm_model, IS_LLM_ENABLED
191
 
192
- # LLM kontrolü
193
  if not IS_LLM_ENABLED or llm_model is None:
194
- print("⚠️ LLM aktif değil veya yüklenmemiş")
195
  return "MISC", "LLM Aktif Değil"
196
 
197
  try:
198
  print(f"\n{'='*50}")
199
- print(f"🧠 LLM analizi başlatılıyor: '{entity_text}'")
200
-
201
- # Device kontrolü - SADECE CPU KULLAN (kararlılık için)
202
- device = "cpu"
203
- print(f"🖥️ Kullanılan device: {device}")
204
 
205
- # Modelin device'ını kontrol et
206
  try:
207
  current_device = next(llm_model.parameters()).device
208
- print(f"📌 Model mevcut device: {current_device}")
209
-
210
- # Eğer model CPU'da değilse CPU'ya taşı
211
  if str(current_device) != "cpu":
212
- print(f"🔄 Model CPU'ya taşınıyor...")
213
  llm_model.to("cpu")
214
- torch.cuda.empty_cache() if torch.cuda.is_available() else None
215
- print(f"✅ Model CPU'ya taşındı")
216
- except Exception as e:
217
- print(f"⚠️ Device kontrol hatası: {e}")
218
- # Hata durumunda modeli CPU'ya taşı
219
- try:
220
- llm_model.to("cpu")
221
- except:
222
- pass
223
-
224
- # 1. Etiket Tanımları
225
  label_rules = ""
226
  for k, v in custom_label_definitions.items():
227
- label_rules += f"### {k}\n- TANIM: {v['tanim']}\n- ANAHTARLAR: {', '.join(v['anahtar_kelime
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  model_id = "Qwen/Qwen2.5-1.5B-Instruct"
20
  tokenizer = AutoTokenizer.from_pretrained(model_id)
21
 
22
+ # LLM modelini global olarak yükle
23
  llm_model = None
24
  IS_LLM_ENABLED = False
25
 
26
  try:
27
  print("📦 LLM modeli yükleniyor...")
 
 
28
  llm_model = AutoModelForCausalLM.from_pretrained(
29
  model_id,
30
+ torch_dtype=torch.float32,
31
+ device_map=None,
32
  trust_remote_code=True,
33
+ low_cpu_mem_usage=True
34
  )
 
 
35
  llm_model = llm_model.to("cpu")
36
+ llm_model.eval()
 
37
  IS_LLM_ENABLED = True
38
  print(f"✅ LLM modeli yüklendi! Device: {next(llm_model.parameters()).device}")
 
 
39
  except Exception as e:
40
  IS_LLM_ENABLED = False
41
  print(f"⚠️ LLM yüklenemedi: {e}")
 
42
 
43
+ # --- 2. WIKIPEDIA FONKSİYONLARI (GELİŞMİŞ ARAMA) ---
44
 
45
  def test_wikipedia_connection():
46
+ """Wikipedia bağlantısını test et"""
47
  logs = []
48
 
 
49
  try:
50
  import wikipedia
51
  logs.append(f"✅ Wikipedia modülü yüklü: {wikipedia.__version__}")
 
53
  logs.append(f"❌ Wikipedia modülü yüklü değil: {e}")
54
  return "\n".join(logs)
55
 
 
56
  try:
57
  response = requests.get("https://tr.wikipedia.org", timeout=5, verify=False)
58
  logs.append(f"✅ İnternet bağlantısı var: {response.status_code}")
 
60
  logs.append(f"❌ İnternet bağlantısı yok: {e}")
61
  return "\n".join(logs)
62
 
 
63
  try:
64
  session = requests.Session()
65
  session.verify = False
66
  session.headers.update({
67
+ 'User-Agent': 'Mozilla/5.0 (compatible; RAG-NER-System/1.0)'
68
  })
69
  wikipedia.wikipedia._session = session
70
 
71
  wikipedia.set_lang("tr")
72
+ test_terms = ["Türkiye", "İstanbul", "Mustafa Kemal Atatürk"]
73
 
74
+ for term in test_terms:
 
 
 
 
 
75
  try:
76
+ search_results = wikipedia.search(term)
77
+ if search_results:
78
+ summary = wikipedia.summary(search_results[0], sentences=1, auto_suggest=False)
79
+ logs.append(f"✅ '{term}' -> '{search_results[0]}' (başarılı)")
80
+ else:
81
+ logs.append(f"❌ '{term}' -> sonuç yok")
82
+ time.sleep(0.3)
83
  except Exception as e:
84
+ logs.append(f"❌ '{term}' -> hata: {str(e)[:50]}")
85
+
 
 
86
  except Exception as e:
87
+ logs.append(f"❌ Wikipedia hatası: {str(e)}")
88
 
89
  return "\n".join(logs)
90
 
91
+ def improve_search_term(term):
92
+ """Arama terimini iyileştir - Daha fazla eşleşme için"""
93
+ # Özel terim dönüşümleri
94
+ special_cases = {
95
+ "Türk": "Türkler",
96
+ "Türkler": "Türkler",
97
+ "Altın Aslan": "Altın Aslan Ödülü",
98
+ "Venedik Film Festivali": "Venedik Film Festivali",
99
+ "Kış Uykusu": "Kış Uykusu (film)",
100
+ "Inception": "Inception (film)",
101
+ "Oscar": "Akademi Ödülü",
102
+ "Nobel": "Nobel Ödülü",
103
+ "Altın Palmiye": "Altın Palmiye",
104
+ "Cannes": "Cannes Film Festivali",
105
+ "Berlin": "Berlin Film Festivali",
106
+ }
107
+
108
+ # Özel durum kontrolü
109
+ for key, value in special_cases.items():
110
+ if term.lower() == key.lower():
111
+ return [value, term]
112
+
113
+ # Genel iyileştirmeler
114
+ improved = [term]
115
+
116
+ # Büyük harf dönüşümleri
117
+ improved.append(term.title())
118
+
119
+ # Tekil/çoğul
120
+ if term.endswith("lar") or term.endswith("ler"):
121
+ improved.append(term[:-3])
122
+ else:
123
+ improved.append(term + "lar")
124
+ improved.append(term + "ler")
125
+
126
+ # Benzersizleştir
127
+ improved = list(dict.fromkeys(improved))
128
+
129
+ return improved
130
+
131
  def get_wiki_summary(term):
132
+ """Varlık için Türkçe Wikipedia özeti getirir - Gelişmiş arama ile"""
133
  import wikipedia
 
134
 
135
  print(f"\n{'='*50}")
136
+ print(f"🔍 Türkçe Wikipedia sorgusu: '{term}'")
137
 
138
  try:
139
  # Özel session oluştur
140
  session = requests.Session()
141
  session.verify = False
142
  session.headers.update({
143
+ 'User-Agent': 'Mozilla/5.0 (compatible; RAG-NER-System/1.0)'
144
  })
 
 
145
  wikipedia.wikipedia._session = session
 
 
146
  wikipedia.set_lang("tr")
 
147
 
148
+ # Arama terimlerini iyileştir
149
+ search_terms = improve_search_term(term)
150
+ print(f"📝 Aranacak terimler: {search_terms}")
151
+
152
+ for search_term in search_terms:
153
+ print(f"🔎 '{search_term}' aranıyor...")
154
+
155
+ try:
156
+ # Önce doğrudan sayfa kontrolü
 
 
 
 
 
157
  try:
158
+ page = wikipedia.page(search_term, auto_suggest=False)
159
+ if page:
160
+ summary = page.summary
161
+ sentences = summary.split('.')[:3]
162
+ result = '.'.join(sentences) + '.'
163
+ if len(result) > 20:
164
+ print(f"✅ Doğrudan sayfa bulundu: '{search_term}'")
165
+ print(f" {result[:100]}...")
166
+ return result
167
  except:
168
+ pass
169
+
170
+ # Arama yap
171
+ search_results = wikipedia.search(search_term, results=5)
172
+ if search_results:
173
+ print(f"📊 '{search_term}' -> {len(search_results)} sonuç: {search_results[:3]}")
174
+
175
+ for title in search_results:
176
+ try:
177
+ page = wikipedia.page(title, auto_suggest=False)
178
+ summary = page.summary
179
+ sentences = summary.split('.')[:3]
180
+ result = '.'.join(sentences) + '.'
181
+ if len(result) > 20:
182
+ print(f"✅ '{search_term}' -> '{title}' bulundu")
183
+ print(f" {result[:100]}...")
184
+ return result
185
+ except:
186
+ continue
187
+
188
+ except Exception as e:
189
+ print(f"⚠️ '{search_term}' hatası: {str(e)[:50]}")
190
+ continue
191
+
192
+ time.sleep(0.3) # Rate limiting
193
 
194
+ # Hiçbir sonuç yoksa
195
  print(f"❌ '{term}' için Türkçe Wikipedia'da sonuç bulunamadı")
196
  return None
197
 
198
  except Exception as e:
199
+ print(f"❌ HATA: {str(e)}")
 
 
200
  return None
201
  finally:
202
  print(f"{'='*50}\n")
 
208
  """LLM ile etiket analizi yapar - RuntimeError tamamen çözüldü"""
209
  global llm_model, IS_LLM_ENABLED
210
 
 
211
  if not IS_LLM_ENABLED or llm_model is None:
 
212
  return "MISC", "LLM Aktif Değil"
213
 
214
  try:
215
  print(f"\n{'='*50}")
216
+ print(f"🧠 LLM analizi: '{entity_text}'")
 
 
 
 
217
 
218
+ # Model CPU'da çalışıyor, emin olalım
219
  try:
220
  current_device = next(llm_model.parameters()).device
 
 
 
221
  if str(current_device) != "cpu":
 
222
  llm_model.to("cpu")
223
+ if torch.cuda.is_available():
224
+ torch.cuda.empty_cache()
225
+ except:
226
+ pass
227
+
228
+ # Etiket Tanımları
 
 
 
 
 
229
  label_rules = ""
230
  for k, v in custom_label_definitions.items():
231
+ anahtar_kelimeler = ', '.join(v['anahtar_kelimeler'])
232
+ label_rules += f"### {k}\n- TANIM: {v['tanim']}\n- ANAHTARLAR: {anahtar_kelimeler}\n\n"
233
+
234
+ # Prompt oluştur
235
+ prompt = f"""Sen yüksek hassasiyetli bir semantik analiz uzmanısın.
236
+ Görevin, '[[{entity_text}]]' varlığını aşağıdaki 4 adımlı Sistematik CoT protokolüne göre sınıflandırmaktır.
237
+
238
+ ETİKET TANIMLARI:
239
+ {label_rules}
240
+
241
+ SİSTEMATİK CoT ADIMLARI:
242
+ 1. **Sentaktik İnceleme:** Cümle içinde varlığın sağındaki ve solundaki kelimeleri (niteleyicileri) tespit et.
243
+ 2. **Bilgi Entegrasyonu:** Wikipedia verisindeki genel tanımı oku.
244
+ 3. **Çelişki ve Hiyerarşi Denetimi:** Wikipedia bilgisi ile cümledeki kullanım amacı çelişiyor mu?
245
+ 4. **Etiket Eşleşmesi:** Elde edilen nihai kanıtları, 'ETİKET TANIMLARI'ndaki en yakın kategoriyle eşleştir.
246
+
247
+ REFERANS ANALİZLER (FEW-SHOT):
248
+ Örnek 1 (Tam Uyum):
249
+ VARLIK: 'Inception'
250
+ CÜMLE: "Dün gece Inception filmini tekrar izledim."
251
+ WIKI: "Inception, Christopher Nolan tarafından yönetilen 2010 yapımı bilimkurgu filmidir."
252
+ ANALİZ:
253
+ - Adım 1: Cümlede 'film' ve 'izlemek' kelimeleri görsel esere işaret ediyor.
254
+ - Adım 2: Wiki verisi varlığın bir film olduğunu doğruluyor.
255
+ - Adım 3: Kaynaklar arasında çelişki yok.
256
+ - Adım 4: MOVIE etiketi uygundur.
257
+ CEVAP: MOVIE
258
+
259
+ Örnek 2 (Kritik Çelişki):
260
+ VARLIK: 'Gizli Bahçe'
261
+ CÜMLE: "Yazar son romanı 'Gizli Bahçe' ile ödül aldı."
262
+ WIKI: "Gizli Bahçe: 1993 yapımı bir dram filmidir."
263
+ ANALİZ:
264
+ - Adım 1: Cümlede 'roman' ve 'yazar' kelimeleri varlığı doğrudan kitap olarak niteliyor.
265
+ - Adım 2: Wiki verisi bu ismi bir film (movie) olarak gösteriyor.
266
+ - Adım 3: ÇELİŞKİ TESPİT EDİLDİ. Kaynak hiyerarşisi gereği cümledeki 'roman' ifadesi Wikipedia'dan daha önceliklidir.
267
+ - Adım 4: BOOK etiketi uygundur.
268
+ CEVAP: BOOK
269
+
270
+ GÜNCEL GÖREV:
271
+ - HEDEF VARLIK: {entity_text}
272
+ - ORİJİNAL CÜMLE: "{full_sentence}"
273
+ - HARİCİ BİLGİ (Wikipedia): "{wiki_context}"
274
+
275
+ ÇIKTI KURALLARI:
276
+ - Cevabında asla yıldız (*) veya markdown kullanma.
277
+ - Analiz adımlarını yukarıdaki 4 adımlı protokole göre yaz.
278
+
279
+ ÇIKTI FORMATI:
280
+ Analiz: [4 Adımlı CoT Analizi]
281
+ Cevap: [SADECE_ETIKET_ADI]"""
282
+
283
+ messages = [{"role": "user", "content": prompt}]
284
+ text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
285
+ model_inputs = tokenizer([text], return_tensors="pt")
286
+
287
+ # CPU'ya taşı
288
+ model_inputs = {k: v.to("cpu") for k, v in model_inputs.items()}
289
+
290
+ print(f"🔄 LLM generate başlatılıyor...")
291
+
292
+ with torch.no_grad():
293
+ generated_ids = llm_model.generate(
294
+ model_inputs.input_ids,
295
+ max_new_tokens=450,
296
+ do_sample=False,
297
+ temperature=0.1,
298
+ pad_token_id=tokenizer.eos_token_id
299
+ )
300
+
301
+ response_ids = [output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)]
302
+ full_output = tokenizer.batch_decode(response_ids, skip_special_tokens=True)[0].strip()
303
+
304
+ print(f"✅ LLM çıktısı alındı")
305
+
306
+ # Etiket Ayıklama
307
+ clean_output = full_output.replace("*", "")
308
+ final_label = "MISC"
309
+ valid_keys = list(custom_label_definitions.keys())
310
+ match = re.search(r"Cevap:\s*([A-Z_]+)", clean_output, re.IGNORECASE)
311
+
312
+ if match:
313
+ extracted = match.group(1).upper().strip()
314
+ if extracted in valid_keys:
315
+ final_label = extracted
316
+ print(f"🏷️ Etiket: {final_label}")
317
+ else:
318
+ print(f"⚠️ Geçersiz etiket: {extracted}")
319
+ else:
320
+ print(f"⚠️ Etiket bulunamadı, MISC atanıyor")
321
+
322
+ return final_label, clean_output
323
+
324
+ except RuntimeError as e:
325
+ print(f"❌ RuntimeError: {str(e)}")
326
+ try:
327
+ llm_model.to("cpu")
328
+ if torch.cuda.is_available():
329
+ torch.cuda.empty_cache()
330
+ except:
331
+ pass
332
+ return "MISC", f"RuntimeError: {str(e)[:100]}"
333
+
334
+ except Exception as e:
335
+ print(f"❌ LLM hatası: {type(e).__name__} - {str(e)}")
336
+ print(traceback.format_exc())
337
+ return "MISC", f"Hata: {str(e)[:100]}"
338
+
339
+ # --- 4. ANA İŞLEM HATTI ---
340
+
341
+ def process_ner(text):
342
+ current_logs = ["🚀 <b>Sistem Başlatıldı:</b> Metin analiz ediliyor..."]
343
+ final_results = []
344
+ yield "<br>".join(current_logs), []
345
+
346
+ custom_labels = {
347
+ "MOVIE": {"tanim": "Sinematik eserler (film, dizi).", "anahtar_kelimeler": ["film", "dizi", "sinema", "yönetmen"]},
348
+ "BOOK": {"tanim": "Yazılı edebi eserler (kitap, roman).", "anahtar_kelimeler": ["kitap", "roman", "yazar", "öykü"]},
349
+ "SOFTWARE": {"tanim": "Dijital sistemler (yazılım, işletim sistemi).", "anahtar_kelimeler": ["yazılım", "kod", "program", "sistem"]},
350
+ "AWARD": {"tanim": "Resmi ödüller ve festival ödülleri.", "anahtar_kelimeler": ["ödül", "oscar", "altın aslan", "nobel", "festival"]},
351
+ "PRODUCT": {"tanim": "Ticari ürünler (marka, model).", "anahtar_kelimeler": ["marka", "model", "telefon", "bilgisayar"]},
352
+ "NORP": {"tanim": "Etnik ve dini gruplar, milliyetler.", "anahtar_kelimeler": ["türk", "fransız", "alman", "millet"]},
353
+ "GPE": {"tanim": "Siyasi bölgeler (ülke, şehir).", "anahtar_kelimeler": ["ülke", "şehir", "başkent", "eyalet"]}
354
+ }
355
+
356
+ try:
357
+ initial_results = ner_pipe(text)
358
+ current_logs.append(f"✅ NER işlemi tamamlandı: {len(initial_results)} varlık bulundu.")
359
+ yield "<br>".join(current_logs), []
360
+ except Exception as e:
361
+ current_logs.append(f"❌ NER hatası: {str(e)}")
362
+ yield "<br>".join(current_logs), []
363
+ return
364
+
365
+ for entity in initial_results:
366
+ word = entity['word'].replace(" ", " ").strip()
367
+ label = entity['entity_group']
368
+
369
+ if label in ["PER", "ORG", "LOC"]:
370
+ res = {"Varlık": word, "İlk Etiket": label, "Nihai Etiket": label, "Kaynak": "Model"}
371
+ current_logs.append(f"✅ <b>{word}</b>: {label} (Doğrudan Tespit)")
372
+ final_results.append(res)
373
+ table_display = [[r["Varlık"], r["İlk Etiket"], f"<b>{r['Nihai Etiket']}</b>", r["Kaynak"]] for r in final_results]
374
+ yield "<br>".join(current_logs), table_display
375
+ continue
376
+
377
+ elif label == "MISC":
378
+ current_logs.append(f"🔍 <b>Analiz Başladı:</b> '{word}'")
379
+ yield "<br>".join(current_logs), [[r["Varlık"], r["İlk Etiket"], r["Nihai Etiket"], r["Kaynak"]] for r in final_results]
380
+
381
+ start_time = time.time()
382
+ current_logs.append(f"⏱️ <b>Türkçe Wikipedia sorgusu:</b> '{word}'")
383
+ yield "<br>".join(current_logs), [[r["Varlık"], r["İlk Etiket"], r["Nihai Etiket"], r["Kaynak"]] for r in final_results]
384
+
385
+ wiki_text = None
386
+ try:
387
+ wiki_text = get_wiki_summary(word)
388
+ elapsed = time.time() - start_time
389
+
390
+ if wiki_text:
391
+ current_logs.append(f"✅ <b>Wikipedia başarılı</b> ({elapsed:.2f}s)")
392
+ wiki_preview = wiki_text[:200] + "..." if len(wiki_text) > 200 else wiki_text
393
+ current_logs.append(f"<div style='margin-left:20px; border-left:2px solid #007bff; padding-left:10px; color:#555;'>🌐 <b>Wiki:</b> {wiki_preview}</div>")
394
+ else:
395
+ current_logs.append(f"❌ <b>Wikipedia boş döndü</b> ({elapsed:.2f}s)")
396
+ except Exception as e:
397
+ elapsed = time.time() - start_time
398
+ current_logs.append(f"❌ <b>Wikipedia hatası</b> ({elapsed:.2f}s): {str(e)[:100]}")
399
+ wiki_text = None
400
+
401
+ yield "<br>".join(current_logs), [[r["Varlık"], r["İlk Etiket"], r["Nihai Etiket"], r["Kaynak"]] for r in final_results]
402
+
403
+ if wiki_text and IS_LLM_ENABLED:
404
+ try:
405
+ current_logs.append(f"🧠 <b>LLM analizi başlatılıyor:</b> '{word}'")
406
+ yield "<br>".join(current_logs), [[r["Varlık"], r["İlk Etiket"], r["Nihai Etiket"], r["Kaynak"]] for r in final_results]
407
+
408
+ new_label, cot_text = refine_label_with_llm(word, text, wiki_text, custom_labels)
409
+
410
+ cot_preview = cot_text[:300] + "..." if len(cot_text) > 300 else cot_text
411
+ current_logs.append(f"🧠 <b>CoT Analizi:</b> {cot_preview}")
412
+
413
+ res = {"Varlık": word, "İlk Etiket": label, "Nihai Etiket": new_label, "Kaynak": "RAG+LLM"}
414
+ current_logs.append(f"🏷️ <b>Nihai Etiket:</b> {new_label}")
415
+
416
+ except Exception as e:
417
+ error_msg = str(e)[:100]
418
+ current_logs.append(f"❌ <b>LLM analiz hatası:</b> {error_msg}")
419
+ res = {"Varlık": word, "İlk Etiket": label, "Nihai Etiket": "MISC", "Kaynak": f"Hata: {error_msg}"}
420
+ else:
421
+ if not wiki_text:
422
+ res = {"Varlık": word, "İlk Etiket": label, "Nihai Etiket": "MISC", "Kaynak": "Model"}
423
+ current_logs.append(f"⚠️ '{word}' için Wikipedia bilgisi olmadığından MISC olarak etiketlendi.")
424
+ else:
425
+ res = {"Varlık": word, "İlk Etiket": label, "Nihai Etiket": "MISC", "Kaynak": "Model"}
426
+ current_logs.append(f"⚠️ LLM aktif değil, '{word}' MISC olarak etiketlendi.")
427
+
428
+ final_results.append(res)
429
+ table_display = [[r["Varlık"], r["İlk Etiket"], f"<b>{r['Nihai Etiket']}</b>", r["Kaynak"]] for r in final_results]
430
+ yield "<br>".join(current_logs), table_display
431
+
432
+ current_logs.append("✨ <b>Analiz Tamamlandı.</b>")
433
+ yield "<br>".join(current_logs), [[r["Varlık"], r["İlk Etiket"], f"<b>{r['Nihai Etiket']}</b>", r["Kaynak"]] for r in final_results]
434
+
435
+ # --- 5. DEBUG FONKSİYONLARI ---
436
+
437
+ def debug_wikipedia():
438
+ result = test_wikipedia_connection()
439
+ return f"<pre style='background:#f4f4f4;padding:10px;border-radius:5px;font-family:monospace;font-size:12px;'>{result}</pre>"
440
+
441
+ def test_single_term(term):
442
+ if not term:
443
+ return "Lütfen bir terim girin."
444
+
445
+ logs = [f"🔍 '{term}' için Türkçe Wikipedia testi"]
446
+ logs.append("="*50)
447
+
448
+ try:
449
+ result = get_wiki_summary(term)
450
+ if result:
451
+ logs.append(f"✅ SONUÇ: {result}")
452
+ else:
453
+ logs.append(f"❌ Sonuç bulunamadı")
454
+
455
+ import wikipedia
456
+ logs.append(f"\n📊 Detaylı arama:")
457
+ try:
458
+ session = requests.Session()
459
+ session.verify = False
460
+ session.headers.update({
461
+ 'User-Agent': 'Mozilla/5.0 (compatible; RAG-NER-System/1.0)'
462
+ })
463
+ wikipedia.wikipedia._session = session
464
+ wikipedia.set_lang("tr")
465
+
466
+ test_terms = improve_search_term(term)
467
+ for t in test_terms:
468
+ try:
469
+ search_results = wikipedia.search(t)
470
+ if search_results:
471
+ logs.append(f" '{t}' -> {len(search_results)} sonuç: {search_results[:3]}")
472
+ try:
473
+ summary = wikipedia.summary(search_results[0], sentences=1)
474
+ logs.append(f" Özet: {summary[:100]}...")
475
+ except:
476
+ pass
477
+ else:
478
+ logs.append(f" '{t}' -> sonuç yok")
479
+ except Exception as e:
480
+ logs.append(f" '{t}' -> hata: {str(e)[:50]}")
481
+ time.sleep(0.2)
482
+ except Exception as e:
483
+ logs.append(f"Test hatası: {str(e)}")
484
+
485
+ except Exception as e:
486
+ logs.append(f"❌ Hata: {str(e)}")
487
+ logs.append(traceback.format_exc())
488
+
489
+ return "\n".join(logs)
490
+
491
+ def check_llm_status():
492
+ global IS_LLM_ENABLED, llm_model
493
+
494
+ logs = ["=== LLM DURUM KONTROLÜ ==="]
495
+ logs.append(f"LLM Aktif: {IS_LLM_ENABLED}")
496
+ logs.append(f"Model: {model_id}")
497
+
498
+ if llm_model is not None:
499
+ try:
500
+ device = next(llm_model.parameters()).device
501
+ dtype = next(llm_model.parameters()).dtype
502
+ logs.append(f"Device: {device}")
503
+ logs.append(f"Dtype: {dtype}")
504
+ logs.append(f"CUDA Kullanılabilir: {torch.cuda.is_available()}")
505
+ except Exception as e:
506
+ logs.append(f"Device kontrol hatası: {str(e)}")
507
+ else:
508
+ logs.append("Model yüklenmemiş!")
509
+
510
+ return "\n".join(logs)
511
+
512
+ # --- 6. GRADIO ARAYÜZÜ ---
513
+
514
+ with gr.Blocks(title="RAG-NER Uzman Karar Destek Sistemi") as demo:
515
+ gr.Markdown("# 🚀 RAG-NER Uzman Karar Destek Sistemi (Türkçe Wikipedia)")
516
+
517
+ with gr.Tab("Metin Analizi"):
518
+ input_text = gr.Textbox(
519
+ label="Analiz Edilecek Metin",
520
+ placeholder="Analiz etmek istediğiniz metni buraya girin...",
521
+ lines=3
522
+ )
523
+
524
+ examples_list = [
525
+ ["Türk yönetmen Nuri Bilge Ceylan, Venedik Film Festivali'nde Altın Aslan ödülünü kazandığı Kış Uykusu filmiyle uluslararası üne kavuştu."],
526
+ ["Amerikalı yazar George Orwell'in ünlü kitabı 1984, Apple şirketinin Macintosh tanıtım reklamında ilham kaynağı olarak kullanılmış ve Windows işletim sistemine karşı bir metafor haline gelmişti."],
527
+ ["Fransız oyuncu Marion Cotillard, Christopher Nolan'ın Inception filmiyle Oscar ödülüne aday gösterilmiş ve daha önce La Vie en Rose performansıyla En İyi Kadın Oyuncu Akademi Ödülü'nü kazanmıştı."]
528
+ ]
529
+
530
+ gr.Examples(
531
+ examples=examples_list,
532
+ inputs=input_text,
533
+ label="Hazır Örnek Senaryolar"
534
+ )
535
+
536
+ with gr.Row():
537
+ log_output = gr.HTML(label="Sistem Günlüğü")
538
+ table_output = gr.Dataframe(
539
+ headers=["Varlık", "İlk Etiket", "Nihai Etiket", "Kaynak"],
540
+ datatype="markdown",
541
+ wrap=True
542
+ )
543
+
544
+ btn = gr.Button("Analiz Et", variant="primary")
545
+ btn.click(
546
+ process_ner,
547
+ inputs=input_text,
548
+ outputs=[log_output, table_output]
549
+ )
550
+
551
+ with gr.Tab("Debug"):
552
+ gr.Markdown("## 🐛 Debug Paneli")
553
+
554
+ gr.Markdown("### 🌐 Türkçe Wikipedia Testi")
555
+ with gr.Row():
556
+ debug_btn = gr.Button("Wikipedia Bağlantısını Test Et", variant="secondary")
557
+ debug_output = gr.HTML(label="Debug Sonuçları")
558
+ debug_btn.click(debug_wikipedia, outputs=debug_output)
559
+
560
+ gr.Markdown("### 🔍 Tek Terim Testi (Gelişmiş Arama)")
561
+ with gr.Row():
562
+ single_term_input = gr.Textbox(
563
+ label="Test Edilecek Terim",
564
+ placeholder="Örn: Türk, Venedik Film Festivali, Altın Aslan",
565
+ scale=3
566
+ )
567
+ single_term_btn = gr.Button("Test Et", variant="secondary", scale=1)
568
+
569
+ single_term_output = gr.Textbox(
570
+ label="Sonuç",
571
+ lines=15,
572
+ interactive=False
573
+ )
574
+ single_term_btn.click(test_single_term, inputs=single_term_input, outputs=single_term_output)
575
+
576
+ gr.Markdown("### 🧠 LLM Durum Kontrolü")
577
+ with gr.Row():
578
+ llm_status_btn = gr.Button("LLM Durumunu Kontrol Et", variant="secondary")
579
+ llm_status_output = gr.Textbox(
580
+ label="LLM Durumu",
581
+ lines=8,
582
+ interactive=False
583
+ )
584
+ llm_status_btn.click(check_llm_status, outputs=llm_status_output)
585
+
586
+ # --- 7. BAŞLATMA ---
587
+
588
+ if __name__ == "__main__":
589
+ print("\n" + "="*50)
590
+ print("🚀 SİSTEM BAŞLATILIYOR...")
591
+ print("="*50)
592
+
593
+ print("\n📡 Türkçe Wikipedia bağlantısı test ediliyor...")
594
+ test_result = test_wikipedia_connection()
595
+ print(test_result)
596
+
597
+ print("\n🧠 LLM durumu kontrol ediliyor...")
598
+ print(check_llm_status())
599
+
600
+ print("\n" + "="*50)
601
+ print("✅ Sistem hazır, Gradio başlatılıyor...")
602
+ print("="*50 + "\n")
603
+
604
+ demo.launch(
605
+ auth=("admin", "1113"),
606
+ auth_message="Lütfen uzman paneline erişmek için giriş yapın.",
607
+ debug=True,
608
+ share=True
609
+ )