apak commited on
Commit
aa7ec05
·
verified ·
1 Parent(s): 32166f1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +63 -123
app.py CHANGED
@@ -7,6 +7,7 @@ import gradio as gr
7
  from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
8
 
9
  # --- 1. MODELLERİN HAZIRLANMASI ---
 
10
  ner_pipe = pipeline("ner", model="xlm-roberta-large-finetuned-conll03-english", aggregation_strategy="simple", device=-1)
11
  model_id = "Qwen/Qwen2.5-1.5B-Instruct"
12
  tokenizer = AutoTokenizer.from_pretrained(model_id)
@@ -19,6 +20,7 @@ except Exception as e:
19
 
20
  # --- 2. YARDIMCI FONKSİYONLAR ---
21
  def get_wiki_summary(term):
 
22
  try:
23
  wikipedia.set_lang("tr")
24
  search_results = wikipedia.search(term)
@@ -26,193 +28,131 @@ def get_wiki_summary(term):
26
  return wikipedia.summary(search_results[0], sentences=2, auto_suggest=False)
27
  except: return None
28
 
 
 
 
 
 
 
 
 
 
29
  @spaces.GPU
30
  def refine_label_with_llm(entity_text, full_sentence, wiki_context, custom_label_definitions):
 
31
  if not IS_LLM_ENABLED: return "MISC", "LLM Aktif Değil"
32
 
33
  device = "cuda" if torch.cuda.is_available() else "cpu"
34
  llm_model.to(device)
35
 
36
- # Dinamik Etiket Kurallarını Oluşturma
37
  label_rules = ""
38
  for k, v in custom_label_definitions.items():
39
  label_rules += f"### {k}\n- TANIM: {v['tanim']}\n- ANAHTAR KELİMELER: {', '.join(v['anahtar_kelimeler'])}\n\n"
40
 
41
- prompt = f"""Sen yüksek hassasiyetli bir veri sınıflandırma uzmanısın.
42
- Görevin, analiz edilen varlığı aşağıdaki sistematik metodolojiyi kullanarak kategorize etmektir.
43
 
44
  ETİKET TANIMLARI:
45
  {label_rules}
46
 
47
- ANALİZ VERİLERİ:
48
  - HEDEF VARLIK: {entity_text}
49
  - ORİJİNAL CÜMLE: "{full_sentence}"
50
  - HARİCİ BİLGİ (Wikipedia): "{wiki_context}"
51
 
52
- SİSTEMATİK ANALİZ ADIMLARI (Auto-CoT):
53
- 1. Bağlamsal Kanıt Toplama: Orijinal cümle içerisinde hedef varlığı niteleyen doğrudan ipuçlarını (yanındaki tür isimleri, eylemler, sıfatlar) saptanır.
54
- 2. Bilgi Entegrasyonu: Wikipedia verisinden varlığın genel kimliğini ve kategorisini belirle.
55
- 3. Kaynak Hiyerarşisi ve Çelişki Denetimi: Eğer cümledeki yerel bağlam (birincil kaynak) varlığı belirli bir kategoriye (örn: kitap) işaret ediyorsa; ancak harici bilgi (ikincil kaynak) farklı bir kategori (örn: film) sunuyorsa, birincil kaynağın spesifik beyanına öncelik ver.
56
- 4. Sınıflandırma Mantığı: Sentezlenen en güvenilir veriyi 'ETİKET TANIMLARI'ndaki anahtar kelimelerle sistematik olarak eşleştir.
57
- 5. Doğrulama: Kararın, varlığın cümle içindeki kullanım amacıyla (fonksiyonel bağlam) tutarlı olduğunu teyit et.
58
 
59
  ÇIKTI FORMATI:
60
- Analiz: [Mantıksal çıkarım sürecini ve kaynak tercih sebebini açıklayan kısa analiz]
61
- Cevap: [Sadece ETIKET_ADI]"""
62
 
63
  messages = [{"role": "user", "content": prompt}]
64
  text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
65
  model_inputs = tokenizer([text], return_tensors="pt").to(device)
66
 
67
  try:
68
- # Daha temiz bir üretim için max_new_tokens ve temperature ayarları
69
- generated_ids = llm_model.generate(
70
- model_inputs.input_ids,
71
- max_new_tokens=300,
72
- do_sample=False,
73
- temperature=0.1
74
- )
75
  response_ids = [output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)]
76
  full_output = tokenizer.batch_decode(response_ids, skip_special_tokens=True)[0].strip()
77
 
78
- # Optimize Edilmiş Etiket Ayıklama
 
79
  final_label = "MISC"
80
  valid_keys = list(custom_label_definitions.keys())
