Update app.py
Browse files
app.py
CHANGED
|
@@ -1,24 +1,36 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
import torch
|
| 3 |
-
from transformers import pipeline
|
| 4 |
import re
|
| 5 |
|
| 6 |
-
# Global
|
| 7 |
-
|
|
|
|
|
|
|
| 8 |
|
| 9 |
-
def
|
| 10 |
-
"""Load
|
| 11 |
-
global
|
| 12 |
-
|
|
|
|
|
|
|
| 13 |
print("🏔️ Loading Atlas-Chat-2B model...")
|
| 14 |
-
|
| 15 |
"text-generation",
|
| 16 |
model="MBZUAI-Paris/Atlas-Chat-2B",
|
| 17 |
model_kwargs={"torch_dtype": torch.bfloat16},
|
| 18 |
device="cuda" if torch.cuda.is_available() else "cpu"
|
| 19 |
)
|
| 20 |
-
print("✅
|
| 21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
|
| 23 |
def detect_arabizi(text):
|
| 24 |
"""
|
|
@@ -60,7 +72,8 @@ def detect_arabizi(text):
|
|
| 60 |
'salam', 'salamu aleikum', 'slm',
|
| 61 |
'yallah', 'yalla', 'hya', 'aji',
|
| 62 |
'mabghitsh', 'mabghach', 'makansh', 'machi',
|
| 63 |
-
'walakin', 'walaken', 'ama', 'mais'
|
|
|
|
| 64 |
]
|
| 65 |
|
| 66 |
text_lower = text.lower()
|
|
@@ -76,246 +89,68 @@ def detect_arabizi(text):
|
|
| 76 |
|
| 77 |
return False
|
| 78 |
|
| 79 |
-
def
|
| 80 |
"""
|
| 81 |
-
Convert Arabizi text to Arabic
|
| 82 |
-
COMPLETE HARD-CODED MAPPINGS
|
| 83 |
"""
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
# COMPREHENSIVE WORD MAPPINGS (Arabizi → Arabic)
|
| 88 |
-
word_mappings = {
|
| 89 |
-
# Pronouns
|
| 90 |
-
'ana': 'أنا', 'nta': 'نتا', 'nti': 'نتي', 'howa': 'هوا', 'hiya': 'هيا',
|
| 91 |
-
'hoa': 'هوا', 'hia': 'هيا', 'hna': 'حنا', 'ahna': 'أحنا',
|
| 92 |
-
'ntuma': 'نتوما', 'ntouma': 'نتوما', 'huma': 'هوما', 'houma': 'هوما',
|
| 93 |
-
|
| 94 |
-
# Question words
|
| 95 |
-
'shkoun': 'شكون', 'chkoun': 'شكون', 'skoun': 'شكون',
|
| 96 |
-
'achno': 'أشنو', 'chno': 'شنو', 'shno': 'شنو', 'ach': 'أش',
|
| 97 |
-
'wach': 'واش', 'wash': 'واش', 'ouach': 'واش',
|
| 98 |
-
'kifash': 'كيفاش', 'kif': 'كيف', 'ki': 'كي', 'kayf': 'كيف',
|
| 99 |
-
'feen': 'فين', 'fin': 'فين', 'fen': 'فين', 'fain': 'فين', 'mnin': 'منين',
|
| 100 |
-
'imta': 'إمتا', 'meta': 'متا', 'mata': 'متا', 'emta': 'إمتا',
|
| 101 |
-
'3lach': 'علاش', 'alach': 'علاش', '3la ach': 'علاش',
|
| 102 |
-
|
| 103 |
-
# Common verbs
|
| 104 |
-
'bghit': 'بغيت', 'bghiti': 'بغيتي', 'bgha': 'بغا', 'bghina': 'بغينا',
|
| 105 |
-
'kan': 'كان', 'kana': 'كانا', 'kanet': 'كانت', 'kanu': 'كانو',
|
| 106 |
-
'galt': 'قلت', 'galti': 'قلتي', 'gal': 'قال', 'galet': 'قالت',
|
| 107 |
-
'galou': 'قالو', 'galina': 'قلنا',
|
| 108 |
-
'rah': 'راح', 'raha': 'راها', 'rahi': 'راهي', 'rahom': 'راهم',
|
| 109 |
-
'ghadi': 'غادي', 'ghad': 'غاد', 'gha': 'غا', 'ghadia': 'غادية',
|
| 110 |
-
'dir': 'دير', 'dert': 'درت', 'derat': 'درات', 'derna': 'درنا',
|
| 111 |
-
'ja': 'جا', 'jat': 'جات', 'jina': 'جينا', 'jaou': 'جاو',
|
| 112 |
-
'mcha': 'مشا', 'mchat': 'مشات', 'mchina': 'مشينا', 'mchaou': 'مشاو',
|
| 113 |
-
'khrj': 'خرج', 'khrja': 'خرجا', 'khrjat': 'خرجات', 'khrjna': 'خرجنا',
|
| 114 |
-
'dkhl': 'دخل', 'dkhla': 'دخلا', 'dkhlat': 'دخلات', 'dkhlna': 'دخلنا',
|
| 115 |
-
|
| 116 |
-
# Demonstratives
|
| 117 |
-
'had': 'هاد', 'hada': 'هادا', 'hadi': 'هادي', 'hadou': 'هادو',
|
| 118 |
-
'hadouk': 'هادوك', 'hadchi': 'هادشي', 'hadak': 'هاداك',
|
| 119 |
-
'dak': 'داك', 'dik': 'ديك', 'dok': 'دوك', 'dakchi': 'داكشي',
|
| 120 |
-
|
| 121 |
-
# Prepositions
|
| 122 |
-
'fi': 'في', 'f': 'ف', 'men': 'من', 'mn': 'من', 'l': 'ل', 'li': 'لي',
|
| 123 |
-
'bla': 'بلا', 'b': 'ب', 'bi': 'بي', 'bih': 'بيه', 'biha': 'بيها',
|
| 124 |
-
'mea': 'معا', 'maak': 'معاك', 'maaki': 'معاكي', 'maana': 'معانا',
|
| 125 |
-
'maahom': 'معاهم', 'maaha': 'معاها',
|
| 126 |
-
|
| 127 |
-
# Numbers
|
| 128 |
-
'wahed': 'واحد', 'joj': 'جوج', 'tlata': 'تلاتا', 'rebaa': 'ربعا',
|
| 129 |
-
'khamsa': 'خ��سا', 'setta': 'ستا', 'sebaa': 'سبعا', 'tmanya': 'تمنيا',
|
| 130 |
-
'tesaa': 'تسعا', 'ashra': 'عشرا',
|
| 131 |
-
|
| 132 |
-
# Time expressions
|
| 133 |
-
'daba': 'دابا', 'tawa': 'توا', 'ghda': 'غدا', 'lbareeh': 'البارح',
|
| 134 |
-
'nhar': 'نهار', 'lila': 'ليلا', 'sbah': 'صباح', 'aachia': 'عشيا',
|
| 135 |
-
|
| 136 |
-
# Family
|
| 137 |
-
'mama': 'ماما', 'baba': 'بابا', 'khoya': 'خويا', 'khti': 'ختي',
|
| 138 |
-
'khuya': 'خويا', 'khtiya': 'ختيا', 'akhi': 'أخي', 'ukhti': 'أختي',
|
| 139 |
-
'jad': 'جد', 'jada': 'جدا', 'amo': 'عمو', 'ama': 'عما',
|
| 140 |
-
'khal': 'خال', 'khala': 'خالا',
|
| 141 |
-
|
| 142 |
-
# Adjectives
|
| 143 |
-
'zwin': 'زوين', 'zwina': 'زوينا', 'qbih': 'قبيح', 'qbiha': 'قبيحا',
|
| 144 |
-
'kbir': 'كبير', 'kbira': 'كبيرا', 'sghir': 'صغير', 'sghira': 'صغيرا',
|
| 145 |
-
'tqil': 'تقيل', 'tqila': 'تقيلا', 'khfif': 'خفيف', 'khfifa': 'خفيفا',
|
| 146 |
-
'sahel': 'ساهل', 'sahla': 'ساهلا', 'saab': 'صعب', 'saba': 'صعبا',
|
| 147 |
-
|
| 148 |
-
# Quantities
|
| 149 |
-
'bzf': 'بزاف', 'bzzaf': 'بزاف', 'bezzaf': 'بزاف', 'ktir': 'كتير',
|
| 150 |
-
'chway': 'شوياة', 'chwiya': 'شوياة', 'shwiya': 'شوياة', 'chwia': 'شوياة',
|
| 151 |
-
'kolchi': 'كولشي', 'kol': 'كول', 'ga': 'غاع', 'gaa': 'غاع',
|
| 152 |
-
'hta': 'حتا', 'walo': 'والو', 'walou': 'والو',
|
| 153 |
-
|
| 154 |
-
# Negations
|
| 155 |
-
'ma': 'ما', 'machi': 'ماشي', 'mabghitsh': 'مابغيتش', 'makainch': 'ماكاينش',
|
| 156 |
-
'makansh': 'ماكانش', 'maghatch': 'ماغاتش', 'mabaghish': 'مابغيش',
|
| 157 |
|
| 158 |
-
#
|
| 159 |
-
|
| 160 |
-
'ama': 'أما', 'ida': 'إذا', 'ila': 'إلا', 'hta': 'حتا',
|
| 161 |
-
'ou': 'أو', 'o': 'أو', 'aw': 'أو', 'wla': 'ولا',
|
| 162 |
|
| 163 |
-
#
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
|
|
|
| 171 |
|
| 172 |
-
#
|
| 173 |
-
|
| 174 |
-
'rbat': 'الرباط', 'fas': 'فاس', 'mknas': 'مكناس',
|
| 175 |
-
'tanja': 'طنجا', 'agadir': 'أكادير', 'marrakech': 'مراكش',
|
| 176 |
|
| 177 |
-
|
| 178 |
-
'dar': 'دار', 'bit': 'بيت', 'tomo': 'طوموبيل', 'karhouba': 'كرهوبا',
|
| 179 |
-
'makla': 'ماكلا', 'atay': 'أتاي', 'khobz': 'خوبز', 'lma': 'الما',
|
| 180 |
-
'tajin': 'طاجين', 'tajine': 'طاجين', 'couscous': 'كوسكوس',
|
| 181 |
-
'msemen': 'مسمن', 'rghaif': 'رغايف', 'harira': 'حريرا',
|
| 182 |
-
'khodra': 'خضرا', 'fawakeh': 'فواكه', 'lahem': 'لحم',
|
| 183 |
-
'djaj': 'دجاج', 'hout': 'حوت', 'lben': 'اللبن',
|
| 184 |
-
'skar': 'سكر', 'melh': 'ملح', 'zit': 'زيت', 'zebda': 'زبدا',
|
| 185 |
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
'faq': 'فاق', 'faqat': 'فاقات', 'faqna': 'فقنا', 'faqou': 'فاقو',
|
| 191 |
-
'tlab': 'طلب', 'tlbat': 'طلبات', 'tlabna': 'طلبنا', 'tlabou': 'طلبو',
|
| 192 |
-
'khdam': 'خدم', 'khdmat': 'خدمات', 'khdamna': 'خدمنا', 'khdamou': 'خدمو',
|
| 193 |
-
'qra': 'قرا', 'qrat': 'قرات', 'qrina': 'قرينا', 'qraw': 'قراو',
|
| 194 |
-
'kteb': 'كتب', 'ktbat': 'كتبات', 'ktebna': 'كتبنا', 'ktbou': 'كتبو',
|
| 195 |
-
'chaf': 'شاف', 'chafat': 'شافات', 'chfna': 'شفنا', 'chafou': 'شافو',
|
| 196 |
-
'sma': 'سمع', 'smat': 'سمعات', 'smana': 'سمعنا', 'smaou': 'سمعو'
|
| 197 |
-
}
|
| 198 |
-
|
| 199 |
-
# CHARACTER MAPPINGS (Arabizi numbers/letters → Arabic)
|
| 200 |
-
char_mappings = {
|
| 201 |
-
'2': 'ء', '3': 'ع', '5': 'خ', '6': 'ط', '7': 'ح', '8': 'غ', '9': 'ق',
|
| 202 |
-
'a': 'ا', 'b': 'ب', 't': 'ت', 'th': 'ث', 'j': 'ج', 'd': 'د',
|
| 203 |
-
'r': 'ر', 'z': 'ز', 's': 'س', 'sh': 'ش', 'f': 'ف', 'k': 'ك',
|
| 204 |
-
'l': 'ل', 'm': 'م', 'n': 'ن', 'h': 'ه', 'w': 'و', 'y': 'ي',
|
| 205 |
-
'aa': 'آ', 'ee': 'ي', 'oo': 'و', 'ou': 'و', 'ai': 'ي', 'ay': 'ي'
|
| 206 |
-
}
|
| 207 |
-
|
| 208 |
-
# DIGRAPH MAPPINGS (two-letter combinations first)
|
| 209 |
-
digraph_mappings = {
|
| 210 |
-
'kh': 'خ', 'gh': 'غ', 'ch': 'ش', 'th': 'ث', 'dh': 'ذ',
|
| 211 |
-
'sh': 'ش', 'ts': 'ص', 'dz': 'ض', 'ss': 'ص', 'tt': 'ط',
|
| 212 |
-
'zz': 'ظ', 'aa': 'آ', 'ee': 'ي', 'ii': 'ي', 'oo': 'و',
|
| 213 |
-
'uu': 'و', 'ou': 'و', 'ai': 'ي', 'ay': 'ي', 'ey': 'ي'
|
| 214 |
-
}
|
| 215 |
-
|
| 216 |
-
# Convert text
|
| 217 |
-
result = text.lower()
|
| 218 |
-
|
| 219 |
-
# Step 1: Apply word mappings (most specific first)
|
| 220 |
-
for arabizi_word, arabic_word in word_mappings.items():
|
| 221 |
-
# Use word boundaries to avoid partial matches
|
| 222 |
-
pattern = r'\b' + re.escape(arabizi_word) + r'\b'
|
| 223 |
-
result = re.sub(pattern, arabic_word, result, flags=re.IGNORECASE)
|
| 224 |
-
|
| 225 |
-
# Step 2: Apply digraph mappings
|
| 226 |
-
for digraph, arabic_char in digraph_mappings.items():
|
| 227 |
-
result = result.replace(digraph, arabic_char)
|
| 228 |
-
|
| 229 |
-
# Step 3: Apply single character mappings
|
| 230 |
-
for char, arabic_char in char_mappings.items():
|
| 231 |
-
if len(char) == 1: # Only single chars in this step
|
| 232 |
-
result = result.replace(char, arabic_char)
|
| 233 |
-
|
| 234 |
-
return result
|
| 235 |
|
| 236 |
-
def arabic_to_arabizi(
|
| 237 |
"""
|
| 238 |
-
Convert Arabic script to Arabizi
|
| 239 |
-
|
| 240 |
"""
|
| 241 |
-
if not
|
| 242 |
-
return
|
| 243 |
|
| 244 |
# COMPREHENSIVE WORD MAPPINGS (Arabic → Arabizi)
|
| 245 |
word_mappings = {
|
| 246 |
-
#
|
| 247 |
'أنا': 'ana', 'نتا': 'nta', 'نتي': 'nti', 'هوا': 'howa', 'هيا': 'hiya',
|
| 248 |
'حنا': 'hna', 'أحنا': 'ahna', 'نتوما': 'ntuma', 'هوما': 'huma',
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
'
|
| 252 |
-
'واش': 'wach', 'كيفاش': 'kifash', 'كيف': 'kif', 'فين': 'feen',
|
| 253 |
-
'منين': 'mnin', 'إمتا': 'imta', 'متا': 'meta', 'علاش': '3lach',
|
| 254 |
-
|
| 255 |
-
# Common verbs
|
| 256 |
'بغيت': 'bghit', 'بغيتي': 'bghiti', 'بغا': 'bgha', 'بغينا': 'bghina',
|
| 257 |
'كان': 'kan', 'كانا': 'kana', 'كانت': 'kanet', 'كانو': 'kanu',
|
| 258 |
'قلت': 'galt', 'قلتي': 'galti', 'قال': 'gal', 'قالت': 'galet',
|
| 259 |
-
'قالو': 'galou', 'قلنا': 'galina',
|
| 260 |
'راح': 'rah', 'راها': 'raha', 'راهي': 'rahi', 'راهم': 'rahom',
|
| 261 |
-
'غادي': 'ghadi', 'غاد': 'ghad', 'غا': 'gha',
|
| 262 |
-
'
|
| 263 |
-
'
|
| 264 |
-
'
|
| 265 |
-
|
| 266 |
-
|
| 267 |
-
'هاد': 'had', 'هادا': 'hada', 'هادي': 'hadi', 'هادو': 'hadou',
|
| 268 |
-
'هادوك': 'hadouk', 'هادشي': 'hadchi', 'هاداك': 'hadak',
|
| 269 |
-
'داك': 'dak', 'ديك': 'dik', 'دوك': 'dok', 'داكشي': 'dakchi',
|
| 270 |
-
|
| 271 |
-
# Numbers
|
| 272 |
-
'واحد': 'wahed', 'جوج': 'joj', 'تلاتا': 'tlata', 'ربعا': 'rebaa',
|
| 273 |
-
'خمسا': 'khamsa', 'ستا': 'setta', 'سبعا': 'sebaa', 'تمنيا': 'tmanya',
|
| 274 |
-
'تسعا': 'tesaa', 'عشرا': 'ashra',
|
| 275 |
-
|
| 276 |
-
# Time
|
| 277 |
-
'دابا': 'daba', 'توا': 'tawa', 'غدا': 'ghda', 'البارح': 'lbareeh',
|
| 278 |
-
'نهار': 'nhar', 'ليلا': 'lila', 'صباح': 'sbah', 'عشيا': 'aachia',
|
| 279 |
-
|
| 280 |
-
# Family
|
| 281 |
'ماما': 'mama', 'بابا': 'baba', 'خويا': 'khoya', 'ختي': 'khti',
|
| 282 |
-
'
|
| 283 |
-
'
|
| 284 |
-
|
| 285 |
-
|
| 286 |
-
'زوين': 'zwin', 'زوينا': 'zwina', '
|
| 287 |
-
'كبير': 'kbir', 'كبيرا': 'kbira', 'صغير': 'sghir', 'صغيرا': 'sghira',
|
| 288 |
-
'تقيل': 'tqil', 'تقيلا': 'tqila', 'خفيف': 'khfif', 'خفيفا': 'khfifa',
|
| 289 |
-
|
| 290 |
-
# Quantities
|
| 291 |
-
'بزاف': 'bzzaf', 'كتير': 'ktir', 'شوياة': 'chwiya', 'كولشي': 'kolchi',
|
| 292 |
-
'كول': 'kol', 'غاع': 'gaa', 'حتا': 'hta', 'والو': 'walo',
|
| 293 |
-
|
| 294 |
-
# Negations
|
| 295 |
-
'ما': 'ma', 'ماشي': 'machi', 'مابغيتش': 'mabghitsh', 'ماكاينش': 'makainch',
|
| 296 |
-
'ماكانش': 'makansh', 'ماغاتش': 'maghatch', 'مابغيش': 'mabaghish',
|
| 297 |
-
|
| 298 |
-
# Expressions
|
| 299 |
-
'سلام': 'salam', 'يالاه': 'yallah', 'يالا': 'yalla', 'هيا': 'hya',
|
| 300 |
-
'أجي': 'aji', 'سير': 'sir', 'سيري': 'siri', 'أجو': 'ajou',
|
| 301 |
-
'مبروك': 'mabrook', 'باركا': 'baraka', 'بصحا': 'besaha',
|
| 302 |
-
'الله': 'allah', 'ربي': 'rabi', 'إن شاء الله': 'inchallah',
|
| 303 |
-
'ما شاء الله': 'machallah', 'الحمد لله': 'hamdulillah',
|
| 304 |
-
|
| 305 |
-
# Places
|
| 306 |
-
'المغرب': 'lmaghrib', 'مغرب': 'maghrib', 'كازا': 'casa',
|
| 307 |
-
'الرباط': 'rbat', 'فاس': 'fas', 'مكناس': 'mknas',
|
| 308 |
-
'طنجا': 'tanja', 'أكادير': 'agadir', 'مراكش': 'marrakech',
|
| 309 |
-
|
| 310 |
-
# Food and drinks
|
| 311 |
-
'طاجين': 'tajine', 'كوسكوس': 'couscous', 'مسمن': 'msemen',
|
| 312 |
-
'رغايف': 'rghaif', 'حريرا': 'harira', 'أتاي': 'atay',
|
| 313 |
-
'خوبز': 'khobz', 'الما': 'lma', 'لحم': 'lahem', 'دجاج': 'djaj',
|
| 314 |
-
|
| 315 |
-
# Common nouns
|
| 316 |
-
'دار': 'dar', 'بيت': 'bit', 'طوموبيل': 'tomo', 'كرهوبا': 'karhouba',
|
| 317 |
-
'ماكلا': 'makla', 'خضرا': 'khodra', 'فواكه': 'fawakeh',
|
| 318 |
-
'حوت': 'hout', 'اللبن': 'lben', 'سكر': 'skar', 'ملح': 'melh'
|
| 319 |
}
|
| 320 |
|
| 321 |
# CHARACTER MAPPINGS (Arabic → Arabizi)
|
|
@@ -325,42 +160,42 @@ def arabic_to_arabizi(text):
|
|
| 325 |
'ش': 'sh', 'ص': 's', 'ض': 'd', 'ط': '6', 'ظ': 'z', 'ع': '3',
|
| 326 |
'غ': 'gh', 'ف': 'f', 'ق': '9', 'ك': 'k', 'ل': 'l', 'م': 'm',
|
| 327 |
'ن': 'n', 'ه': 'h', 'و': 'w', 'ي': 'y', 'ء': '2',
|
| 328 |
-
'آ': 'aa', 'أ': 'a', 'إ': 'i', '
|
| 329 |
-
'
|
|
|
|
| 330 |
}
|
| 331 |
|
| 332 |
-
|
| 333 |
-
result = text
|
| 334 |
|
| 335 |
-
# Step 1: Apply word mappings
|
| 336 |
for arabic_word, arabizi_word in word_mappings.items():
|
| 337 |
# Use word boundaries to avoid partial matches
|
| 338 |
-
|
| 339 |
-
result = re.sub(pattern, arabizi_word, result)
|
| 340 |
|
| 341 |
# Step 2: Apply character mappings
|
| 342 |
for arabic_char, arabizi_char in char_mappings.items():
|
| 343 |
result = result.replace(arabic_char, arabizi_char)
|
| 344 |
|
| 345 |
-
return result
|
| 346 |
|
| 347 |
def chat_with_atlas(message, history):
|
| 348 |
-
"""Generate response from Atlas-Chat model with Arabizi conversion"""
|
| 349 |
if not message.strip():
|
| 350 |
-
return "
|
| 351 |
|
| 352 |
try:
|
| 353 |
-
# Load
|
| 354 |
-
|
| 355 |
|
| 356 |
# Detect if input is Arabizi
|
| 357 |
is_arabizi_input = detect_arabizi(message)
|
| 358 |
|
| 359 |
# Prepare input for the model
|
| 360 |
if is_arabizi_input:
|
| 361 |
-
# Convert Arabizi to Arabic
|
| 362 |
-
|
| 363 |
-
|
|
|
|
| 364 |
model_input = arabic_input
|
| 365 |
else:
|
| 366 |
# Use original input (Arabic or English)
|
|
@@ -369,27 +204,29 @@ def chat_with_atlas(message, history):
|
|
| 369 |
# Generate response using Arabic input
|
| 370 |
messages = [{"role": "user", "content": model_input}]
|
| 371 |
|
| 372 |
-
outputs =
|
| 373 |
messages,
|
| 374 |
max_new_tokens=256,
|
| 375 |
temperature=0.1,
|
| 376 |
do_sample=True,
|
| 377 |
-
pad_token_id=
|
| 378 |
)
|
| 379 |
|
| 380 |
# Extract the response
|
| 381 |
response = outputs[0]["generated_text"][-1]["content"].strip()
|
|
|
|
| 382 |
|
| 383 |
# Convert response back to Arabizi if input was Arabizi
|
| 384 |
if is_arabizi_input:
|
| 385 |
arabizi_response = arabic_to_arabizi(response)
|
| 386 |
-
print(f"🔄 Converted
|
| 387 |
return arabizi_response
|
| 388 |
else:
|
| 389 |
# Return original response for Arabic/English
|
| 390 |
return response
|
| 391 |
|
| 392 |
except Exception as e:
|
|
|
|
| 393 |
# Return error in appropriate language
|
| 394 |
if detect_arabizi(message):
|
| 395 |
return f"sorry, kan chi mochkil: {str(e)}. 3awd jar'b!"
|
|
@@ -399,16 +236,19 @@ def chat_with_atlas(message, history):
|
|
| 399 |
# Create the Gradio interface
|
| 400 |
demo = gr.ChatInterface(
|
| 401 |
fn=chat_with_atlas,
|
| 402 |
-
title="🏔️ Atlas-Chat: Moroccan Arabic AI
|
| 403 |
description="""
|
| 404 |
-
**مرحبا بك في أطلس
|
| 405 |
|
| 406 |
-
**🧠
|
| 407 |
- **Arabic Script (العربية)** → AI responds in Arabic
|
| 408 |
-
- **Arabizi (3arabi bi 7oruf latin)** → AI
|
| 409 |
- **English** → AI responds in English
|
| 410 |
|
| 411 |
-
|
|
|
|
|
|
|
|
|
|
| 412 |
|
| 413 |
**جرب هذه الأسئلة / Try these questions:**
|
| 414 |
""",
|
|
@@ -420,13 +260,14 @@ demo = gr.ChatInterface(
|
|
| 420 |
"شنو كيتسمى المنتخب المغربي؟",
|
| 421 |
"chno kaytsma lmontakhab lmaghribi?",
|
| 422 |
"What is Morocco famous for?",
|
| 423 |
-
"Tell me about Casablanca",
|
| 424 |
"كيفاش نقدر نتعلم الدارجة؟",
|
| 425 |
"kifash n9der nt3elem darija?",
|
| 426 |
"wach kayn atay f lmaghrib?",
|
| 427 |
"3lach lmaghrib zwien bzzaf?",
|
| 428 |
"kifash nsali tajine?",
|
| 429 |
-
"chno homa l2aklat lmaghribiya?"
|
|
|
|
|
|
|
| 430 |
],
|
| 431 |
cache_examples=False
|
| 432 |
)
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
import torch
|
| 3 |
+
from transformers import pipeline, AutoTokenizer, AutoModelForSeq2SeqLM
|
| 4 |
import re
|
| 5 |
|
| 6 |
+
# Global variables to store the models
|
| 7 |
+
atlas_pipe = None
|
| 8 |
+
transliteration_tokenizer = None
|
| 9 |
+
transliteration_model = None
|
| 10 |
|
| 11 |
+
def load_models():
|
| 12 |
+
"""Load both Atlas-Chat and Transliteration models"""
|
| 13 |
+
global atlas_pipe, transliteration_tokenizer, transliteration_model
|
| 14 |
+
|
| 15 |
+
# Load Atlas-Chat model
|
| 16 |
+
if atlas_pipe is None:
|
| 17 |
print("🏔️ Loading Atlas-Chat-2B model...")
|
| 18 |
+
atlas_pipe = pipeline(
|
| 19 |
"text-generation",
|
| 20 |
model="MBZUAI-Paris/Atlas-Chat-2B",
|
| 21 |
model_kwargs={"torch_dtype": torch.bfloat16},
|
| 22 |
device="cuda" if torch.cuda.is_available() else "cpu"
|
| 23 |
)
|
| 24 |
+
print("✅ Atlas-Chat model loaded!")
|
| 25 |
+
|
| 26 |
+
# Load Transliteration model
|
| 27 |
+
if transliteration_tokenizer is None or transliteration_model is None:
|
| 28 |
+
print("🔄 Loading Transliteration model...")
|
| 29 |
+
transliteration_tokenizer = AutoTokenizer.from_pretrained("atlasia/Transliteration-Moroccan-Darija")
|
| 30 |
+
transliteration_model = AutoModelForSeq2SeqLM.from_pretrained("atlasia/Transliteration-Moroccan-Darija")
|
| 31 |
+
print("✅ Transliteration model loaded!")
|
| 32 |
+
|
| 33 |
+
return atlas_pipe, transliteration_tokenizer, transliteration_model
|
| 34 |
|
| 35 |
def detect_arabizi(text):
|
| 36 |
"""
|
|
|
|
| 72 |
'salam', 'salamu aleikum', 'slm',
|
| 73 |
'yallah', 'yalla', 'hya', 'aji',
|
| 74 |
'mabghitsh', 'mabghach', 'makansh', 'machi',
|
| 75 |
+
'walakin', 'walaken', 'ama', 'mais',
|
| 76 |
+
'kayn', 'makaynsh', 'chi', 'tayi'
|
| 77 |
]
|
| 78 |
|
| 79 |
text_lower = text.lower()
|
|
|
|
| 89 |
|
| 90 |
return False
|
| 91 |
|
| 92 |
+
def arabizi_to_arabic_ai(arabizi_text):
|
| 93 |
"""
|
| 94 |
+
Convert Arabizi text to Arabic using the specialized AI model
|
|
|
|
| 95 |
"""
|
| 96 |
+
try:
|
| 97 |
+
_, tokenizer, model = load_models()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 98 |
|
| 99 |
+
# Tokenize the input text
|
| 100 |
+
input_tokens = tokenizer(arabizi_text, return_tensors="pt", padding=True, truncation=True, max_length=512)
|
|
|
|
|
|
|
| 101 |
|
| 102 |
+
# Perform transliteration
|
| 103 |
+
with torch.no_grad():
|
| 104 |
+
output_tokens = model.generate(
|
| 105 |
+
**input_tokens,
|
| 106 |
+
max_length=512,
|
| 107 |
+
num_beams=4,
|
| 108 |
+
early_stopping=True,
|
| 109 |
+
no_repeat_ngram_size=2
|
| 110 |
+
)
|
| 111 |
|
| 112 |
+
# Decode the output tokens
|
| 113 |
+
arabic_text = tokenizer.decode(output_tokens[0], skip_special_tokens=True)
|
|
|
|
|
|
|
| 114 |
|
| 115 |
+
return arabic_text.strip()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 116 |
|
| 117 |
+
except Exception as e:
|
| 118 |
+
print(f"❌ Error in Arabizi→Arabic conversion: {e}")
|
| 119 |
+
# Fallback to original text if conversion fails
|
| 120 |
+
return arabizi_text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
|
| 122 |
+
def arabic_to_arabizi(arabic_text):
|
| 123 |
"""
|
| 124 |
+
Convert Arabic script to Arabizi using character mappings
|
| 125 |
+
(Keeping this as backup since no reverse model available)
|
| 126 |
"""
|
| 127 |
+
if not arabic_text:
|
| 128 |
+
return arabic_text
|
| 129 |
|
| 130 |
# COMPREHENSIVE WORD MAPPINGS (Arabic → Arabizi)
|
| 131 |
word_mappings = {
|
| 132 |
+
# Common words first (most likely to appear)
|
| 133 |
'أنا': 'ana', 'نتا': 'nta', 'نتي': 'nti', 'هوا': 'howa', 'هيا': 'hiya',
|
| 134 |
'حنا': 'hna', 'أحنا': 'ahna', 'نتوما': 'ntuma', 'هوما': 'huma',
|
| 135 |
+
'شكون': 'shkoun', 'أشنو': 'achno', 'شنو': 'chno', 'واش': 'wach',
|
| 136 |
+
'كيفاش': 'kifash', 'كيف': 'kif', 'فين': 'feen', 'منين': 'mnin',
|
| 137 |
+
'إمتا': 'imta', 'متا': 'meta', 'علاش': '3lach', 'أش': 'ach',
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
'بغيت': 'bghit', 'بغيتي': 'bghiti', 'بغا': 'bgha', 'بغينا': 'bghina',
|
| 139 |
'كان': 'kan', 'كانا': 'kana', 'كانت': 'kanet', 'كانو': 'kanu',
|
| 140 |
'قلت': 'galt', 'قلتي': 'galti', 'قال': 'gal', 'قالت': 'galet',
|
|
|
|
| 141 |
'راح': 'rah', 'راها': 'raha', 'راهي': 'rahi', 'راهم': 'rahom',
|
| 142 |
+
'غادي': 'ghadi', 'غاد': 'ghad', 'غا': 'gha',
|
| 143 |
+
'هاد': 'had', 'هادا': 'hada', 'هادي': 'hadi', 'هادشي': 'hadchi',
|
| 144 |
+
'داك': 'dak', 'ديك': 'dik', 'داكشي': 'dakchi',
|
| 145 |
+
'بزاف': 'bzzaf', 'شوياة': 'chwiya', 'كولشي': 'kolchi',
|
| 146 |
+
'ماشي': 'machi', 'مابغيتش': 'mabghitsh', 'ماكاينش': 'makainch',
|
| 147 |
+
'دابا': 'daba', 'توا': 'tawa', 'غدا': 'ghda',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 148 |
'ماما': 'mama', 'بابا': 'baba', 'خويا': 'khoya', 'ختي': 'khti',
|
| 149 |
+
'سلام': 'salam', 'يالاه': 'yallah', 'هيا': 'hya',
|
| 150 |
+
'المغرب': 'lmaghrib', 'مغرب': 'maghrib',
|
| 151 |
+
'طاجين': 'tajine', 'أتاي': 'atay', 'خوبز': 'khobz',
|
| 152 |
+
'كاين': 'kayn', 'ماكاينش': 'makaynsh', 'شي': 'chi',
|
| 153 |
+
'زوين': 'zwin', 'زوينا': 'zwina', 'مزيان': 'mzyan', 'مزيانا': 'mzyana'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
}
|
| 155 |
|
| 156 |
# CHARACTER MAPPINGS (Arabic → Arabizi)
|
|
|
|
| 160 |
'ش': 'sh', 'ص': 's', 'ض': 'd', 'ط': '6', 'ظ': 'z', 'ع': '3',
|
| 161 |
'غ': 'gh', 'ف': 'f', 'ق': '9', 'ك': 'k', 'ل': 'l', 'م': 'm',
|
| 162 |
'ن': 'n', 'ه': 'h', 'و': 'w', 'ي': 'y', 'ء': '2',
|
| 163 |
+
'آ': 'aa', 'أ': 'a', 'إ': 'i', 'ة': 'a', 'ى': 'a',
|
| 164 |
+
'؟': '?', '،': ',', '؛': ';', ':': ':', '!': '!',
|
| 165 |
+
'َ': 'a', 'ُ': 'o', 'ِ': 'i', 'ً': 'an', 'ٌ': 'on', 'ٍ': 'in'
|
| 166 |
}
|
| 167 |
|
| 168 |
+
result = arabic_text
|
|
|
|
| 169 |
|
| 170 |
+
# Step 1: Apply word mappings
|
| 171 |
for arabic_word, arabizi_word in word_mappings.items():
|
| 172 |
# Use word boundaries to avoid partial matches
|
| 173 |
+
result = re.sub(r'\b' + re.escape(arabic_word) + r'\b', arabizi_word, result)
|
|
|
|
| 174 |
|
| 175 |
# Step 2: Apply character mappings
|
| 176 |
for arabic_char, arabizi_char in char_mappings.items():
|
| 177 |
result = result.replace(arabic_char, arabizi_char)
|
| 178 |
|
| 179 |
+
return result.strip()
|
| 180 |
|
| 181 |
def chat_with_atlas(message, history):
|
| 182 |
+
"""Generate response from Atlas-Chat model with AI-powered Arabizi conversion"""
|
| 183 |
if not message.strip():
|
| 184 |
+
return "ahlan wa sahlan! kifash n9der n3awnek? / مرحبا! كيفاش نقدر نعاونك؟"
|
| 185 |
|
| 186 |
try:
|
| 187 |
+
# Load models
|
| 188 |
+
atlas_model, _, _ = load_models()
|
| 189 |
|
| 190 |
# Detect if input is Arabizi
|
| 191 |
is_arabizi_input = detect_arabizi(message)
|
| 192 |
|
| 193 |
# Prepare input for the model
|
| 194 |
if is_arabizi_input:
|
| 195 |
+
# Convert Arabizi to Arabic using AI model
|
| 196 |
+
print(f"🔄 Converting Arabizi: '{message}'")
|
| 197 |
+
arabic_input = arabizi_to_arabic_ai(message)
|
| 198 |
+
print(f"✅ Converted to Arabic: '{arabic_input}'")
|
| 199 |
model_input = arabic_input
|
| 200 |
else:
|
| 201 |
# Use original input (Arabic or English)
|
|
|
|
| 204 |
# Generate response using Arabic input
|
| 205 |
messages = [{"role": "user", "content": model_input}]
|
| 206 |
|
| 207 |
+
outputs = atlas_model(
|
| 208 |
messages,
|
| 209 |
max_new_tokens=256,
|
| 210 |
temperature=0.1,
|
| 211 |
do_sample=True,
|
| 212 |
+
pad_token_id=atlas_model.tokenizer.eos_token_id
|
| 213 |
)
|
| 214 |
|
| 215 |
# Extract the response
|
| 216 |
response = outputs[0]["generated_text"][-1]["content"].strip()
|
| 217 |
+
print(f"🤖 Atlas response: '{response}'")
|
| 218 |
|
| 219 |
# Convert response back to Arabizi if input was Arabizi
|
| 220 |
if is_arabizi_input:
|
| 221 |
arabizi_response = arabic_to_arabizi(response)
|
| 222 |
+
print(f"🔄 Converted to Arabizi: '{arabizi_response}'")
|
| 223 |
return arabizi_response
|
| 224 |
else:
|
| 225 |
# Return original response for Arabic/English
|
| 226 |
return response
|
| 227 |
|
| 228 |
except Exception as e:
|
| 229 |
+
print(f"❌ Error in chat: {e}")
|
| 230 |
# Return error in appropriate language
|
| 231 |
if detect_arabizi(message):
|
| 232 |
return f"sorry, kan chi mochkil: {str(e)}. 3awd jar'b!"
|
|
|
|
| 236 |
# Create the Gradio interface
|
| 237 |
demo = gr.ChatInterface(
|
| 238 |
fn=chat_with_atlas,
|
| 239 |
+
title="🏔️ Atlas-Chat: Advanced Moroccan Arabic AI",
|
| 240 |
description="""
|
| 241 |
+
**مرحبا بك في أطلس شات المطور!** Welcome to Advanced Atlas-Chat! 🇲🇦
|
| 242 |
|
| 243 |
+
**🧠 AI-Powered Language Detection & Conversion:**
|
| 244 |
- **Arabic Script (العربية)** → AI responds in Arabic
|
| 245 |
+
- **Arabizi (3arabi bi 7oruf latin)** → AI-powered conversion → Arabizi response
|
| 246 |
- **English** → AI responds in English
|
| 247 |
|
| 248 |
+
**⚡ NEW: Professional Arabizi Conversion**
|
| 249 |
+
- Uses specialized AI model trained on Moroccan Darija
|
| 250 |
+
- Perfect understanding of context: "kayn chi" → "كاين شي"
|
| 251 |
+
- Handles complex phrases accurately
|
| 252 |
|
| 253 |
**جرب هذه الأسئلة / Try these questions:**
|
| 254 |
""",
|
|
|
|
| 260 |
"شنو كيتسمى المنتخب المغربي؟",
|
| 261 |
"chno kaytsma lmontakhab lmaghribi?",
|
| 262 |
"What is Morocco famous for?",
|
|
|
|
| 263 |
"كيفاش نقدر نتعلم الدارجة؟",
|
| 264 |
"kifash n9der nt3elem darija?",
|
| 265 |
"wach kayn atay f lmaghrib?",
|
| 266 |
"3lach lmaghrib zwien bzzaf?",
|
| 267 |
"kifash nsali tajine?",
|
| 268 |
+
"chno homa l2aklat lmaghribiya?",
|
| 269 |
+
"kayn chi restaurants zwinin f casa?",
|
| 270 |
+
"mr7ba! kif dayr?"
|
| 271 |
],
|
| 272 |
cache_examples=False
|
| 273 |
)
|