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 |
)
|