81
-
82
- # Regex Açıklaması:
83
- # Cevap kelimesinden sonra gelebilecek yıldız(*), iki nokta(:) ve boşlukları(\s) kapsar.
84
- # Yakalanan grup ([A-Z_]+) sadece büyük harf ve alt tire içerir.
85
- match = re.search(r"Cevap[:\s\*]+([A-Z_]+)", full_output, re.IGNORECASE)
86
 
87
  if match:
88
  extracted = match.group(1).upper().strip()
89
- if extracted in valid_keys:
90
- final_label = extracted
 
 
91
 
92
- # FALLBACK: Eğer yukarıdaki regex yakalayamazsa (Model 'Cevap:' demeyi unutursa)
93
- if final_label == "MISC":
94
- # Metnin en sonuna odaklanarak geçerli etiketlerden birini ara
95
- upper_output = full_output.upper()
96
- for key in valid_keys:
97
- if key in upper_output:
98
- final_label = key
99
- # Not: Birden fazla etiket geçerse sonuncuyu/ilkini alma tercihi yapılabilir.
100
- break
101
-
102
- return final_label, full_output
103
  except Exception as e:
104
  return "MISC", f"Hata: {str(e)}"
105
 
106
  # --- 3. ANA İŞLEM HATTI ---
107
  def process_ner(text):
108
- logs = ["🚀 <b>Sistem Başlatıldı:</b> Metin analiz ediliyor..."]
109
- yield logs, []
110
-
111
  custom_labels = {
112
- "MOVIE": {
113
- "tanim": "Sinematik ve görsel sanat eserleri, kurgusal yapımlar, sahne sanatları.",
114
- "anahtar_kelimeler": ["film", "dizi", "sinema", "belgesel", "sinematografik"],
115
- "ornekler": ["Oppenheimer", "Hababam Sınıfı", "Inception", "Yüzüklerin Efendisi"]
116
- },
117
- "BOOK": {
118
- "tanim": "Yazılı edebiyat ürünleri, basılı materyaller, ciltli veya dijital kitaplar.",
119
- "anahtar_kelimeler": ["kitap", "roman", "dergi", "makale", "hikaye", "yayın"],
120
- "ornekler": ["Nutuk", "Sefiller", "Çalıkuşu", "Suç ve Ceza"]
121
- },
122
- "SOFTWARE": {
123
- "tanim": "Dijital kod tabanlı sistemler, bilgisayar programları, algoritmalar.",
124
- "anahtar_kelimeler": ["yazılım", "program", "algoritma", "kod", "app", "uygulama", "işletim sistemi", "framework"],
125
- "ornekler": ["Windows 11", "Artificial Intelligence", "AI", "Python", "Adobe Photoshop", "Android"]
126
- },
127
- "AWARD": {
128
- "tanim": "Resmi törenlerle verilen takdir, ödül ve onur simgeleri.",
129
- "anahtar_kelimeler": ["ödül", "festival", "madalya", "nişan", "birincilik", "yarışma", "tören"],
130
- "ornekler": ["Nobel Barış Ödülü", "Altın Portakal", "Şampiyonlar Ligi Kupası","Oscar Ödülü"]
131
- },
132
- "PRODUCT": {
133
- "tanim": "Fiziksel olarak üretilen, markası olan ticari ürün ve cihazlar.",
134
- "anahtar_kelimeler": ["ürün", "cihaz", "model", "marka", "donanım", "telefon", "bilgisayar", "araç"],
135
- "ornekler": ["iPhone 13", "Tesla Model 3", "PlayStation 5"]
136
- },
137
- "NORP": {
138
- "tanim": "Milliyet, din, etnik grup veya siyasi topluluk tanımları.",
139
- "anahtar_kelimeler": ["halk", "millet", "etnik", "din", "vatandaş", "soy", "topluluk", "ırk"],
140
- "ornekler": ["Ruslar", "Türkler", "Müslümanlar", "Slavlar"]
141
- },
142
- "GPE": {
143
- "tanim": "Siyasi sınırları olan ülkeler, şehirler ve idari bölgeler.",
144
- "anahtar_kelimeler": ["ülke", "şehir", "kent", "eyalet", "başkent", "ilçe", "vatan"],
145
- "ornekler": ["Türkiye", "Ankara", "Polonya", "İstanbul"]
146
  }
147
- }
148
-
149
 
150
  initial_results = ner_pipe(text)
151
- final_results = []
152
-
153
  for entity in initial_results:
154
  word = entity['word'].replace(" ", " ").strip()
155
  label = entity['entity_group']
156
 
157
  if label in ["PER", "ORG", "LOC"]:
