File size: 21,498 Bytes
5334f44 2b35763 5334f44 40f29ea 5334f44 40f29ea 2b35763 5334f44 40f29ea 5334f44 2b35763 5334f44 40f29ea 5334f44 40f29ea 2b35763 40f29ea 2b35763 40f29ea 5334f44 40f29ea 5334f44 2b35763 5334f44 2b35763 40f29ea 5334f44 2b35763 5334f44 1dc478a 5334f44 2b35763 eed7a19 2b35763 5334f44 eed7a19 8b4bb8f 5334f44 eed7a19 40f29ea 8b4bb8f faaf135 5334f44 eed7a19 2b35763 eed7a19 8b4bb8f eed7a19 5334f44 2b35763 5334f44 8b4bb8f 2b35763 5334f44 2b35763 eed7a19 2b35763 5334f44 2b35763 8b4bb8f 5334f44 8b4bb8f eed7a19 8b4bb8f 2b35763 8b4bb8f 2b35763 eed7a19 5334f44 8b4bb8f 5334f44 8b4bb8f 5334f44 2b35763 8b4bb8f 5334f44 2b35763 7c14329 2b35763 40f29ea 2b35763 5334f44 7c14329 2b35763 40f29ea 2b35763 7c14329 5334f44 7c14329 2b35763 7c14329 2b35763 7c14329 5334f44 8b4bb8f 5334f44 2b35763 5334f44 2b35763 5334f44 2b35763 5334f44 7c14329 2b35763 8b4bb8f 2b35763 5334f44 8b4bb8f 7c14329 8b4bb8f 2b35763 7c14329 2b35763 7c14329 2b35763 7c14329 2b35763 5334f44 40f29ea 5334f44 40f29ea faaf135 40f29ea 5334f44 2b35763 7c14329 2b35763 7c14329 2b35763 7c14329 2b35763 d9c31cf 2b35763 7c14329 2b35763 8b4bb8f 2b35763 8b4bb8f 2b35763 d9c31cf 7c14329 40f29ea 2b35763 40f29ea 2b35763 8b4bb8f 2b35763 8b4bb8f 2b35763 d9c31cf 2b35763 2dc408f 2b35763 40f29ea 13b6cde faaf135 40f29ea 2b35763 2dc408f 2b35763 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 |
import torch
import wikipedia
from transformers import pipeline
import gradio as gr
import os
# --- Global Log Listesini Tanımla ---
# Başlangıçtaki model yükleme mesajlarını Gradio UI'a aktarmak için bu listeyi kullanıyoruz.
_initial_logs = []
# --- 1. İlk Tarama Modeli (Hızlı NER) ---
# XLM-Roberta çok dillidir ve standart olarak PER, LOC, ORG, MISC etiketleri üretir.
_initial_logs.append("1. Standart NER Modeli yükleniyor...")
# NER modelini yüklerken, cihazı açıkça belirterek Gradio'nun başlangıç aşamalarında oluşabilecek hataları azaltıyoruz.
ner_pipe = pipeline(
"ner",
model="xlm-roberta-large-finetuned-conll03-english",
aggregation_strategy="simple",
device=0 if torch.cuda.is_available() else -1
)
# --- 2. Akıl Yürütme Modeli (LLM - RAG Karar Verici) ---
_initial_logs.append("2. LLM (Karar Verici) yükleniyor...")
model_id = "Qwen/Qwen2.5-1.5B-Instruct" # Türkçe yeteneği iyi ve hızlı
llm_model_kwargs = {}
# Cihaz ayarlarını yapma
if torch.cuda.is_available():
llm_model_kwargs["torch_dtype"] = torch.bfloat16
llm_device_map = "auto"
_initial_logs.append("CUDA desteği bulundu, model GPU üzerinde bfloat16 ile yüklenecek.")
else:
_initial_logs.append("CUDA desteği bulunamadı, model CPU üzerinde float32 ile yüklenecek.")
llm_device_map = "cpu" # Açıkça CPU'ya ayarlandı
try:
gen_pipe = pipeline(
"text-generation",
model=model_id,
model_kwargs=llm_model_kwargs,
device_map=llm_device_map
)
except Exception as e:
_initial_logs.append(f"❌ LLM yüklenirken bir hata oluştu (Muhtemelen Bellek Yetersizliği/OOM): {e}")
# Olası bir çökme durumunu önlemek için alternatif bir çözüm ekleyin
gen_pipe = None
_initial_logs.append("LLM boru hattı devre dışı bırakıldı. Uygulama sadece temel NER yapacaktır.")
_initial_logs.append("✅ Modeller Hazır!")
# --- Wikipedia Fonksiyonu ---
wikipedia.set_lang("tr")
def get_wiki_summary(term):
"""Wikipedia'dan bir terim için özet bilgi çeker."""
try:
results = wikipedia.search(term)
if not results: return None
# İlk sonucu alır, ilk 3 cümleyi özetler
return wikipedia.summary(results[0], sentences=3, auto_suggest=False)
except wikipedia.exceptions.PageError:
return None
except wikipedia.exceptions.RedirectError:
return None
except Exception as e:
# Bu loglar konsola düşer, ancak UI log akışına dahil edilmez.
return None
# --- LLM ile Etiket Rafine Etme Fonksiyonu ---
def refine_label_with_llm(entity_text, wiki_context, custom_label_definitions):
"""LLM kullanarak MISC etiketini özel etiketlerden biriyle rafine eder."""
if gen_pipe is None:
return "MISC" # LLM devre dışıysa rafine etme
labels_str = ", ".join(custom_label_definitions.keys())
label_definitions_str = "\n".join(
[f"- {k}: {v}" for k, v in custom_label_definitions.items()]
)
# LLM için örnekler (Few-shot learning) - İyileştirilmiş ve daha çeşitli
few_shot_examples = """ÖRNEK 1 (NORP İÇİN):
VARLIK: Türk
BAĞLAM: Türkler, Türkiye Cumhuriyeti'nde yaşayan ve Türkçe konuşan büyük bir etnik gruptur. (NORP tanımı ile eşleşir.)
GÖZLEM: 'Türk' varlığı bir etnik grubu veya milliyeti ifade ediyor. Bağlamda 'etnik grup' ve 'Türkiye Cumhuriyeti' geçiyor.
AKIL YÜRÜTME: Etnik veya dini grupları tanımlayan etiket 'NORP'dur. 'Türk' varlığı bu tanıma uymaktadır.
CEVAP: NORP
ÖRNEK 2 (LANGUAGE İÇİN):
VARLIK: Türkçe
BAĞLAM: Türkçenin ilk yazılı örnekleri Orhun Yazıtları'dır. Türk dilleri koluna ait bir dildir. Dünya çapında en çok konuşulan 20. dildir. (LANGUAGE tanımı ile eşleşir.)
GÖZLEM: 'Türkçe', bir iletişim aracı olan dili ifade ediyor. Bağlamda 'Türk dilleri koluna ait bir dildir' ifadesi geçiyor.
AKIL YÜRÜTME: İnsan dillerinin adlarını tanımlayan etiket 'LANGUAGE'dir. Varlık tanımıyla tam olarak eşleşmektedir.
CEVAP: LANGUAGE
ÖRNEK 3 (BOOK İÇİN):
VARLIK: Sinekli Bakkal
BAĞLAM: Halide Edib Adıvar'ın 1935'te yayınlanan ve popüler kültürde önemli yer tutan romanıdır. Eser, II. Dünya Savaşı öncesi İstanbul'u anlatır. (BOOK tanımı ile eşleşir.)
GÖZLEM: 'Sinekli Bakkal' yazar adı ve yayın tarihi ile birlikte bir 'roman' olarak anılıyor. Bağlamda 'romanıdır' ifadesi geçiyor.
AKIL YÜRÜTME: Yazılı veya basılı eserleri, romanları ve yayınları tanımlayan etiket 'BOOK'tur. Bu tanıma uymaktadır.
CEVAP: BOOK
ÖRNEK 4 (TITLE İÇİN):
VARLIK: General
BAĞLAM: Birçok orduda yüksek rütbeli bir subay unvanıdır. Türkiye'de en yüksek rütbelerden biridir. (TITLE tanımı ile eşleşir.)
GÖZLEM: 'General' bir rütbe, unvan veya pozisyon belirtiyor. Bağlamda 'yüksek rütbeli bir subay unvanı' ifadesi geçiyor.
AKIL YÜRÜTME: Kişinin unvanını, rütbesini veya pozisyonunu tanımlayan etiket 'TITLE'dır. 'General' bu tanıma uymaktadır.
CEVAP: TITLE
"""
# --- Chain of Thought (CoT) Prompt Yapısı --- İyileştirilmiş ve daha kuralcı
prompt = f"""Sen uzman bir veri sınıflandırma sistemisin.
Görevin, aşağıdaki varlığı ve bağlamı analiz ederek, **YALNIZCA** ETİKET TANIMLARI'ndan birini (veya uymuyorsa MISC'i) seçmektir.
AKIL YÜRÜTME ZİNCİRİNİ (Chain of Thought) takip ederek adım adım karar ver:
1. GÖZLEM: Varlık ve Wiki Bağlamı arasındaki anahtar eşleşmeleri (isim, tarih, unvan, tür, yayıncı vb.) listele.
2. AKIL YÜRÜTME: Bu gözlemlerin, **ETİKET TANIMLARI**'ndan hangisine **EN YAKIN** olduğunu gerekçesiyle açıkla.
3. KARAR: Yalnızca uygun olan ETİKET'i (veya MISC'i) ÇIKTI FORMATI'na uygun olarak belirt. **MISC'i sadece hiçbir tanıma uymuyorsa kullan.**
{few_shot_examples}
---
ETİKET TANIMLARI:{label_definitions_str}
---
GÖREV VARLIĞI:
VARLIK: {entity_text}
BAĞLAM (Wikipedia): {wiki_context}
ÇIKTI FORMATI:
GÖZLEM: [Tespit edilen anahtar özellikler]
AKIL YÜRÜTME: [Gözlemlerin hangi tanıma uyduğu ve neden]
CEVAP: [SEÇİLEN ETİKET]
"""
messages = [{"role": "user", "content": prompt}]
# LLM çağrısı
outputs = gen_pipe(
messages,
max_new_tokens=150, # CoT için token sayısını koruduk
do_sample=False,
temperature=0.1
)
# LLM çıktısını analiz etme
full_output = outputs[0]["generated_text"][-1]["content"].strip()
final_label = "MISC"
# CoT'yi log'a kaydetmek için parse edelim
cog_output = ""
try:
# Cevap satırını bulur
# Regex ile daha sağlam arama yapılabilir, ancak şimdilik listenin sonuncusunu alıyoruz.
cevap_satiri = [line for line in full_output.split('\n') if 'CEVAP:' in line][-1]
raw_label = cevap_satiri.split('CEVAP:')[-1].strip().upper()
# GÖZLEM ve AKIL YÜRÜTME satırlarını bul
gözlem = [line for line in full_output.split('\n') if 'GÖZLEM:' in line]
akil_yurutme = [line for line in full_output.split('\n') if 'AKIL YÜRÜTME:' in line]
if gözlem and akil_yurutme:
# Sadece akıl yürütme kısmını log'a eklemek için alalım
cog_output = akil_yurutme[-1].replace('AKIL YÜRÜTME:', '').strip()
# Geçerli etiketleri kontrol et
valid_labels = list(custom_label_definitions.keys()) # UNKNOWN'ı çıkarttık, zaten tanımlı değil.
if raw_label in valid_labels:
final_label = raw_label
# CoT çıktısını etikete ekleyerek sonraki aşamada kullanmak için
if cog_output:
return (final_label, cog_output)
except IndexError:
# LLM çıktısı beklenmedik bir formattaysa MISC döner
final_label = "MISC"
return (final_label, cog_output) # (Etiket, CoT Gerekçesi)
# --- NER Pipeline Fonksiyonu (YALNIZCA 2 DEĞER ÜRETİYOR) ---
def advanced_ner_pipeline(text, target_labels, progress=gr.Progress()):
"""
Standart NER modelini çalıştırır, MISC etiketli varlıklar için
Wikipedia ve LLM kullanarak zenginleştirme (RAG) yapar.
"""
# İlk adımda, global başlangıç loglarını log_messages'a ekle.
log_messages = list(_initial_logs)
try:
initial_results = ner_pipe(text)
except Exception as e:
log_messages.append(f"❌ Hata: Temel NER modelinde sorun oluştu: {e}")
yield log_messages, []
return
final_results = []
total_entities = len(initial_results)
log_messages.append(f"🕵️♀️ Toplam {total_entities} varlık inceleniyor...")
# İlk yield (2 değer)
# Bu, model yükleme loglarını Gradio arayüzüne ilk kez gönderir.
yield log_messages, None
for i, entity in enumerate(initial_results):
word = entity['word']
label = entity['entity_group']
# Gradio ilerleme çubuğunu güncelle
current_progress = (i + 1) / total_entities
# İlerlemeyi, işlenen varlık sayısıyla güncelleyin.
progress(current_progress, desc=f"İşleniyor: {word}")
result_obj = {
"entity": word,
"initial_label": label,
"final_label": label,
"source": "Model",
"reasoning": "" # CoT gerekçesi için yeni alan
}
# Eğer etiket MISC ise RAG sürecini başlat
if label == "MISC" and gen_pipe is not None:
standardized_word = word.title()
log_messages.append(f" ⚠️ MISC tespit edildi: '{word}'. Wikipedia'ya soruluyor...")
yield log_messages, None # Log mesajını gönder (2 değer)
wiki_context = get_wiki_summary(standardized_word)
if wiki_context:
log_messages.append(f" 📄 Wiki Bağlamı bulundu: {wiki_context[:50]}...")
yield log_messages, None # Log mesajını gönder (2 değer)
# LLM'den hem etiketi hem de gerekçeyi al
new_label, reasoning = refine_label_with_llm(standardized_word, wiki_context, target_labels)
result_obj["final_label"] = new_label
result_obj["source"] = "RAG+LLM (CoT)"
result_obj["reasoning"] = reasoning # Gerekçeyi kaydet
log_messages.append(f" 🔄 Etiket Güncellendi: MISC -> {new_label}")
if reasoning:
log_messages.append(f" 💡 Akıl Yürütme: {reasoning[:70]}...")
yield log_messages, None # Log mesajını gönder (2 değer)
else:
log_messages.append(" ❌ Wiki'de bilgi bulunamadı, MISC olarak kalıyor.")
yield log_messages, None # Log mesajını gönder (2 değer)
else:
log_messages.append(f" ✅ {word} için etiket: {label}")
yield log_messages, None # Log mesajını gönder (2 değer)
final_results.append(result_obj)
log_messages.append("✅ İşlem tamamlandı! Nihai sonuçlar tabloda.")
# Sonuçlar hazır olduğunda final_results'ı gönder
yield log_messages, final_results # Nihai loglar ve sonuçlar (2 değer)
# --- Özel Etiket Tanımları (23 Etikete Genişletildi) ---
custom_label_definitions = {
# Standart CoNLL-2003 etiketleri (LLM tarafından rafine edilmez, ancak sonuçta görünür)
"PER": "Kişi adları, takma adlar, ünlüler.",
"ORG": "Şirketler, kurumlar, hükümet kuruluşları.",
"LOC": "Coğrafi yerler, siyasi bölgeler, binalar.",
# MISC içinden rafine edilecek ince taneli etiketler (Toplam 19 adet)
"DATE": "Mutlak veya göreceli tarih ifadeleri (yıl, ay, gün).",
"TIME": "Günün saati, zaman aralığı.",
"MONEY": "Parasal değerler, para birimleri.",
"QUANTITY": "Ağırlık, uzunluk, hacim gibi ölçü birimleri ve sayısal değerler.",
"PERCENT": "Yüzdelik ifadeler.",
"NORP": "Milliyetler, etnik, dini veya politik gruplar.",
"LAW": "Resmi kanun, yasa, yönetmelik veya hukuki belge adı.",
"EVENT": "Savaşlar, festivaller, spor turnuvaları, doğal afetler veya kurumsal etkinlikler.",
"BOOK": "Yazılı veya basılı bir eser, yayınlanmış roman, ders kitabı.",
"MOVIE": "Sinema filmi, dizi, belgesel gibi görsel-işitsel yapıt.",
"SONG": "Müzik eseri, şarkı, beste veya albüm adı.",
"ART": "Resim, heykel, spesifik mimari eser adı (Örn: Mona Lisa).",
"AWARD": "Ödül, madalya veya nişan adı (Örn: Nobel, Oscar).",
"PRODUCT": "Ticari olarak satılan somut bir eşya, model, cihaz veya marka serisi (Örn: iPhone 15 Pro, Mercedes C200).",
"SOFTWARE": "Bilgisayar programları, mobil uygulamalar, yapay zeka sistemleri, işletim sistemleri.",
"ORG_SUB": "Şirket birimleri, üniversite fakülteleri, dernek şubeleri gibi büyük bir kurumun alt birimleri.",
"LANGUAGE": "Dillerin adı (Örn: İngilizce, Arapça).",
"TITLE": "Kişinin unvanı, rütbesi veya pozisyonu (Örn: Profesör, General, Başkan).",
"CYBER": "URL, E-posta adresi, IP adresi, hashtag veya kullanıcı adı.",
# MISC: Kalan her şey
"MISC": "Diğer adlandırılmış varlıklar (LLM tarafından rafine edilemeyen veya uymayanlar)."
}
# --- Gradio Arayüzü Fonksiyonu (Düzeltilmiş ve Birleştirilmiş) ---
def process_ner_request(text, progress=gr.Progress()):
"""
Gradio arayüzünden çağrılan ana fonksiyondur.
advanced_ner_pipeline'dan gelen logları ve sonuçları HTML olarak biçimlendirir.
"""
all_logs = []
final_results = None
for logs_step, results_step in advanced_ner_pipeline(text, custom_label_definitions, progress=progress):
all_logs = logs_step # Her adımda güncel logları al
if results_step is not None:
final_results = results_step
# --- Geçici Log Çıktısı Oluşturma ---
log_output_html = "<div style='max-height: 200px; overflow-y: scroll; border: 1px solid #eee; padding: 10px; margin-bottom: 10px; background-color: #f9f9f9; border-radius: 8px; font-family: monospace; font-size: 12px;'>"
for log in all_logs:
# Stil iyileştirmeleri
color = 'blue' if '✅' in log else ('orange' if '⚠️' in log else ('red' if '❌' in log else 'black'))
log_output_html += f"<p style='margin: 0; color: {color};'>{log.replace(' ', ' ')}</p>"
log_output_html += "</div>"
# --- Geçici/Nihai Sonuç Tablosu Oluşturma ---
current_results_html = ""
if final_results: # Eğer sonuç listesi boş değilse tabloyu oluştur
# Tailwind benzeri sınıflar kullanarak basit bir tablo oluştur
current_results_html = """
<style>
.ner-table {
width:100%;
border-collapse: collapse;
font-family: Arial, sans-serif;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
.ner-table th, .ner-table td {
padding: 12px 15px;
text-align: left;
border-bottom: 1px solid #ddd;
}
.ner-table th {
background-color: #3b82f6; /* Tailwind blue-500 */
color: white;
font-weight: bold;
text-transform: uppercase;
}
.ner-table tr:nth-child(even) {
background-color: #f3f4f6; /* Tailwind gray-100 */
}
.ner-table tr:hover {
background-color: #e5e7eb; /* Tailwind gray-200 */
}
.tooltip-text {
visibility: hidden;
background-color: #333;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px 10px;
position: absolute;
z-index: 1;
bottom: 125%; /* Üstte göster */
left: 50%;
transform: translateX(-50%);
opacity: 0;
transition: opacity 0.3s;
width: 300px;
font-size: 11px;
line-height: 1.4;
}
.tooltip-container:hover .tooltip-text {
visibility: visible;
opacity: 1;
}
.tooltip-container {
position: relative;
display: inline-block;
}
</style>
<table class='ner-table'>\n"""
current_results_html += " <tr>\n"
current_results_html += " <th>VARLIK</th>\n"
current_results_html += " <th>İLK ETİKET</th>\n"
current_results_html += " <th>RAG SONRASI ETİKETİ (GEREKÇE)</th>\n"
current_results_html += " <th>KAYNAK</th>\n"
current_results_html += " </tr>\n"
for item in final_results:
# Etiket renklendirmesi için basit bir mantık (23 etiket için rastgele renkler atandı)
color_map = {
"PER": "background-color: #f8c291;", "LOC": "background-color: #a2c4c9;", "ORG": "background-color: #b3c99f;",
"MISC": "background-color: #fef08a;",
"DATE": "background-color: #e5ccff;", "TIME": "background-color: #d1d5db;", "MONEY": "background-color: #fcd34d;",
"QUANTITY": "background-color: #bfdbfe;", "PERCENT": "background-color: #99f6e4;", "NORP": "background-color: #fbcfe8;",
"LAW": "background-color: #f0abfc;", "EVENT": "background-color: #a7f3d0;", "BOOK": "background-color: #ffedd5;",
"MOVIE": "background-color: #c7d2fe;", "SONG": "background-color: #e9d5ff;", "ART": "background-color: #bae6fd;",
"AWARD": "background-color: #fee2e2;", "PRODUCT": "background-color: #ffc999;", "SOFTWARE": "background-color: #d1fae5;",
"ORG_SUB": "background-color: #ccfbf1;", "LANGUAGE": "background-color: #fef9c3;", "TITLE": "background-color: #fecaca;",
"CYBER": "background-color: #dbeafe;"
}
final_label_style = color_map.get(item['final_label'], "")
# CoT gerekçesini bir tooltip olarak ekleme
reasoning_tooltip = ""
if item.get("reasoning"):
# Gerekçe varsa tooltip'i oluştur
reasoning_tooltip = f"""
<div class='tooltip-container'>
{item['final_label']}
<span class='tooltip-text'>
CoT Akıl Yürütme: {item['reasoning']}
</span>
</div>
"""
else:
reasoning_tooltip = item['final_label']
current_results_html += " <tr>\n"
current_results_html += f" <td>{item['entity']}</td>\n"
current_results_html += f" <td>{item['initial_label']}</td>\n"
current_results_html += f" <td style='{final_label_style}'>{reasoning_tooltip}</td>\n"
current_results_html += f" <td>{item['source']}</td>\n"
current_results_html += " </tr>\n"
current_results_html += "</table>"
# Gradio'ya logları ve sonuç tablosunu gönder (her adımda güncelleyin)
yield log_output_html, current_results_html
# --- Gradio Arayüzünü Tanımla ---
iface = gr.Interface(
fn=process_ner_request,
inputs=gr.Textbox(lines=5, placeholder="Metin giriniz...", label="Giriş Metni"),
# Çıktı olarak 2 ayrı HTML bileşeni döndürülmeli.
outputs=[gr.HTML(label="İşlem Logları"), gr.HTML(label="Zenginleştirilmiş NER Sonuçları")],
title="Gelişmiş İnce Taneli NER (23 Etiket - RAG/LLM Destekli)",
description="Metindeki varlıkları tanır ve MISC etiketlileri, 23 ince taneli kategoriye dönüştürmek için Wikipedia (RAG) ve LLM (Qwen2.5-1.5B) kullanılmaktadır. Etiket seti, akademik çalışmalardan esinlenerek 23 özel kategoriye genişletilmiştir.",
examples=[
# Yeni etiketleri test eden örnekler eklendi
["Milli Eğitim Bakanlığı'na bağlı Lise Birimleri, 2024 Türkiye Kupası etkinliğine katılacak ve %15 indirim uygulayacak."],
["General Vural, Türkçe dilini kullanan Türk askerlerini, https://example.com üzerinden uyardı. 'Hürriyet Kasidesi' eserini okudu."],
["Windows 11 işletim sistemi, 1000 TL karşılığında satışa sunulmuştur. 'Cumhurbaşkanı' unvanına sahip kişi, Kanun maddesini değiştirdi."],
],
analytics_enabled=False
)
# --- Gradio Uygulamasını Başlat ---
if __name__ == "__main__":
# Eğer port belirlenmemişse, varsayılan 7860 kullanılır.
port = int(os.environ.get('PORT', 7860))
iface.launch(share=False, server_port=port) |