MISCNER_Light / old_app.py
apak's picture
Rename app.py to old_app.py
ebfc31e verified
Raw History Blame Contribute Delete
10.2 kB
import torch
import wikipedia
import spaces
import os
import re
import gradio as gr
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
from labels_config import custom_labels
# --- 1. MODELLERİN HAZIRLANMASI ---
ner_pipe = pipeline("ner", model="xlm-roberta-large-finetuned-conll03-english", aggregation_strategy="simple", device=-1)
model_id = "Qwen/Qwen2.5-1.5B-Instruct"
tokenizer = AutoTokenizer.from_pretrained(model_id)
try:
llm_model = AutoModelForCausalLM.from_pretrained(model_id, torch_dtype=torch.bfloat16, device_map="cpu", trust_remote_code=True)
IS_LLM_ENABLED = True
except Exception as e:
IS_LLM_ENABLED = False
#-------------------------------------------------------
# --- 2. YARDIMCI FONKSİYONLAR ---
def get_wiki_summary(term):
"""Varlık için Wikipedia özeti getirir."""
try:
wikipedia.set_lang("tr")
search_results = wikipedia.search(term)
if not search_results: return None
return wikipedia.summary(search_results[0], sentences=2, auto_suggest=False)
except: return None
# ------------------------------------------------------
# --- 3. ETİKET GÜNCELLEME FONKSİYONU ---
@spaces.GPU
def refine_label_with_llm(entity_text, full_sentence, wiki_context, custom_labels):
if not IS_LLM_ENABLED: return "MISC", "LLM Aktif Değil"
device = "cuda" if torch.cuda.is_available() else "cpu"
llm_model.to(device)
# 3.1 Etiket Tanımları | Custom_labels listesindeki içerik burada kullanılıyor.
label_rules = ""
for k, v in custom_labels.items():
label_rules += f"### {k}\n- Tanım: {v['tanim']}\n- Anahtar Kelimeler: {', '.join(v['anahtar_kelimeler'])}\n- Örnekler: {', '.join(v['ornekler'])}\n\n"
# 3.2 Sistematik Chain of Thouht ve Kuralların Tanımlanması
prompt = f"""
Sen yüksek hassasiyetli bir semantik analiz uzmanısın. Görevin, '[[{entity_text}]]' varlığını aşağıdaki 4 adımlı Sistematik CoT protokolüne göre sınıflandırmaktır.
ETİKET TANIMLARI:
{label_rules}
SİSTEMATİK CoT ADIMLARI:
Adım 1: Wikipedia'dan gelen bilgilere ("{wiki_context}") dayanarak varlığın niteliklerini belirle( yazılım , film, kitap vb.).
Adım 2: Belirlediğin nitelikleri yukarıdaki {label_rules} listesindeki bütün alanlarla ( ) karşılaştır.
Adım 3: En yüksek anlamsal benzerliğe sahip etiketi RAG sonucu olarak seç. Kararını somut kanıtlara dayandır
Adım 4: Eğer Wikipedia bilgisi yetersizse veya {label_rules} dışındaki bir etiket seçtiysen; varlığın ( [[{entity_text}]]) yanındaki niteleyici kelimelerle ("filmi","ödül","romanı" vb) birlikte Adım 1, Adım 2 ve Adım 3 aşamalarını tekrarla. Eğer hiçbir etiket {label_rules} listesine uyum sağlanamazsa MISC değerini koru.
FEW-SHOT ÖRNEKLERİ:
ÖRNEK 1:
- CÜMLE: "1984, distopik bir geleceği anlatan en önemli romandır."
- VARLIK: 1984
- WIKIPEDIA: "1984 (roman), George Orwell tarafından yazılmış distopik bir kitaptır. Ayrıca 1984 bir takvim yılıdır."
- Analiz:- Adım 1: Wikipedia'dan gelen bilgilere göre, "1984" bir romandır.
- Adım 2: Listedeki "romanı" anahtar kelimesiyle eşleşmektedir.
- Adım 3: RAG sonucu olarak "BOOK" etiketi seçildi.
- Adım 4: Cümledeki "romandır" ifadesi ile "romanı" anahtar kelimeleri eşleştiği için "BOOK" etiketi karar verildi.
- CEVAP: BOOK
ÖRNEK 2:
- CÜMLE: "Bilgisayar Windows işletim sistemiyle sorunsuz çalışıyor."
- VARLIK: Windows
- WIKIPEDIA: "Microsoft Windows, kişisel bilgisayarlar için geliştirilmiş bir işletim sistemidir."
- Analiz:-Adım 1: Wikipedia'dan gelen bilgilere göre "Windows" bir yazılımdır.
-Adım 2: Listedeki "Windows 11" ornek ifadesiyle eşleşmektedir.
-Adım 3: RAG sonucu olarak "SOFTWARE" etiketi seçildi.
-Adım 4: Cümledeki "Windows" ifadesi "Windows 11" örneği eşleştiği için "SOFTWARE" etiketine karar verildi.
- CEVAP: SOFTWARE
GÜNCEL GÖREV:
- HEDEF VARLIK: {entity_text}
- ORİJİNAL CÜMLE: "{full_sentence}"
- DAHİLİ BİLGİ : "{custom_labels}"
- HARİCİ BİLGİ (Wikipedia): "{wiki_context}"
ÇIKTI KURALLARI:
- Cevabında asla yıldız (*) veya markdown kullanma.
- Analiz adımlarını yukarıdaki 4 adımlı protokole göre yaz. Wikipediadan gelen cevabı yazma, sadece kendi değerlendirmeni yaz.
- Yanıtını hiçbir açıklama eklemeden doğrudan [ {{ ... }} ] formatında başlat ve bitir.
ÇIKTI FORMATI:
Analiz: [4 Adımlı CoT Analizi]
Cevap: \n[SADECE_ETIKET_ADI]
"""
messages = [{"role": "user", "content": prompt}]
text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
model_inputs = tokenizer([text], return_tensors="pt").to(device)
try:
generated_ids = llm_model.generate(model_inputs.input_ids, max_new_tokens=450, do_sample=False, temperature=0.1)
response_ids = [output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)]
full_output = tokenizer.batch_decode(response_ids, skip_special_tokens=True)[0].strip()
# 3.3 Markdown temizliği ve Etiket Ayıklama
clean_output = full_output.replace("*", "")
final_label = "MISC"
valid_keys = list(custom_labels.keys())
match = re.search(r"Cevap:\s*([A-Z_]+)", clean_output, re.IGNORECASE)
if match:
extracted = match.group(1).upper().strip()
if extracted in valid_keys: final_label = extracted
return final_label, clean_output
except Exception as e:
return "MISC", f"Hata: {str(e)}"
#------------------------------------------------------------------
# --- 3. ANA İŞLEM HATTI ---
def process_ner(text):
current_logs = ["<b>Sistem Başlatıldı:</b> Metin analiz ediliyor..."]
final_results = []
yield "<br>".join(current_logs), []
initial_results = ner_pipe(text)
for entity in initial_results:
word = entity['word'].replace(" ", " ").strip()
label = entity['entity_group']
if label in ["PER", "ORG", "LOC"]:
res = {"Varlık": word, "İlk Etiket": label, "Nihai Etiket": label, "Kaynak": "Model"}
current_logs.append(f"✅ <b>{word}</b>: {label} (Doğrudan Tespit)")
elif label == "MISC":
current_logs.append(f"🔍 <b>Analiz Başladı:</b> '{word}'")
yield "<br>".join(current_logs), [[r["Varlık"], r["İlk Etiket"], r["Nihai Etiket"], r["Kaynak"]] for r in final_results]
wiki_text = get_wiki_summary(word)
if wiki_text:
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>")
new_label, cot_text = refine_label_with_llm(word, text, wiki_text, custom_labels)
current_logs.append(f"<div style='margin-left:20px; border-left:2px solid #28a745; padding-left:10px;'>🧠 <b>CoT Analizi:</b> {cot_text}</div>")
res = {"Varlık": word, "İlk Etiket": label, "Nihai Etiket": new_label, "Kaynak": "RAG+LLM"}
else:
current_logs.append(f"⚠️ '{word}' için Wikipedia kaydı bulunamadı.")
res = {"Varlık": word, "İlk Etiket": label, "Nihai Etiket": "MISC", "Kaynak": "Model"}
final_results.append(res)
# Tablo çıktısında Nihai Etiket bold yapılır
table_display = [[r["Varlık"], r["İlk Etiket"], f"<b>{r['Nihai Etiket']}</b>", r["Kaynak"]] for r in final_results]
yield "<br>".join(current_logs), table_display
current_logs.append("✨ <b>Analiz Tamamlandı.</b>")
yield "<br>".join(current_logs), [[r["Varlık"], r["İlk Etiket"], f"<b>{r['Nihai Etiket']}</b>", r["Kaynak"]] for r in final_results]
#---------------------------------------------------
# --- 4. GRADIO ARAYÜZÜ ---
with gr.Blocks(title=" RAG-NER") as demo:
gr.Markdown("# MISC-RAG-NER")
with gr.Tab("Metin Analizi"):
input_text = gr.Textbox(
label="Analiz Edilecek Metin",
placeholder="Analiz etmek istediğiniz metni buraya girin...",
lines=3
)
examples_list = [
["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."],
["Alman 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."],
["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ı."]
]
gr.Examples(
examples=examples_list,
inputs=input_text,
label="Örnek Senaryolar"
)
with gr.Row():
# Log çıktısı için HTML bileşeni
log_output = gr.HTML(label="Sistem Günlüğü")
# Tablo çıktısı (Markdown desteği ile kalın yazıları gösterir)
table_output = gr.Dataframe(
headers=["Varlık", "İlk Etiket", "Nihai Etiket", "Kaynak"],
datatype="markdown",
wrap=True
)
btn = gr.Button("Analiz Et", variant="primary")
# Buton fonksiyonu
btn.click(
process_ner,
inputs=input_text,
outputs=[log_output, table_output]
)
#----------------------------------------------------
# --- 5. KULLANICI DENETİMİ (LOGIN) ---
if __name__ == "__main__":
demo.launch( server_port=7860,
auth=("admin", "1113"),
auth_message="Proje arayüzüne erişmek için giriş yapın."
)