158
  res = {"Varlık": word, "İlk Etiket": label, "Nihai Etiket": label, "Kaynak": "Model"}
159
- logs.append(f"✅ <b>{word}</b>: {label} (Doğrudan Tespit)")
160
  elif label == "MISC":
161
- logs.append(f"🔍 <b>Analiz Başladı:</b> '{word}' (MISC) inceleniyor...")
162
- yield logs, [[r["Varlık"], r["İlk Etiket"], r["Nihai Etiket"], r["Kaynak"]] for r in final_results]
163
 
164
  wiki_text = get_wiki_summary(word)
165
  if wiki_text:
166
- logs.append(f"<div style='border-left: 3px solid #007bff; padding-left: 10px; color: #555;'>🌐 <b>Wiki:</b> {wiki_text}</div>")
167
- new_label, raw_llm_response = refine_label_with_llm(word, text, wiki_text, custom_labels)
168
- logs.append(f"<div style='border-left: 3px solid #28a745; padding-left: 10px; font-style: italic;'>🧠 <b>CoT Analizi:</b> {raw_llm_response}</div>")
169
  res = {"Varlık": word, "İlk Etiket": label, "Nihai Etiket": new_label, "Kaynak": "RAG+LLM"}
170
  else:
171
- logs.append(f"⚠️ '{word}' için Wikipedia kaydı bulunamadı.")
172
  res = {"Varlık": word, "İlk Etiket": label, "Nihai Etiket": "MISC", "Kaynak": "Model"}
173
- else:
174
- res = {"Varlık": word, "İlk Etiket": label, "Nihai Etiket": label, "Kaynak": "Model"}
175
-
176
  final_results.append(res)
177
- yield logs, [[r["Varlık"], r["İlk Etiket"], r["Nihai Etiket"], r["Kaynak"]] for r in final_results]
 
 
178
 
179
- logs.append("✨ <b>Analiz Tamamlandı.</b>")
180
- yield logs, [[r["Varlık"], r["İlk Etiket"], r["Nihai Etiket"], r["Kaynak"]] for r in final_results]
181
 
182
- # --- 4. GÖRSEL ARAYÜZ ---
183
- with gr.Blocks(title=" RAG-NER System") as demo:
184
- gr.Markdown("# RAGNER Sistemi")
185
 
186
  with gr.Tab("Metin Analizi"):
187
- input_text = gr.Textbox(label="Metin Girişi", lines=4)
188
- gr.Examples(
189
- examples=[
190
- "Nobel Barış Ödülü'nü kazanan yazar, son romanı 'Gizli Bahçe' ile büyük beğeni topladı.",
191
- "Oppenheimer filmini izlemek için dün gece Bayraktar-AI yazılımını kullanarak bilet aldık.",
192
- "Türkiye'nin başkenti Ankara'da düzenlenen teknoloji festivalinde birçok ödül verildi."
193
- ],
194
- inputs=input_text
195
- )
196
- submit_btn = gr.Button("Analiz Et", variant="primary")
197
 
198
  with gr.Row():
199
- # Güncellenen Alt Alta Log Görünümü
200
- log_output = gr.HTML(label="İşlem Adımları", value="Sistem Hazır.")
201
- table_output = gr.Dataframe(headers=["Varlık", "İlk Etiket", "Nihai Etiket", "Kaynak"], scale=2)
202
-
203
- with gr.Tab("İş Akışı"):
204
- gr.Markdown("### 🛠 Algoritma Adımları\n1. NER ile Varlık Tespiti\n2. MISC Etiket Filtreleme\n3. Wikipedia RAG Süreci\n4. CoT & Çelişki Yönetimi ile LLM Kararı")
205
-
206
- def update_ui(text):
207
- for logs, table in process_ner(text):
208
- # Logları alt alta, düzgün bir liste formatında birleştiriyoruz
209
- log_html = "<div style='display: flex; flex-direction: column; gap: 10px; background: #f9f9f9; padding: 15px; border-radius: 8px; border: 1px solid #ddd; height: 450px; overflow-y: auto; font-family: Segoe UI, sans-serif;'>"
210
- for m in logs:
211
- log_html += f"<div style='border-bottom: 1px solid #eee; padding-bottom: 5px;'>{m}</div>"
212
- log_html += "</div>"
213
- yield log_html, table
214
-
215
- submit_btn.click(update_ui, inputs=input_text, outputs=[log_output, table_output])
216
 
217
  if __name__ == "__main__":
218
- demo.launch(server_name="0.0.0.0", server_port=7860, auth=("admin", "1113"))
 
7
  from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
8
 
9
  # --- 1. MODELLERİN HAZIRLANMASI ---
