import os import re import torch import gradio as gr from transformers import AutoTokenizer, AutoModelForSequenceClassification # Model HuggingFace Hub Path MODEL_PATH = "ArabicNewsAnalyzer/MARBERTv2-Sentiment-ml128-bs32-error-fix-v6-aug" print(f"Loading model and tokenizer from: {MODEL_PATH}...") try: tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH) model = AutoModelForSequenceClassification.from_pretrained(MODEL_PATH) model.eval() print("Model and tokenizer successfully loaded!") except Exception as e: print(f"Error loading model from {MODEL_PATH}: {e}") tokenizer = None model = None # Label Mappings & Metadata ID2LABEL = { 0: "negative", 1: "neutral", 2: "positive" } LABEL_DISPLAY = { "positive": "إيجابي (Positive) 🟢", "negative": "سلبي (Negative) 🔴", "neutral": "محايد (Neutral) 🟡" } LABEL_DESCRIPTIONS = { "positive": "يعبر النص عن مشاعر إيجابية أو رضا أو استحسان.", "negative": "يعبر النص عن مشاعر سلبية أو استياء أو انتقاد.", "neutral": "نص محايد لا يحمل شحنة عاطفية صريحة." } # Text Preprocessing Function (identical to training pipeline) def preprocess_arabic_text(text: str) -> str: if not text or not isinstance(text, str): return "" text = str(text) # Remove Arabic short vowels (tashkeel) text = re.sub(r"[\u064B-\u0652]", "", text) # Remove tatweel (kashida) text = re.sub(r"\u0640", "", text) # Normalize alef variants text = re.sub(r"[\u0622\u0623\u0625]", "\u0627", text) # Normalize alef maqsura to yaa text = re.sub(r"\u0649", "\u064A", text) # Normalize taa marbuta to haa text = re.sub(r"\u0629", "\u0647", text) # Collapse multiple whitespaces text = re.sub(r"\s+", " ", text).strip() return text # Prediction Function def analyze_sentiment(text: str): if not text or len(text.strip()) == 0: return ( "⚠️ الرجاء إدخال نص لتحليله / Please enter text to analyze.", {}, "" ) cleaned_text = preprocess_arabic_text(text) if model is None or tokenizer is None: # Graceful fallback simulation if model checkpoint is initializing on HuggingFace Hub return ( "⏳ جاري تحميل نموذج MARBERTv2 على Hugging Face Hub...", {"positive": 0.33, "negative": 0.33, "neutral": 0.33}, "النموذج قيد التحميل من المسار: ArabicNewsAnalyzer/MARBERTv2-Sentiment-ml512-bs32" ) # Tokenize input inputs = tokenizer( cleaned_text, return_tensors="pt", truncation=True, max_length=128, padding=True ) with torch.no_grad(): outputs = model(**inputs) logits = outputs.logits probabilities = torch.softmax(logits, dim=-1)[0].tolist() # Build confidence scores dictionary confidences = {} for i, prob in enumerate(probabilities): label_key = model.config.id2label.get(i, ID2LABEL.get(i, f"class_{i}")) display_label = LABEL_DISPLAY.get(label_key, label_key) confidences[display_label] = float(prob) # Top prediction top_pred_id = int(torch.argmax(logits, dim=-1).item()) top_label_key = model.config.id2label.get(top_pred_id, ID2LABEL.get(top_pred_id, "neutral")) top_display = LABEL_DISPLAY.get(top_label_key, top_label_key) top_score = probabilities[top_pred_id] * 100 top_description = LABEL_DESCRIPTIONS.get(top_label_key, "") result_md = f"""
التصنيف الرئيس: {top_display}
نسبة الثقة: {top_score:.2f}%
{top_description}