apak commited on
Commit
1dce756
·
verified ·
1 Parent(s): 852ed70

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +83 -79
app.py CHANGED
@@ -3,10 +3,9 @@ import wikipedia
3
  import spaces
4
  import os
5
  import re
6
- import json
7
  import gradio as gr
8
  from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
9
- from labels_config import CUSTOM_LABEL_DEFINITIONS
10
 
11
  # --- 1. MODELLERİN HAZIRLANMASI ---
12
  ner_pipe = pipeline("ner", model="xlm-roberta-large-finetuned-conll03-english", aggregation_strategy="simple", device=-1)
@@ -14,16 +13,9 @@ model_id = "Qwen/Qwen2.5-1.5B-Instruct"
14
  tokenizer = AutoTokenizer.from_pretrained(model_id)
15
 
16
  try:
17
- # Bellek optimizasyonu için device_map auto ve bfloat16 kullanıldı
18
- llm_model = AutoModelForCausalLM.from_pretrained(
19
- model_id,
20
- torch_dtype=torch.bfloat16,
21
- device_map="auto",
22
- trust_remote_code=True
23
- )
24
  IS_LLM_ENABLED = True
25
  except Exception as e:
26
- print(f"Model yükleme hatası: {e}")
27
  IS_LLM_ENABLED = False
28
 
29
  # --- 2. YARDIMCI FONKSİYONLAR ---
@@ -46,78 +38,97 @@ def get_random_examples():
46
  return [["Oppenheimer filmi geçen yıl vizyona girdi."], ["Sefiller romanı Victor Hugo tarafından yazılmıştır."]]
47
 
48
  @spaces.GPU
49
- def refine_labels_batch(misc_items, full_sentence):
50
- """
51
- MISC etiketli varlıkları toplu olarak CoT protokolüyle işler.
52
- misc_items: list of dict -> [{'word': '...', 'wiki': '...'}, ...]
53
- """
54
- if not IS_LLM_ENABLED or not misc_items: return []
55
 
56
  device = "cuda" if torch.cuda.is_available() else "cpu"
 
57
 
58
- # Etiket kurallarını metne dönüştür
59
  label_rules = ""
60
- for k, v in CUSTOM_LABEL_DEFINITIONS.items():
61
  label_rules += f"### {k}\n- TANIM: {v['tanim']}\n- ANAHTARLAR: {', '.join(v['anahtar_kelimeler'])}\n\n"
62
 
63
- # Hedef varlıkları listele
64
- targets_text = ""
65
- for i, item in enumerate(misc_items):
66
- targets_text += f"\nVARLIK {i+1}: {item['word']}\nWIKI BİLGİSİ: {item['wiki']}\n"
67
-
68
- prompt = f"""Sen yüksek hassasiyetli bir semantik analiz uzmanısın.
69
- Görevin, sana verilen listedeki varlıkları aşağıdaki 4 adımlı Sistematik CoT protokolüne göre sınıflandırmaktır.
70
 
71
  ETİKET TANIMLARI:
72
  {label_rules}
73
 
74
  SİSTEMATİK CoT ADIMLARI:
75
- 1. Sentaktik İnceleme (Cümle bağlamı)
76
- 2. Bilgi Entegrasyonu (Wikipedia verisi)
77
- 3. Çelişki ve Hiyerarşi Denetimi (Cümle bilgisi Wikipedia'dan üstündür)
78
- 4. Etiket Eşleşmesi
79
 
80
  REFERANS ANALİZLER (FEW-SHOT):
81
- Örnek 1: 'Inception' | Cümle: 'Inception filmini izledim' | Wiki: '2010 yapımı film' -> Cevap: MOVIE
82
- Örnek 2: 'Gizli Bahçe' | Cümle: 'Yazar son romanı Gizli Bahçe ile...' | Wiki: '1993 yapımı film' -> Cevap: BOOK (Cümle öncelikli)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
 
84
  GÜNCEL GÖREV:
85
- ORİJİNAL CÜMLE: "{full_sentence}"
86
- ANALİZ EDİLECEK VARLIKLAR:
87
- {targets_text}
 
 
 
 
88
 
89
- ÇIKTI FORMATI:
90
- Sadece aşağıdaki JSON yapısını döndür, başka açıklama ekleme:
91
- [
92
- {{"varlik": "VARLIK_ADI", "analiz": "Adım 1-2-3-4 özeti", "karar": "ETIKET_ADI"}},
93
- ...
94
- ]"""
95
 
