| import gradio as gr
|
| import torch
|
| import re
|
| import unicodedata
|
| from transformers import AutoModelForSequenceClassification, AutoTokenizer
|
| import torch.nn.functional as F
|
|
|
|
|
| REPO_NAME = "ArabicNewsAnalyzer/arabic-dialect-identifier-msa-lev"
|
|
|
|
|
| PREPROCESS_CONFIG = {
|
| 'remove_urls' : True,
|
| 'remove_mentions' : True,
|
| 'remove_hashtags' : True,
|
| 'remove_emojis' : True,
|
| 'remove_punctuation' : True,
|
| 'remove_latin' : True,
|
| 'remove_digits' : True,
|
| 'normalize_alef' : True,
|
| 'normalize_yeh' : True,
|
| 'normalize_teh_marbuta' : True,
|
| 'remove_tatweel' : True,
|
| 'remove_diacritics' : True,
|
| 'remove_extra_spaces' : True,
|
| 'min_token_length' : 2,
|
| }
|
|
|
| ARABIC_DIACRITICS_PATTERN = re.compile(r'[\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED]')
|
| TATWEEL_PATTERN = re.compile(r'\u0640')
|
| ALEF_PATTERN = re.compile(r'[\u0622\u0623\u0625\u0671]')
|
| YEH_PATTERN = re.compile(r'\u0649')
|
| TEH_MARBUTA_PATTERN = re.compile(r'\u0629')
|
|
|
| def is_emoji(char):
|
| try:
|
| return unicodedata.category(char) in ('So', 'Sm') or ord(char) in range(0x1F600, 0x1FFFF)
|
| except TypeError:
|
| return False
|
|
|
| def preprocess(text: str, cfg: dict) -> str:
|
| if not isinstance(text, str):
|
| return ''
|
| if cfg['remove_urls']:
|
| text = re.sub(r'https?://\S+|www\.\S+', ' ', text)
|
| if cfg['remove_mentions']:
|
| text = re.sub(r'@\w+', ' ', text)
|
| if cfg['remove_hashtags']:
|
| text = re.sub(r'#\w+', ' ', text)
|
| if cfg['remove_emojis']:
|
| text = ''.join(c for c in text if not is_emoji(c))
|
| if cfg['remove_punctuation']:
|
| text = re.sub(r'[!\"#$%&\'()*+,\-./:;<=>?@\[\\\]^_`{|}~ุุุยซยป]', ' ', text)
|
| if cfg['remove_latin']:
|
| text = re.sub(r'[a-zA-Z]', ' ', text)
|
| if cfg['remove_digits']:
|
| text = re.sub(r'[0-9ู -ูฉ]', ' ', text)
|
| if cfg['normalize_alef']:
|
| text = ALEF_PATTERN.sub('\u0627', text)
|
| if cfg['normalize_yeh']:
|
| text = YEH_PATTERN.sub('\u064A', text)
|
| if cfg['normalize_teh_marbuta']:
|
| text = TEH_MARBUTA_PATTERN.sub('\u0647', text)
|
| if cfg['remove_tatweel']:
|
| text = TATWEEL_PATTERN.sub('', text)
|
| if cfg['remove_diacritics']:
|
| text = ARABIC_DIACRITICS_PATTERN.sub('', text)
|
| if cfg['remove_extra_spaces']:
|
| text = re.sub(r'\s+', ' ', text).strip()
|
| return text
|
|
|
|
|
| tokenizer = AutoTokenizer.from_pretrained(REPO_NAME)
|
| model = AutoModelForSequenceClassification.from_pretrained(REPO_NAME)
|
| model.eval()
|
|
|
|
|
| device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
|
| model.to(device)
|
|
|
| def predict_dialect(text):
|
| if not text.strip():
|
| return {"Please enter some text": 1.0}
|
|
|
|
|
| clean_text = preprocess(text, PREPROCESS_CONFIG)
|
|
|
|
|
| if len(clean_text.split()) < PREPROCESS_CONFIG['min_token_length']:
|
| return {"Error: Input too short after cleaning (URLs/Mentions removed).": 1.0}
|
|
|
|
|
| inputs = tokenizer(
|
| clean_text,
|
| max_length=128,
|
| padding='max_length',
|
| truncation=True,
|
| return_tensors="pt"
|
| )
|
|
|
| inputs = {k: v.to(device) for k, v in inputs.items()}
|
|
|
|
|
| with torch.no_grad():
|
| outputs = model(**inputs)
|
|
|
| probabilities = F.softmax(outputs.logits, dim=-1).squeeze(0)
|
|
|
|
|
| confidences = {model.config.id2label[i]: float(probabilities[i]) for i in range(model.config.num_labels)}
|
|
|
|
|
| return confidences
|
|
|
|
|
| iface = gr.Interface(
|
| fn=predict_dialect,
|
| inputs=gr.Textbox(
|
| lines=3,
|
| placeholder="Enter Arabic text here...",
|
| label="Arabic Text"
|
| ),
|
| outputs=gr.Label(num_top_classes=len(model.config.id2label), label="Predicted Dialect Confidence"),
|
| title="Arabic Dialect Identification (Two Regions)",
|
| description="Fine-tuned UBC-NLP/MARBERTv2 to detect regional Arabic dialects. (Preprocessing removes punctuation, Latin chars, URLs, Emojis, and Normalizes text exactly as in training).",
|
| examples=[
|
| ["ุดูููู ุดุฎุจุงุฑู ูุง ุฎูู"],
|
| ["ูุด ุญุงูู ูุด ุนููู
ูุ"],
|
| ["ุงุฒูู ูุง ุนู
ุนุงู
ู ุงููุ"],
|
| ]
|
| )
|
|
|
| iface.launch() |