File size: 10,198 Bytes
0092992
ffccf87
0092992
 
fa04cb7
0092992
 
1910a2e
0950aa3
0092992
 
 
 
 
 
 
1dce756
0092992
 
 
eb14876
0092992
 
 
 
aa7ec05
0092992
 
 
 
 
 
eb14876
6769cc5
eb14876
0092992
6769cc5
1dce756
0092992
 
1dce756
ffccf87
eb14876
0092992
6769cc5
3cac801
4a0642c
eb14876
6fcdcbb
 
eb14876
 
 
 
 
 
75918c8
3cac801
379cd64
c4580d9
eb14876
 
 
 
 
 
 
3cac801
 
 
 
eb14876
 
 
3cac801
eb14876
 
3cac801
 
 
 
eb14876
 
 
 
 
 
 
 
 
 
5962eec
eb14876
 
 
 
e3b710f
eb14876
6c3abec
0092992
 
 
4a0642c
0092992
1dce756
0092992
 
 
eb14876
1dce756
 
6769cc5
1dce756
 
 
 
 
 
 
c238eff
1dce756
70af7a1
eb14876
e93227c
70af7a1
eb14876
70af7a1
1dce756
70af7a1
4a0642c
70af7a1
 
 
 
 
1dce756
e93227c
70af7a1
1dce756
 
e93227c
70af7a1
1dce756
 
2d14fa3
1dce756
 
 
 
 
70af7a1
1dce756
 
 
 
70af7a1
 
1dce756
eb14876
0092992
 
6769cc5
eb14876
0092992
 
 
 
852ed70
0092992
be052ba
0092992
 
e3b710f
379cd64
852ed70
0092992
 
852ed70
 
 
6769cc5
852ed70
0092992
29fea0c
1dce756
852ed70
1dce756
0092992
 
 
 
be052ba
0092992
 
852ed70
1dce756
852ed70
 
 
 
 
be052ba
eb14876
 
852ed70
0092992
1dce756
c59a4c3
852ed70
3297216
852ed70
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
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."
    )