Spaces:
Runtime error
Runtime error
import gradio as gr | |
from transformers import AutoTokenizer, AutoModelForMaskedLM, pipeline | |
import random | |
# تحميل نموذج صغير للغة العربية | |
print("جاري تحميل النموذج الخفيف...") | |
MODEL_NAME = "asafaya/bert-mini-arabic" # نموذج عربي أصغر بكثير | |
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME) | |
model = AutoModelForMaskedLM.from_pretrained(MODEL_NAME) | |
# إنشاء توليد النصوص | |
nlp = pipeline("fill-mask", model=model, tokenizer=tokenizer) | |
print("تم تحميل النموذج بنجاح!") | |
# عبارات افتتاحية مختلفة حسب المشاعر | |
emotion_starters = { | |
"سعيد": [ | |
"أشعر بسعادة كبيرة لأن", | |
"أنا سعيد جداً بـ", | |
"الفرح يملأ قلبي عندما", | |
"مما يسعدني حقاً هو" | |
], | |
"حزين": [ | |
"أشعر بالحزن بسبب", | |
"ما يؤلمني هو", | |
"يعتصر قلبي حزناً عندما", | |
"الحزن يسكنني لأن" | |
], | |
"غاضب": [ | |
"أشعر بالغضب من", | |
"ما يثير غضبي هو", | |
"لا أستطيع تحمل", | |
"يزعجني كثيراً أن" | |
], | |
# يمكن إضافة المزيد للمشاعر الأخرى | |
} | |
# إضافة عبارات افتتاحية للمشاعر الأخرى | |
for emotion in ["متحمس", "خائف", "متفائل", "متشائم", "مندهش", "مشتاق", "ممتن", "فخور", "مرتبك", "محبط", "هادئ"]: | |
if emotion not in emotion_starters: | |
emotion_starters[emotion] = [f"أشعر بأنني {emotion} لأن", f"عندما أكون {emotion} فإنني", f"ما يجعلني {emotion} هو"] | |
# القائمة المنسدلة للمشاعر | |
emotions = list(emotion_starters.keys()) | |
def generate_text(emotion, length_choice): | |
# تحويل اختيار الطول إلى عدد جمل | |
length_options = {"قصير": 3, "متوسط": 5, "طويل": 8} | |
num_sentences = length_options.get(length_choice, 5) | |
# اختيار عبارة افتتاحية عشوائية | |
starter = random.choice(emotion_starters[emotion]) | |
text = starter | |
# استخدام التنبؤ بالكلمات المُخفاة لإنشاء جمل | |
for _ in range(num_sentences): | |
try: | |
# استخدام النموذج لتنبؤ كلمة جديدة | |
if len(text) > 5: # التأكد من وجود نص كافٍ | |
mask_input = text + " " + tokenizer.mask_token | |
result = nlp(mask_input) | |
predicted_word = result[0]['token_str'] if result else "والحياة" | |
# الاستمرار في بناء النص | |
text += " " + predicted_word | |
# إضافة علامات ترقيم عشوائية | |
if random.random() > 0.7: | |
text += random.choice([".", "،", "؛", "!"]) | |
except Exception as e: | |
# إذا حدث خطأ، استمرار بكلمات بسيطة | |
text += " " + random.choice(["الحياة", "الأمل", "المستقبل", "الذكريات", "التجارب"]) | |
# تنظيف النص وإضافة علامة ترقيم في النهاية | |
if not any(text.endswith(x) for x in [".", "!", "؟"]): | |
text += "." | |
return text | |
# نفس CSS السابق | |
css = """ | |
:root { | |
--rose-gold: #bd8c7d; | |
--rose-gold-light: #d1a193; | |
--black: #000000; | |
--dark-gray: #121212; | |
} | |
body { | |
background-color: var(--black) !important; | |
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" opacity="0.08"><text x="10" y="30" font-family="Arial" font-size="20" fill="%23bd8c7d">أ</text><text x="40" y="50" font-family="Arial" font-size="25" fill="%23bd8c7d">ب</text><text x="70" y="20" font-family="Arial" font-size="15" fill="%23bd8c7d">ت</text><text x="20" y="70" font-family="Arial" font-size="30" fill="%23bd8c7d">ث</text><text x="60" y="80" font-family="Arial" font-size="20" fill="%23bd8c7d">ج</text></svg>'); | |
} | |
.gradio-container { | |
margin: 0 auto; | |
background-color: var(--black) !important; | |
max-width: 850px !important; | |
} | |
.main { | |
background-color: var(--dark-gray) !important; | |
border: 2px solid var(--rose-gold) !important; | |
border-radius: 15px !important; | |
box-shadow: 0 0 15px rgba(189, 140, 125, 0.3) !important; | |
padding: 20px !important; | |
position: relative; | |
overflow: hidden; | |
} | |
.main::before { | |
content: ""; | |
position: absolute; | |
top: 0; | |
left: 0; | |
right: 0; | |
height: 5px; | |
background: linear-gradient(90deg, var(--black), var(--rose-gold), var(--black)); | |
} | |
h1, h2, h3, p, span, label { | |
color: var(--rose-gold) !important; | |
font-family: 'Amiri', 'Noto Sans Arabic', sans-serif !important; | |
} | |
.title { | |
text-align: center; | |
position: relative; | |
padding-bottom: 15px; | |
} | |
.title::after { | |
content: ""; | |
position: absolute; | |
bottom: -5px; | |
left: 50%; | |
transform: translateX(-50%); | |
font-size: 24px; | |
color: var(--rose-gold); | |
opacity: 0.7; | |
} | |
.prose { | |
color: var(--rose-gold-light) !important; | |
} | |
textarea, .output-text, .input-text { | |
color: var(--rose-gold) !important; | |
background-color: var(--dark-gray) !important; | |
border: 1px solid var(--rose-gold) !important; | |
border-radius: 8px !important; | |
font-family: 'Amiri', 'Noto Sans Arabic', sans-serif !important; | |
font-size: 18px !important; | |
line-height: 1.6 !important; | |
padding: 15px !important; | |
box-shadow: inset 0 0 8px rgba(189, 140, 125, 0.1) !important; | |
} | |
button { | |
background-color: var(--rose-gold) !important; | |
color: var(--black) !important; | |
border: none !important; | |
border-radius: 8px !important; | |
font-family: 'Amiri', 'Noto Sans Arabic', sans-serif !important; | |
font-weight: bold !important; | |
transition: all 0.3s ease !important; | |
padding: 10px 20px !important; | |
letter-spacing: 1px !important; | |
} | |
button:hover { | |
background-color: var(--rose-gold-light) !important; | |
box-shadow: 0 0 10px rgba(189, 140, 125, 0.6) !important; | |
transform: translateY(-2px); | |
} | |
select, .dropdown { | |
background-color: var(--dark-gray) !important; | |
color: var(--rose-gold) !important; | |
border: 1px solid var(--rose-gold) !important; | |
border-radius: 8px !important; | |
font-family: 'Amiri', 'Noto Sans Arabic', sans-serif !important; | |
} | |
.footer { | |
border-top: 1px solid var(--rose-gold) !important; | |
color: var(--rose-gold) !important; | |
margin-top: 30px; | |
padding-top: 15px; | |
text-align: center; | |
position: relative; | |
} | |
.footer::before { | |
content: "♱"; | |
position: absolute; | |
top: -15px; | |
left: 50%; | |
transform: translateX(-50%); | |
background-color: var(--dark-gray); | |
padding: 0 15px; | |
color: var(--rose-gold); | |
font-size: 18px; | |
} | |
/* زخارف إضافية */ | |
.corner-decoration { | |
position: absolute; | |
font-size: 24px; | |
color: var(--rose-gold); | |
opacity: 0.4; | |
} | |
.top-right { | |
top: 15px; | |
right: 15px; | |
} | |
.top-left { | |
top: 15px; | |
left: 15px; | |
} | |
.bottom-right { | |
bottom: 15px; | |
right: 15px; | |
} | |
.bottom-left { | |
bottom: 15px; | |
left: 15px; | |
} | |
.output-container { | |
position: relative; | |
padding: 10px; | |
border-radius: 10px; | |
border: 1px solid var(--rose-gold); | |
background-color: rgba(0, 0, 0, 0.3); | |
} | |
.output-container::before { | |
content: "۞"; | |
font-size: 24px; | |
color: var(--rose-gold); | |
display: block; | |
text-align: center; | |
margin-bottom: 10px; | |
opacity: 0.5; | |
} | |
""" | |
# إنشاء واجهة المستخدم (نفس الواجهة السابقة) | |
with gr.Blocks(css=css) as demo: | |
with gr.Column(elem_classes=["main"]): | |
gr.HTML(""" | |
<div class="corner-decoration top-right">٭</div> | |
<div class="corner-decoration top-left">٭</div> | |
<div class="corner-decoration bottom-right">٭</div> | |
<div class="corner-decoration bottom-left">٭</div> | |
<div class="title"> | |
<h1>❁ اكتبلي ❁</h1> | |
<h2>مولد النصوص العربية بالمشاعر</h2> | |
<p>أداة لتوليد نصوص عربية إبداعية بناءً على المشاعر التي تختارها</p> | |
</div> | |
""") | |
with gr.Row(): | |
with gr.Column(scale=1): | |
emotion = gr.Dropdown( | |
choices=emotions, | |
label="اختر المشاعر", | |
value="سعيد" | |
) | |
length = gr.Radio( | |
choices=["قصير", "متوسط", "طويل"], | |
label="طول النص", | |
value="متوسط" | |
) | |
generate_button = gr.Button("✨ توليد النص ✨") | |
with gr.Column(scale=2): | |
with gr.Box(elem_classes=["output-container"]): | |
output = gr.Textbox( | |
label="النص المولّد", | |
lines=12, | |
elem_classes=["output-text"] | |
) | |
gr.HTML(""" | |
<div class="footer"> | |
<p>❁ اكتبلي - إبداع بلا حدود ❁</p> | |
</div> | |
""") | |
generate_button.click( | |
fn=generate_text, | |
inputs=[emotion, length], | |
outputs=output | |
) | |
# تشغيل التطبيق | |
demo.launch() |