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 )