ilterm's picture
Update app.py
dc6cbb4 verified
import gradio as gr
import torch
import torch.nn as nn
import torch.nn.functional as F
from transformers import AutoTokenizer, AutoModel
from huggingface_hub import hf_hub_download
# Model sınıfını tanımla
class HistTurkSentiment(nn.Module):
def __init__(self):
super().__init__()
self.bert = AutoModel.from_pretrained('dbmdz/bert-base-turkish-cased', add_pooling_layer=False)
hidden_size = self.bert.config.hidden_size
self.multihead_attn = nn.MultiheadAttention(hidden_size, 8, dropout=0.1)
self.layer_norm1 = nn.LayerNorm(hidden_size)
self.layer_norm2 = nn.LayerNorm(hidden_size * 2)
self.context_fusion = nn.Sequential(
nn.Linear(hidden_size * 2, hidden_size),
nn.LayerNorm(hidden_size),
nn.GELU(),
nn.Dropout(0.1),
nn.Linear(hidden_size, hidden_size),
nn.LayerNorm(hidden_size)
)
self.sentiment_classifier = nn.Sequential(
nn.Linear(hidden_size, hidden_size // 2),
nn.LayerNorm(hidden_size // 2),
nn.GELU(),
nn.Dropout(0.1),
nn.Linear(hidden_size // 2, 3)
)
def forward(self, input_ids, attention_mask):
outputs = self.bert(input_ids=input_ids, attention_mask=attention_mask, output_hidden_states=True)
# Layer ensemble
layers = torch.stack(outputs.hidden_states[-4:])
weights = torch.tensor([0.1, 0.2, 0.3, 0.4], device=input_ids.device).view(4, 1, 1, 1)
final_output = (layers * weights).sum(dim=0)
# Embeddings
cls_emb = F.normalize(final_output[:, 0, :], p=2, dim=1)
mask = attention_mask.unsqueeze(-1).float()
mean_emb = F.normalize((final_output * mask).sum(dim=1) / mask.sum(dim=1).clamp(min=1e-9), p=2, dim=1)
# Attention
q, k, v = cls_emb.unsqueeze(0), final_output.transpose(0, 1), final_output.transpose(0, 1)
attn_out = self.multihead_attn(q, k, v)[0].squeeze(0)
attn_out = self.layer_norm1(attn_out + cls_emb)
# Fusion
combined = self.layer_norm2(torch.cat([attn_out, mean_emb], dim=1))
fused = self.context_fusion(combined)
return self.sentiment_classifier(fused)
# Global değişkenler
tokenizer = None
model = None
def load_model():
"""Model ve tokenizer'ı yükle (bir kez)"""
global tokenizer, model
if model is None:
print("Model yükleniyor...")
# Tokenizer yükle
tokenizer = AutoTokenizer.from_pretrained("dbbiyte/histurk-BERTurk-sentiment")
# Model oluştur
model = HistTurkSentiment()
# Weights indir ve yükle
weights_path = hf_hub_download("dbbiyte/histurk-BERTurk-sentiment", "pytorch_model.bin")
model.load_state_dict(torch.load(weights_path, map_location='cpu'))
model.eval()
print("Model başarıyla yüklendi!")
def predict_sentiment(text):
"""Ana tahmin fonksiyonu"""
# Boş metin kontrolü
if not text or not text.strip():
return "❌ Lütfen analiz edilecek bir metin girin!"
try:
# Model yükle (ilk kez çağırıldığında)
load_model()
# Tokenize et
inputs = tokenizer(
text,
return_tensors="pt",
truncation=True,
padding=True,
max_length=256,
return_token_type_ids=False
)
# Tahmin yap
with torch.no_grad():
logits = model(**inputs)
probs = F.softmax(logits, dim=-1)
pred_idx = probs.argmax().item()
confidence = probs[0][pred_idx].item()
# Sonuçları formatla
labels = ["Negatif", "Nötr", "Pozitif"]
icons = ["😞", "😐", "😊"]
result_text = f"""
## 🎯 Analiz Sonucu
### {icons[pred_idx]} **{labels[pred_idx]}** Sentiment
**Güven Skoru:** %{confidence*100:.1f}
---
### 📊 Detaylı Skorlar:
- **Negatif:** %{probs[0][0].item()*100:.1f}
- **Nötr:** %{probs[0][1].item()*100:.1f}
- **Pozitif:** %{probs[0][2].item()*100:.1f}
"""
return result_text
except Exception as e:
return f"❌ **Hata oluştu:** {str(e)}"
# Gradio arayüzü
def create_interface():
# CSS stilleri
css = """
.gradio-container {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.prose h2 {
color: #2563eb;
border-bottom: 2px solid #3b82f6;
padding-bottom: 5px;
}
"""
# Örnek metinler - 20. yüzyıl başı Türkçesi ve modern karışımı
examples = [
# 20. yüzyıl başı Türkçesi örnekleri
["Bu müessif ahval-i hazıra karşısında kalbimin hüzn ü melali had ü hesaba gelmeyub, devlet-i aliyyenin bu derece inhitat ve tedennisi beni gayet müteessir ve mahzun eylemiştir."],
["Pek mübarek ve mes'ud bir gün idi. Cennet-mekan Padişahımızın cülus-ı hümayunları münasebetiyle bütün tebaası kemâl-i sürur ve şadmanlık içinde bulunuyordu."],
["Bu kitab-ı mufîdin mütalaasından istifade-i azîme hâsıl olmuş ve ilm ü marifetimde tezayüd vuku bulmuştur. Müellif-i muhteremi hakkında duâ-yı hayr ile yâd eylerim."],
["Böyle bir hâdise-i elîmenin vukuu beni pek müteessir etmiş ve kalb-i âcizanemde derin bir teessür bırakmıştır. Allah her müslümânı böyle belâlardan muhafaza buyursun."],
["İş bu mes'ele-i mühimme hakkında düşündükçe efkâr-ı âcizanem daha ziyade karışmakta ve ne suretle hal edilebileceğini tayin edemez bir hale gelmekteyim."]
]
# Arayüz oluştur
interface = gr.Interface(
fn=predict_sentiment,
inputs=gr.Textbox(
label="📝 Analiz Edilecek Metin",
placeholder="Duygu analizini yapmak istediğiniz Türkçe metni buraya yazın...",
lines=4,
max_lines=10
),
outputs=gr.Markdown(
label="🎯 Analiz Sonucu"
),
title="🤖 histurk-BERTurk-Sentiment Modeli Demosudur",
description="""
Bu uygulama, **Tarihi Türkçe-Osmanlıca metinler** için özel olarak geliştirilmiş BERT tabanlı bir sentiment analizi modeli kullanır.
### 🕰️ Tarihi Metin Desteği:
• 20. yüzyıl başı Osmanlı Türkçesi
• Geçiş dönemi metinleri
• Modern Türkçe metinler
### 📚 Örnek Kullanım Alanları:
• Tarihi belgeler ve mektuplar
• Hatıratlar, biyografiler
• Gazete arşivleri (1900-1950)
• Edebi eserler
• Sosyal medya ve modern metinler
### 🎯 Özellikler:
• Tarihi dil yapılarını anlayabilir
• Osmanlıca kelime ve tamlamaları tanır
• Gerçek zamanlı analiz
• Detaylı güven skorları
**Model:** `dbbiyte/histurk-BERTurk-sentiment`
""",
examples=examples,
cache_examples=False,
theme=gr.themes.Soft(
primary_hue="blue",
secondary_hue="gray"
),
css=css,
allow_flagging="never"
)
return interface
# Uygulamayı başlat
if __name__ == "__main__":
print("🚀 HistTürk Duygu Analizi başlatılıyor...")
interface = create_interface()
interface.launch(
share=False,
server_name="0.0.0.0",
server_port=7860
)