deprem-ner-app / app.py
nypgd's picture
Create app.py
f841a51 verified
Raw
History Blame Contribute Delete
3.99 kB
import os
import torch
import nltk
import gradio as gr
from nltk.tokenize import TweetTokenizer
from transformers import AutoTokenizer, AutoModelForTokenClassification
# 1. NLTK Başlat
nltk.download('punkt', quiet=True)
tknzr = TweetTokenizer(preserve_case=True, strip_handles=False, reduce_len=False)
# 2. Private modele erişim için token al (Space ayarlarından)
hf_token = os.environ.get("HF_TOKEN")
# 3. Modeli Yükle
repo_id = "nypgd/bert-turkish-deprem-ner"
tokenizer = AutoTokenizer.from_pretrained(repo_id, token=hf_token)
model = AutoModelForTokenClassification.from_pretrained(repo_id, token=hf_token)
model.eval()
id2label = model.config.id2label
# 4. Tahmin Fonksiyonu
def extract_entities(text):
if not text.strip(): return []
original_tokens = tknzr.tokenize(text)
if not original_tokens: return []
inputs = tokenizer(original_tokens, is_split_into_words=True, return_tensors="pt", truncation=True)
with torch.no_grad():
logits = model(**inputs).logits
predictions = torch.argmax(logits, dim=2)[0]
word_ids = inputs.word_ids()
token_tags = []
token_logit_idx = []
prev_word_idx = None
for sub_pos, (pred_id, word_idx) in enumerate(zip(predictions, word_ids)):
if word_idx is None: continue
if word_idx != prev_word_idx:
token_tags.append(id2label[pred_id.item()])
token_logit_idx.append(sub_pos)
prev_word_idx = word_idx
SKIP_TOKENS = {',', '-', ':', '.', '/', '(', ')'}
entities = []
current_ent = None
for i, (token, tag) in enumerate(zip(original_tokens, token_tags)):
if tag == 'O' and current_ent and token in SKIP_TOKENS: continue
if tag == 'O':
if current_ent: entities.append(current_ent)
current_ent = None
continue
ent_type = tag[2:]
score_val = round(torch.softmax(logits[0, token_logit_idx[i]], dim=-1).max().item(), 4)
if tag.startswith('B-'):
if current_ent: entities.append(current_ent)
current_ent = {"Etiket": f"[{ent_type}]", "Kelime": token, "Skor": score_val}
elif tag.startswith('I-') and current_ent and current_ent["Etiket"] == f"[{ent_type}]":
current_ent["Kelime"] += " " + token
current_ent["Skor"] = round(min(current_ent["Skor"], score_val), 4)
else:
if current_ent: entities.append(current_ent)
current_ent = {"Etiket": f"[{ent_type}]", "Kelime": token, "Skor": score_val}
if current_ent: entities.append(current_ent)
# Arayüzdeki tablo için veriyi liste formatına çevir
return [[ent["Etiket"], ent["Kelime"], ent["Skor"]] for ent in entities]
# 5. Gradio Arayüzü Tasarımı
with gr.Blocks(theme=gr.themes.Soft()) as demo:
gr.Markdown("# 🚨 BERT Türkçe Deprem Tweet NER")
gr.Markdown("Bu uygulama, deprem tweetlerinden kritik bilgileri (`LOC`, `PER`, `ORG`, `NEED`, `PHONE`, `LINK`) çıkarır. **Model ve Space tamamen gizlidir.**")
with gr.Row():
with gr.Column(scale=1):
input_text = gr.Textbox(lines=6, label="Tweet Metni", placeholder="Analiz edilecek tweeti buraya yapıştırın...")
btn = gr.Button("Analiz Et", variant="primary")
gr.Examples(
examples=[["@AFADTurkiye ve Ahbap ekipleri, Gaziantep İslahiye Yeni Mahalle Karanfil Sokak No:5 adresinde 7 kişi enkaz altında mahsur kaldı. Acil ısıtıcı, çadır ve çocuk maması gerekiyor. Saha sorumlusu Ayşe Yurt iletişim: 0533 123 45 67. Konum ve detaylı bilgi için: https://t.co/yardimadresi"]],
inputs=input_text,
label="Örnek Tweet"
)
with gr.Column(scale=1):
output_table = gr.Dataframe(headers=["Etiket", "Bulunan Metin", "Güven Skoru"], label="Çıkarılan Varlıklar")
btn.click(fn=extract_entities, inputs=input_text, outputs=output_table)
demo.launch()