96
  messages = [{"role": "user", "content": prompt}]
97
  text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
98
  model_inputs = tokenizer([text], return_tensors="pt").to(device)
99
 
100
  try:
101
- generated_ids = llm_model.generate(model_inputs.input_ids, max_new_tokens=1000, do_sample=False, temperature=0.1)
102
  response_ids = [output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)]
103
  full_output = tokenizer.batch_decode(response_ids, skip_special_tokens=True)[0].strip()
104
 
105
- # JSON Ayıklama (Regex ile güvenli hale getirildi)
106
- json_match = re.search(r'\[\s*\{.*\}\s*\]', full_output, re.DOTALL)
107
- if json_match:
108
- return json.loads(json_match.group(0))
109
- return []
 
 
 
 
 
 
110
  except Exception as e:
111
- print(f"Batch Hatası: {e}")
112
- return []
113
 
114
  # --- 3. ANA İŞLEM HATTI ---
115
  def process_ner(text):
116
  current_logs = ["🚀 <b>Sistem Başlatıldı:</b> Metin analiz ediliyor..."]
117
  final_results = []
118
- misc_buffer = []
119
-
120
- # 1. Aşama: Hızlı Tespit ve MISC Toplama
 
121
  initial_results = ner_pipe(text)
122
 
123
  for entity in initial_results:
@@ -125,41 +136,29 @@ def process_ner(text):
125
  label = entity['entity_group']
126
 
127
  if label in ["PER", "ORG", "LOC"]:
128
- final_results.append({"Varlık": word, "İlk": label, "Nihai": label, "Kaynak": "Model"})
129
  current_logs.append(f"✅ <b>{word}</b>: {label} (Doğrudan Tespit)")
130
  elif label == "MISC":
131
- current_logs.append(f"🔍 <b>Wiki Sorgulanıyor:</b> '{word}'")
132
- yield "<br>".join(current_logs), [[r["Varlık"], r["İlk"], r["Nihai"], r["Kaynak"]] for r in final_results]
133
 
134
  wiki_text = get_wiki_summary(word)
135
- misc_buffer.append({"word": word, "wiki": wiki_text or "Bilgi yok."})
136
- current_logs.append(f"📦 <b>Kuyruğa Alındı:</b> {word}")
137
-
138
- # 2. Aşama: Batch LLM İşleme
139
- if misc_buffer:
140
- current_logs.append(f"🧠 <b>Toplu Analiz Başladı:</b> {len(misc_buffer)} varlık CoT ile işleniyor...")
141
- yield "<br>".join(current_logs), [[r["Varlık"], r["İlk"], r["Nihai"], r["Kaynak"]] for r in final_results]
142
-
143
- llm_responses = refine_labels_batch(misc_buffer, text)
144
 
145
- for item in misc_buffer:
146
- # LLM yanıtları içinden doğru varlığı eşleştir
147
- match = next((res for res in llm_responses if res.get('varlik','').lower() in item['word'].lower()), None)
148
-
149
- final_label = match['karar'] if match else "MISC"
150
- cot_summary = match['analiz'] if match else "Analiz yapılamadı."
151
-
152
- final_results.append({
153
- "Varlık": item['word'],
154
- "İlk": "MISC",
155
- "Nihai": final_label,
156
- "Kaynak": "RAG+Batch LLM"
157
- })
158
- current_logs.append(f"<div style='margin-left:20px; border-left:2px solid #28a745; padding-left:10px;'>💡 <b>{item['word']}</b> -> {final_label}<br><small>{cot_summary}</small></div>")
159
 
160
  current_logs.append("✨ <b>Analiz Tamamlandı.</b>")
161
- table_display = [[r["Varlık"], r["İlk"], f"<b>{r['Nihai']}</b>", r["Kaynak"]] for r in final_results]
162
- yield "<br>".join(current_logs), table_display
163
 
