Spaces:
Sleeping
Sleeping
| import torch | |
| from transformers import AutoTokenizer, AutoModelForSequenceClassification | |
| from transformers import pipeline | |
| import logging | |
| import os | |
| import json | |
| import time | |
| from typing import List, Dict, Any, Tuple, Optional, Union | |
| from models.model_selector import ModelSelector | |
| # Loglama yapılandırması | |
| logger = logging.getLogger(__name__) | |
| handler = logging.StreamHandler() | |
| formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') | |
| handler.setFormatter(formatter) | |
| logger.addHandler(handler) | |
| logger.setLevel(logging.INFO) | |
| class ModelManager: | |
| """ | |
| Metin kalitesi ve zararlılık değerlendirmesi için NLP modellerini yöneten sınıf. | |
| Bu sınıf, modellerin yüklenmesi, değerlendirilmesi ve seçilmesinden sorumludur. | |
| """ | |
| def __init__(self, cache_dir: Optional[str] = None, use_cache: bool = True) -> None: | |
| """ | |
| Model Yöneticisi sınıfını başlatır. | |
| Args: | |
| cache_dir: Modellerin önbelleğe alınacağı dizin | |
| use_cache: Önbellek kullanımını etkinleştir/devre dışı bırak | |
| """ | |
| self.toxicity_model = None | |
| self.toxicity_tokenizer = None | |
| self.quality_pipeline = None | |
| self.device = "cuda" if torch.cuda.is_available() else "cpu" | |
| self.cache_dir = cache_dir or os.path.join(os.path.expanduser("~"), ".text_quality_toxicity_cache") | |
| self.use_cache = use_cache | |
| self.model_selector = ModelSelector(cache_dir=self.cache_dir, use_cache=self.use_cache) | |
| self.model_info = { | |
| "toxicity": { | |
| "name": "Bilinmeyen Model", | |
| "description": "Model henüz yüklenmedi", | |
| "language": "unknown" | |
| }, | |
| "quality": { | |
| "name": "Bilinmeyen Model", | |
| "description": "Model henüz yüklenmedi", | |
| "language": "unknown" | |
| } | |
| } | |
| # Önbellek dizinini oluştur | |
| if self.use_cache and not os.path.exists(self.cache_dir): | |
| os.makedirs(self.cache_dir, exist_ok=True) | |
| logger.info( | |
| f"ModelManager başlatıldı. Cihaz: {self.device}, Önbellek: {'Etkin' if use_cache else 'Devre dışı'}") | |
| def load_models_auto_select(self, sample_texts: Optional[List[str]] = None) -> bool: | |
| """ | |
| En iyi modelleri otomatik olarak seçerek yükler. | |
| Args: | |
| sample_texts: Model seçimi için örnek metinler | |
| Returns: | |
| bool: Yükleme başarılı mı? | |
| """ | |
| if sample_texts is None or len(sample_texts) == 0: | |
| # Örnek metinler yoksa varsayılan örnekler kullan | |
| sample_texts = [ | |
| "Türkiye, zengin tarihi ve kültürel mirası ile güzel bir ülkedir.", | |
| "Bu ürün tam bir hayal kırıklığı! Paramı geri istiyorum!", | |
| "Bugün hava çok güzel. Parkta yürüyüş yaptım ve kuşları izledim.", | |
| "Sen ne anlarsın ki bu konudan? Boş konuşma artık!" | |
| ] | |
| try: | |
| logger.info("Otomatik model seçimi başlatılıyor...") | |
| start_time = time.time() | |
| success = self.model_selector.select_best_models(sample_texts) | |
| if success: | |
| best_models = self.model_selector.get_best_models() | |
| self.toxicity_model = best_models["toxicity_model"] | |
| self.toxicity_tokenizer = best_models["toxicity_tokenizer"] | |
| self.quality_pipeline = best_models["quality_pipeline"] | |
| self.model_info["toxicity"] = best_models["toxicity_model_info"] | |
| self.model_info["quality"] = best_models["quality_model_info"] | |
| selection_time = time.time() - start_time | |
| logger.info(f"Otomatik model seçimi {selection_time:.2f} saniyede tamamlandı") | |
| logger.info(f"Seçilen zararlılık modeli: {self.model_info['toxicity']['name']}") | |
| logger.info(f"Seçilen kalite modeli: {self.model_info['quality']['name']}") | |
| # Kullanılan modelleri önbelleğe kaydet | |
| if self.use_cache: | |
| self._save_models_to_cache() | |
| return True | |
| else: | |
| logger.error("Otomatik model seçimi başarısız oldu, varsayılan modellere dönülüyor") | |
| return self.load_default_models() | |
| except Exception as e: | |
| logger.error(f"Otomatik model seçimi sırasında hata: {str(e)}") | |
| return self.load_default_models() | |
| def load_default_models(self) -> bool: | |
| """ | |
| Varsayılan modelleri yükler (otomatik seçim başarısız olursa). | |
| Returns: | |
| bool: Yükleme başarılı mı? | |
| """ | |
| logger.info("Varsayılan modeller yükleniyor...") | |
| # Önce önbellekten yüklemeyi dene | |
| if self.use_cache and self._load_models_from_cache(): | |
| logger.info("Modeller önbellekten başarıyla yüklendi") | |
| return True | |
| success_toxicity = self.load_toxicity_model() | |
| success_quality = self.load_quality_model() | |
| overall_success = success_toxicity and success_quality | |
| if overall_success and self.use_cache: | |
| self._save_models_to_cache() | |
| return overall_success | |
| def load_toxicity_model(self, model_name: str = "savasy/bert-base-turkish-sentiment") -> bool: | |
| """ | |
| Zararlılık tespiti için model yükleme. | |
| Args: | |
| model_name: Yüklenecek model ismi | |
| Returns: | |
| bool: Yükleme başarılı mı? | |
| """ | |
| try: | |
| logger.info(f"Zararlılık modeli yükleniyor: {model_name}") | |
| self.toxicity_tokenizer = AutoTokenizer.from_pretrained(model_name) | |
| self.toxicity_model = AutoModelForSequenceClassification.from_pretrained(model_name) | |
| self.model_info["toxicity"]["name"] = model_name | |
| self.model_info["toxicity"]["description"] = "Türkçe duygu analizi modeli" | |
| self.model_info["toxicity"]["language"] = "tr" | |
| logger.info("Zararlılık modeli başarıyla yüklendi") | |
| return True | |
| except Exception as e: | |
| logger.error(f"Zararlılık modeli yüklenirken hata: {str(e)}") | |
| # Alternatif model deneyelim | |
| try: | |
| backup_model = "dbmdz/bert-base-turkish-cased" | |
| logger.info(f"Yedek Türkçe model deneniyor: {backup_model}") | |
| self.toxicity_tokenizer = AutoTokenizer.from_pretrained(backup_model) | |
| self.toxicity_model = AutoModelForSequenceClassification.from_pretrained(backup_model) | |
| self.model_info["toxicity"]["name"] = backup_model | |
| self.model_info["toxicity"]["description"] = "Genel amaçlı Türkçe BERT modeli" | |
| self.model_info["toxicity"]["language"] = "tr" | |
| logger.info("Yedek Türkçe model başarıyla yüklendi") | |
| return True | |
| except Exception as e2: | |
| logger.error(f"Yedek Türkçe model yüklenirken hata: {str(e2)}") | |
| try: | |
| fallback_model = "distilbert/distilbert-base-uncased-finetuned-sst-2-english" | |
| logger.info(f"İngilizce duygu analizi modeli deneniyor: {fallback_model}") | |
| self.toxicity_tokenizer = AutoTokenizer.from_pretrained(fallback_model) | |
| self.toxicity_model = AutoModelForSequenceClassification.from_pretrained(fallback_model) | |
| self.model_info["toxicity"]["name"] = fallback_model | |
| self.model_info["toxicity"]["description"] = "İngilizce duygu analizi modeli" | |
| self.model_info["toxicity"]["language"] = "en" | |
| logger.info("İngilizce duygu analizi modeli başarıyla yüklendi") | |
| return True | |
| except Exception as e3: | |
| logger.error(f"İngilizce model yüklenirken hata: {str(e3)}") | |
| return False | |
| def load_quality_model(self, model_name: str = "sshleifer/distilbart-cnn-6-6") -> bool: | |
| """ | |
| Metin kalitesi değerlendirmesi için model yükleme. | |
| Args: | |
| model_name: Yüklenecek model ismi | |
| Returns: | |
| bool: Yükleme başarılı mı? | |
| """ | |
| try: | |
| logger.info(f"Kalite modeli yükleniyor: {model_name}") | |
| self.quality_pipeline = pipeline( | |
| "text2text-generation", | |
| model=model_name, | |
| tokenizer=model_name, | |
| device=0 if self.device == "cuda" else -1 | |
| ) | |
| self.model_info["quality"]["name"] = model_name | |
| self.model_info["quality"]["description"] = "İngilizce metin özetleme modeli" | |
| self.model_info["quality"]["language"] = "en" | |
| logger.info("Kalite modeli başarıyla yüklendi") | |
| return True | |
| except Exception as e: | |
| logger.error(f"Kalite modeli yüklenirken hata: {str(e)}") | |
| # Daha hafif bir model deneyelim | |
| try: | |
| backup_model = "Helsinki-NLP/opus-mt-tr-en" | |
| logger.info(f"Türkçe çeviri modeli deneniyor: {backup_model}") | |
| self.quality_pipeline = pipeline( | |
| "translation", | |
| model=backup_model, | |
| device=0 if self.device == "cuda" else -1 | |
| ) | |
| self.model_info["quality"]["name"] = backup_model | |
| self.model_info["quality"]["description"] = "Türkçe-İngilizce çeviri modeli" | |
| self.model_info["quality"]["language"] = "tr" | |
| logger.info("Türkçe çeviri modeli başarıyla yüklendi") | |
| return True | |
| except Exception as e2: | |
| logger.error(f"Türkçe çeviri modeli yüklenirken hata: {str(e2)}") | |
| try: | |
| light_model = "sshleifer/distilbart-xsum-12-6" | |
| logger.info(f"Daha hafif özetleme modeli deneniyor: {light_model}") | |
| self.quality_pipeline = pipeline( | |
| "text2text-generation", | |
| model=light_model, | |
| device=0 if self.device == "cuda" else -1 | |
| ) | |
| self.model_info["quality"]["name"] = light_model | |
| self.model_info["quality"]["description"] = "Hafif İngilizce özetleme modeli" | |
| self.model_info["quality"]["language"] = "en" | |
| logger.info("Hafif özetleme modeli başarıyla yüklendi") | |
| return True | |
| except Exception as e3: | |
| logger.error(f"Hafif özetleme modeli yüklenirken hata: {str(e3)}") | |
| return False | |
| def _save_models_to_cache(self) -> None: | |
| """Kullanılan modellerin bilgilerini önbelleğe kaydeder.""" | |
| if not self.use_cache: | |
| return | |
| try: | |
| cache_file = os.path.join(self.cache_dir, "model_manager_state.json") | |
| cache_data = { | |
| "timestamp": time.time(), | |
| "model_info": self.model_info | |
| } | |
| with open(cache_file, 'w', encoding='utf-8') as f: | |
| json.dump(cache_data, f, ensure_ascii=False, indent=2) | |
| logger.info(f"Model bilgileri önbelleğe kaydedildi: {cache_file}") | |
| except Exception as e: | |
| logger.error(f"Önbelleğe kaydetme hatası: {str(e)}") | |
| def _load_models_from_cache(self) -> bool: | |
| """ | |
| Önbellekten model bilgilerini yükler. | |
| Returns: | |
| bool: Yükleme başarılı mı? | |
| """ | |
| if not self.use_cache: | |
| return False | |
| try: | |
| cache_file = os.path.join(self.cache_dir, "model_manager_state.json") | |
| if not os.path.exists(cache_file): | |
| return False | |
| # Önbellek dosyasının yaşını kontrol et (24 saatten eskiyse yok say) | |
| file_age = time.time() - os.path.getmtime(cache_file) | |
| if file_age > 86400: # 24 saat = 86400 saniye | |
| logger.info(f"Önbellek dosyası çok eski ({file_age / 3600:.1f} saat), yeniden yükleme yapılacak") | |
| return False | |
| with open(cache_file, 'r', encoding='utf-8') as f: | |
| cache_data = json.load(f) | |
| # Model bilgilerini önbellekten al | |
| self.model_info = cache_data.get("model_info", self.model_info) | |
| # Önbellekteki bilgilerle yeniden yükleme yap | |
| toxicity_name = self.model_info["toxicity"].get("name") | |
| quality_name = self.model_info["quality"].get("name") | |
| toxicity_success = self.load_toxicity_model(toxicity_name) if toxicity_name else False | |
| quality_success = self.load_quality_model(quality_name) if quality_name else False | |
| return toxicity_success and quality_success | |
| except Exception as e: | |
| logger.error(f"Önbellekten model yükleme hatası: {str(e)}") | |
| return False | |
| def get_models(self) -> Dict[str, Any]: | |
| """ | |
| Yüklenen modelleri ve bilgilerini döndürür. | |
| Returns: | |
| Dict[str, Any]: Model, tokenizer, pipeline ve model bilgileri | |
| """ | |
| return { | |
| "toxicity_model": self.toxicity_model, | |
| "toxicity_tokenizer": self.toxicity_tokenizer, | |
| "quality_pipeline": self.quality_pipeline, | |
| "model_info": self.model_info | |
| } |