Spaces:
Running
Running
File size: 13,599 Bytes
bd97f47 |
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 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 |
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
} |