10
+ # NER modeli (xlm-roberta) ve LLM (Qwen 2.5) yükleniyor
11
  ner_pipe = pipeline("ner", model="xlm-roberta-large-finetuned-conll03-english", aggregation_strategy="simple", device=-1)
12
  model_id = "Qwen/Qwen2.5-1.5B-Instruct"
13
  tokenizer = AutoTokenizer.from_pretrained(model_id)
 
20
 
21
  # --- 2. YARDIMCI FONKSİYONLAR ---
22
  def get_wiki_summary(term):
23
+ """Varlık için Wikipedia özeti getirir."""
24
  try:
25
  wikipedia.set_lang("tr")
26
  search_results = wikipedia.search(term)
 
28
  return wikipedia.summary(search_results[0], sentences=2, auto_suggest=False)
29
  except: return None
30
 
31
+ def get_random_examples():
32
+ """Wikipedia'dan rastgele gerçek dünya örnekleri çeker."""
33
+ wikipedia.set_lang("tr")
34
+ try:
35
+ random_titles = wikipedia.random(pages=3)
36
+ return [[wikipedia.summary(t, sentences=1, auto_suggest=False)] for t in random_titles]
37
+ except:
38
+ return [["Oppenheimer filmi geçen yıl vizyona girdi."], ["Sefiller romanı çok satıldı."]]
39
+
40
  @spaces.GPU
41
  def refine_label_with_llm(entity_text, full_sentence, wiki_context, custom_label_definitions):
42
+ """LLM kullanarak bağlam analizi ve etiketleme yapar."""
43
  if not IS_LLM_ENABLED: return "MISC", "LLM Aktif Değil"
44
 
45
  device = "cuda" if torch.cuda.is_available() else "cpu"
46
  llm_model.to(device)
47
 
48
+ # Dinamik Etiket Kuralları Oluşturma
49
  label_rules = ""
50
  for k, v in custom_label_definitions.items():
51
  label_rules += f"### {k}\n- TANIM: {v['tanim']}\n- ANAHTAR KELİMELER: {', '.join(v['anahtar_kelimeler'])}\n\n"
52
 
53
+ prompt = f"""Sen uzman bir veri sınıflandırma sistemisin.
54
+ GÖREV: Aşağıdaki varlığı, sağlanan bağlamlara göre en uygun etikete yerleştir.
55
 
56
  ETİKET TANIMLARI:
57
  {label_rules}
58
 
59
+ VERİLER:
60
  - HEDEF VARLIK: {entity_text}
61
  - ORİJİNAL CÜMLE: "{full_sentence}"
62
  - HARİCİ BİLGİ (Wikipedia): "{wiki_context}"
63
 
64
+ ANALİZ ADIMLARI (Auto-CoT):
65
+ 1. Cümle içindeki ipuçlarını (birincil kaynak) ve Wikipedia verisini (ikincil kaynak) karşılaştır.
66
+ 2. Çelişki varsa cümleye öncelik ver.
67
+ 3. Cevabında ASLA yıldız (*) veya markdown kullanma.
 
 
68
 
69
  ÇIKTI FORMATI:
70
+ Analiz: [Analiz süreci]
71
+ Cevap: [SADECE_ETIKET_ADI]"""
72
 
73
  messages = [{"role": "user", "content": prompt}]
74
  text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
75
  model_inputs = tokenizer([text], return_tensors="pt").to(device)
76
 
77
  try:
78
+ generated_ids = llm_model.generate(model_inputs.input_ids, max_new_tokens=250, do_sample=False, temperature=0.1)
 
 
 
 
 
 
79
  response_ids = [output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)]
80
  full_output = tokenizer.batch_decode(response_ids, skip_special_tokens=True)[0].strip()
81
 
82
+ # Temizlik: Yıldızları kaldır ve etiketi ayıkla
83
+ clean_output = full_output.replace("*", "")
84
  final_label = "MISC"
85
  valid_keys = list(custom_label_definitions.keys())
86
+ match = re.search(r"Cevap:\s*([A-Z_]+)", clean_output, re.IGNORECASE)
 
 
 
 
87
 
88
  if match:
89
  extracted = match.group(1).upper().strip()
90
+ if extracted in valid_keys: final_label = extracted
91
+ elif any(k in clean_output.upper() for k in valid_keys):
92
+ for k in valid_keys:
93
+ if k in clean_output.upper(): final_label = k; break
94
 
95
+ return final_label, clean_output
 
 
 
 
 
 
 
 
 
 
96
  except Exception as e:
97
  return "MISC", f"Hata: {str(e)}"
98
 
