import gradio as gr from transformers import AutoTokenizer, AutoModelForSequenceClassification import torch import re from typing import Dict import textstat # ======================= # إعداد النموذج # ======================= MODEL_PATH = "GhadaAlothman/arabert_readability_3class" tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH) model = AutoModelForSequenceClassification.from_pretrained(MODEL_PATH) model.eval() DIACRITICS = re.compile(r"[\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06ED]") AR_LETTERS = r"[\u0600-\u06FF]" SENT_SEP = re.compile(r"[\.!\?؟؛…]+") WORD_RE = re.compile(fr"{AR_LETTERS}+") # ======================= # دوال المساعدة # ======================= def strip_diacritics(s: str): return DIACRITICS.sub("", s) def normalize_arabic(s: str): return re.sub("[\u0622\u0623\u0625]", "ا", strip_diacritics(s)).replace("ى", "ي").replace("ة", "ه") def split_sentences(text: str): return [p.strip() for p in SENT_SEP.split(text) if p.strip()] def tokenize_words(text: str): return WORD_RE.findall(text) def difficult_word(w: str, min_len: int = 6): return len(w) >= min_len def compute_metrics(ar_text: str) -> Dict[str, float]: text_norm = normalize_arabic(ar_text) sents = split_sentences(text_norm) words = tokenize_words(text_norm) n_sents, n_words = max(len(sents), 1), max(len(words), 1) diff_count = sum(1 for w in words if difficult_word(w)) try: osman = float(textstat.osman(ar_text)) except Exception: osman = 0.0 n_chars = sum(len(w) for w in words) ari_ar_score = round((4.71 * (n_chars / n_words)) + (0.5 * (n_words / n_sents)) - 21.43, 3) return { "Word count": n_words, "Sentence count": n_sents, "Character count": n_chars, "OSMAN_Score": round(osman, 3), "ARI_ArScore": ari_ar_score, "Difficult_Words_Count": diff_count, "Average_Sentence_Length_in_Words": round(n_words / n_sents, 3), } # ======================= # دالة التنبؤ # ======================= def analyze_text(text): inputs = tokenizer(text, return_tensors="pt", truncation=True, padding=True, max_length=128) with torch.no_grad(): outputs = model(**inputs) probs = torch.nn.functional.softmax(outputs.logits, dim=-1) label_id = torch.argmax(probs, dim=1).item() label_map = {0: "سهل", 1: "متوسط", 2: "صعب"} label = label_map[label_id] stats = compute_metrics(text) return {"Predicted_Label": label, **stats} # ======================= # واجهة Gradio # ======================= demo = gr.Interface( fn=analyze_text, inputs=gr.Textbox(label="أدخل النص العربي هنا", lines=6), outputs=gr.JSON(label="نتائج التحليل"), api_name="predict", # ← تأكدي إن هذا السطر موجود! title="Arabic Readability Analyzer", description="أداة ذكية لتقييم مقروئية النصوص العربية باستخدام نموذج AraBERT." ) demo.launch()