164
  # --- 4. GRADIO ARAYÜZÜ ---
165
  with gr.Blocks(title="RAG-NER Uzman Karar Destek Sistemi") as demo:
@@ -172,6 +171,7 @@ with gr.Blocks(title="RAG-NER Uzman Karar Destek Sistemi") as demo:
172
  lines=3
173
  )
174
 
 
175
  examples_list = [
176
  ["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."],
177
  ["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."],
@@ -185,7 +185,9 @@ with gr.Blocks(title="RAG-NER Uzman Karar Destek Sistemi") as demo:
185
  )
186
 
187
  with gr.Row():
 
188
  log_output = gr.HTML(label="Sistem Günlüğü")
 
189
  table_output = gr.Dataframe(
190
  headers=["Varlık", "İlk Etiket", "Nihai Etiket", "Kaynak"],
191
  datatype="markdown",
@@ -194,6 +196,7 @@ with gr.Blocks(title="RAG-NER Uzman Karar Destek Sistemi") as demo:
194
 
195
  btn = gr.Button("Analiz Et", variant="primary")
196
 
 
197
  btn.click(
198
  process_ner,
199
  inputs=input_text,
@@ -202,6 +205,7 @@ with gr.Blocks(title="RAG-NER Uzman Karar Destek Sistemi") as demo:
202
 
203
  # --- 5. KULLANICI DENETİMİ (LOGIN) ---
204
  if __name__ == "__main__":
 
205
  demo.launch(
206
  auth=("admin", "1113"),
207
  auth_message="Lütfen uzman paneline erişmek için giriş yapın."
 
3
  import spaces
4
  import os
5
  import re
 
6
  import gradio as gr
7
  from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
8
+ from labels_config import custom_label_definitions
9
 
10
  # --- 1. MODELLERİN HAZIRLANMASI ---
11
  ner_pipe = pipeline("ner", model="xlm-roberta-large-finetuned-conll03-english", aggregation_strategy="simple", device=-1)
 
13
  tokenizer = AutoTokenizer.from_pretrained(model_id)
14
 
15
  try:
16
+ llm_model = AutoModelForCausalLM.from_pretrained(model_id, torch_dtype=torch.bfloat16, device_map="cpu", trust_remote_code=True)
 
 
 
 
 
 
17
  IS_LLM_ENABLED = True
18
  except Exception as e:
 
19
  IS_LLM_ENABLED = False
20
 
21
  # --- 2. YARDIMCI FONKSİYONLAR ---
 
38
  return [["Oppenheimer filmi geçen yıl vizyona girdi."], ["Sefiller romanı Victor Hugo tarafından yazılmıştır."]]
39
 
40
  @spaces.GPU
41
+ def refine_label_with_llm(entity_text, full_sentence, wiki_context, custom_label_definitions):
42
+ if not IS_LLM_ENABLED: return "MISC", "LLM Aktif Değil"
 
 
 
 
43
 
44
  device = "cuda" if torch.cuda.is_available() else "cpu"
45
+ llm_model.to(device)
46
 
47
+ # 1. Etiket Tanımları (Bilgi Kaynağı)
48
  label_rules = ""
49
+ for k, v in custom_label_definitions.items():
50
  label_rules += f"### {k}\n- TANIM: {v['tanim']}\n- ANAHTARLAR: {', '.join(v['anahtar_kelimeler'])}\n\n"
51
 
52
+ # 2. Sistematik CoT ve Kuralların Tanımlanması
53
+ prompt = f"""Sen yüksek hassasiyetli bir semantik analiz uzmanısın.
54
+ Görevin, '[[{entity_text}]]' varlığını aşağıdaki 4 adımlı Sistematik CoT protokolüne göre sınıflandırmaktır.
 
 
 
 
55
 
56
  ETİKET TANIMLARI:
57
  {label_rules}
58
 
59
  SİSTEMATİK CoT ADIMLARI:
60
+ 1. **Sentaktik İnceleme:** Cümle içinde varlığın sağındaki ve solundaki kelimeleri (niteleyicileri) tespit et. Varlık bir fiille mi (yazıldı, vizyona girdi) yoksa bir isimle mi (yazılımı, ödülü) ilişkili?
61
+ 2. **Bilgi Entegrasyonu:** Wikipedia verisindeki genel tanımı oku. Varlığın tarihsel veya teknik kimliğini belirle.
62
+ 3. **Çelişki ve Hiyerarşi Denetimi:** Wikipedia bilgisi ile cümledeki kullanım amacı çelişiyor mu? (Örn: Wiki 'film' diyor ama cümle 'kitap' diyorsa, cümledeki kullanım esastır).
63
+ 4. **Etiket Eşleşmesi:** Elde edilen nihai kanıtları, 'ETİKET TANIMLARI'ndaki en yakın kategoriyle eşleştir ve son kararı ver.
64
 
65
  REFERANS ANALİZLER (FEW-SHOT):
66
+ Örnek 1 (Tam Uyum):
67
+ VARLIK: 'Inception'
68
+ CÜMLE: "Dün gece Inception filmini tekrar izledim."
69
+ WIKI: "Inception, Christopher Nolan tarafından yönetilen 2010 yapımı bilimkurgu filmidir."
70
+ ANALİZ:
71
+ - Adım 1: Cümlede 'film' ve 'izlemek' kelimeleri görsel esere işaret ediyor.
72
+ - Adım 2: Wiki verisi varlığın bir film olduğunu doğruluyor.
73
+ - Adım 3: Kaynaklar arasında çelişki yok.
74
+ - Adım 4: MOVIE etiketi uygundur.
75
+ CEVAP: MOVIE
76
+
77
+ Örnek 2 (Kritik Çelişki):
78
+ VARLIK: 'Gizli Bahçe'
79
+ CÜMLE: "Yazar son romanı 'Gizli Bahçe' ile ödül aldı."
80
+ WIKI: "Gizli Bahçe: 1993 yapımı bir dram filmidir."
81
+ ANALİZ:
82
+ - Adım 1: Cümlede 'roman' ve 'yazar' kelimeleri varlığı doğrudan kitap olarak niteliyor.
83
+ - Adım 2: Wiki verisi bu ismi bir film (movie) olarak gösteriyor.
84
+ - Adım 3: ÇELİŞKİ TESPİT EDİLDİ. Kaynak hiyerarşisi gereği cümledeki 'roman' ifadesi Wikipedia'dan daha önceliklidir.
85
+ - Adım 4: BOOK etiketi uygundur.
86
+ CEVAP: BOOK
87
 
88
  GÜNCEL GÖREV:
89
+ - HEDEF VARLIK: {entity_text}
90
+ - ORİJİNAL CÜMLE: "{full_sentence}"
91
+ - HARİCİ BİLGİ (Wikipedia): "{wiki_context}"
92
+
93
+ ÇIKTI KURALLARI:
94
+ - Cevabında asla yıldız (*) veya markdown kullanma.
95
+ - Analiz adımlarını yukarıdaki 4 adımlı protokole göre yaz.
96
 
97
+ ÇIKTI FORMATI:
98
+ Analiz: [4 Adımlı CoT Analizi]
99
+ Cevap: [SADECE_ETIKET_ADI]"""
 
 
 
100
 
101
  messages = [{"role": "user", "content": prompt}]
102
  text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
103
  model_inputs = tokenizer([text], return_tensors="pt").to(device)
104
 
105
  try:
106
+ generated_ids = llm_model.generate(model_inputs.input_ids, max_new_tokens=450, do_sample=False, temperature=0.1)
107
  response_ids = [output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)]
108
  full_output = tokenizer.batch_decode(response_ids, skip_special_tokens=True)[0].strip()
109
 
110
+ # Markdown temizliği ve Etiket Ayıklama
111
+ clean_output = full_output.replace("*", "")
112
+ final_label = "MISC"
113
+ valid_keys = list(custom_label_definitions.keys())
114
+ match = re.search(r"Cevap:\s*([A-Z_]+)", clean_output, re.IGNORECASE)
115
+
116
+ if match:
117
+ extracted = match.group(1).upper().strip()
118
+ if extracted in valid_keys: final_label = extracted
119
+
120
+ return final_label, clean_output
121
  except Exception as e:
122
+ return "MISC", f"Hata: {str(e)}"
 
123
 
124
  # --- 3. ANA İŞLEM HATTI ---
125
  def process_ner(text):
126
  current_logs = ["🚀 <b>Sistem Başlatıldı:</b> Metin analiz ediliyor..."]
127
  final_results = []
128
+ yield "<br>".join(current_logs), []
129
+
130
+
131
+
132
  initial_results = ner_pipe(text)
133
 
134
  for entity in initial_results:
 
136
  label = entity['entity_group']
137
 
138
  if label in ["PER", "ORG", "LOC"]:
139
+ res = {"Varlık": word, "İlk Etiket": label, "Nihai Etiket": label, "Kaynak": "Model"}
140
  current_logs.append(f"✅ <b>{word}</b>: {label} (Doğrudan Tespit)")
141
  elif label == "MISC":
142
+ current_logs.append(f"🔍 <b>Analiz Başladı:</b> '{word}'")
143
+ yield "<br>".join(current_logs), [[r["Varlık"], r["İlk Etiket"], r["Nihai Etiket"], r["Kaynak"]] for r in final_results]
144
 
145
  wiki_text = get_wiki_summary(word)
146
+ if wiki_text:
147
+ current_logs.append(f"<div style='margin-left:20px; border-left:2px solid #007bff; padding-left:10px; color:#555;'>🌐 <b>Wiki:</b> {wiki_text}</div>")
148
+ new_label, cot_text = refine_label_with_llm(word, text, wiki_text, custom_labels_definitions)
149
+ current_logs.append(f"<div style='margin-left:20px; border-left:2px solid #28a745; padding-left:10px;'>🧠 <b>CoT Analizi:</b> {cot_text}</div>")
150
+ res = {"Varlık": word, "İlk Etiket": label, "Nihai Etiket": new_label, "Kaynak": "RAG+LLM"}
151
+ else:
152
+ current_logs.append(f"⚠️ '{word}' için Wikipedia kaydı bulunamadı.")
153
+ res = {"Varlık": word, "İlk Etiket": label, "Nihai Etiket": "MISC", "Kaynak": "Model"}
 
154
 
155
+ final_results.append(res)
156
+ # Tablo çıktısında Nihai Etiket bold yapılır
157
+ table_display = [[r["Varlık"], r["İlk Etiket"], f"<b>{r['Nihai Etiket']}</b>", r["Kaynak"]] for r in final_results]
158
+ yield "<br>".join(current_logs), table_display
 
 
 
 
 
 
 
 
 
 
159
 
160
  current_logs.append("✨ <b>Analiz Tamamlandı.</b>")
161
+ yield "<br>".join(current_logs), [[r["Varlık"], r["İlk Etiket"], f"<b>{r['Nihai Etiket']}</b>", r["Kaynak"]] for r in final_results]
 
162
 
163
  # --- 4. GRADIO ARAYÜZÜ ---
164
  with gr.Blocks(title="RAG-NER Uzman Karar Destek Sistemi") as demo:
 
171
  lines=3
172
  )
173
 
174
+ # EKSİK OLAN ÖRNEKLER BÖLÜMÜ BURADA TANIMLANDI
175
  examples_list = [
176
  ["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."],
177
  ["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."],
 
185
  )
186
 
187
  with gr.Row():
188
+ # Log çıktısı için HTML bileşeni
189
  log_output = gr.HTML(label="Sistem Günlüğü")
190
+ # Tablo çıktısı (Markdown desteği ile kalın yazıları gösterir)
191
  table_output = gr.Dataframe(
192
  headers=["Varlık", "İlk Etiket", "Nihai Etiket", "Kaynak"],
193
  datatype="markdown",
 
196
 
197
  btn = gr.Button("Analiz Et", variant="primary")
198
 
199
+ # Buton fonksiyonu
200
  btn.click(
201
  process_ner,
202
  inputs=input_text,
 
205
 
206
  # --- 5. KULLANICI DENETİMİ (LOGIN) ---
207
  if __name__ == "__main__":
208
+
209
  demo.launch(
210
  auth=("admin", "1113"),
211
  auth_message="Lütfen uzman paneline erişmek için giriş yapın."