99
  # --- 3. ANA İŞLEM HATTI ---
100
  def process_ner(text):
101
+ current_logs = ["🚀 <b>Analiz Başlatıldı...</b>"]
102
+ final_results = []
103
+
104
  custom_labels = {
105
+ "MOVIE": {"tanim": "Film, dizi ve sinema eserleri.", "anahtar_kelimeler": ["film", "yönetmen", "vizyon"]},
106
+ "BOOK": {"tanim": "Roman, kitap ve yazılı eserler.", "anahtar_kelimeler": ["roman", "yazar", "edebiyat"]},
107
+ "SOFTWARE": {"tanim": "Yazılım, uygulama ve kod sistemleri.", "anahtar_kelimeler": ["yazılım", "algoritma", "kod"]},
108
+ "AWARD": {"tanim": "Resmi ödüller ve başarı nişanları.", "anahtar_kelimeler": ["ödül", "madalya", "oscar"]},
109
+ "PRODUCT": {"tanim": "Ticari ürünler ve cihazlar.", "anahtar_kelimeler": ["marka", "cihaz", "model"]},
110
+ "NORP": {"tanim": "Milliyet, din veya etnik gruplar.", "anahtar_kelimeler": ["halk", "millet", "topluluk"]},
111
+ "GPE": {"tanim": "Ülkeler, şehirler ve bölgeler.", "anahtar_kelimeler": ["ülke", "şehir", "başkent"]}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  }
 
 
113
 
114
  initial_results = ner_pipe(text)
 
 
115
  for entity in initial_results:
116
  word = entity['word'].replace(" ", " ").strip()
117
  label = entity['entity_group']
118
 
119
  if label in ["PER", "ORG", "LOC"]:
120
  res = {"Varlık": word, "İlk Etiket": label, "Nihai Etiket": label, "Kaynak": "Model"}
121
+ current_logs.append(f"✅ <b>{word}</b>: {label} (Doğrudan Tespit)")
122
  elif label == "MISC":
123
+ current_logs.append(f"🔍 <b>Belirsiz Varlık:</b> '{word}' inceleniyor...")
124
+ yield "<br>".join(current_logs), [[r["Varlık"], r["İlk Etiket"], r["Nihai Etiket"], r["Kaynak"]] for r in final_results]
125
 
126
  wiki_text = get_wiki_summary(word)
127
  if wiki_text:
128
+ new_label, cot_text = refine_label_with_llm(word, text, wiki_text, custom_labels)
129
+ current_logs.append(f"<div style='margin-left:20px; color:#444;'>🧠 {cot_text}</div>")
 
130
  res = {"Varlık": word, "İlk Etiket": label, "Nihai Etiket": new_label, "Kaynak": "RAG+LLM"}
131
  else:
 
132
  res = {"Varlık": word, "İlk Etiket": label, "Nihai Etiket": "MISC", "Kaynak": "Model"}
133
+
 
 
134
  final_results.append(res)
135
+ # Tablo çıktısında Nihai Etiket bold yapılır
136
+ table_out = [[r["Varlık"], r["İlk Etiket"], f"<b>{r['Nihai Etiket']}</b>", r["Kaynak"]] for r in final_results]
137
+ yield "<br>".join(current_logs), table_out
138
 
139
+ current_logs.append("✨ <b>Analiz Tamamlandı.</b>")
140
+ yield "<br>".join(current_logs), [[r["Varlık"], r["İlk Etiket"], f"<b>{r['Nihai Etiket']}</b>", r["Kaynak"]] for r in final_results]
141
 
142
+ # --- 4. GRADIO ARAYÜZÜ ---
143
+ with gr.Blocks(title="Expert RAG-NER") as demo:
144
+ gr.Markdown("# 🚀 RAG-NER Uzman Karar Destek Sistemi")
145
 
146
  with gr.Tab("Metin Analizi"):
147
+ txt_input = gr.Textbox(label="Analiz Edilecek Metin", lines=3)
148
+ gr.Examples(examples=get_random_examples(), inputs=txt_input)
 
 
 
 
 
 
 
 
149
 
150
  with gr.Row():
151
+ log_view = gr.HTML(label="Sistem Günlüğü")
152
+ table_view = gr.Dataframe(headers=["Varlık", "İlk Etiket", "Nihai Etiket", "Kaynak"], datatype="markdown")
153
+
154
+ run_btn = gr.Button("Analiz Et", variant="primary")
155
+ run_btn.click(process_ner, inputs=txt_input, outputs=[log_view, table_view])
 
 
 
 
 
 
 
 
 
 
 
 
156
 
157
  if __name__ == "__main__":
158
+ demo.launch()