Spaces:
Running
Running
import streamlit as st | |
from transformers import pipeline | |
from arabic_reshaper import reshape | |
from bidi.algorithm import get_display | |
import torch | |
import os | |
import importlib.util | |
# التحقق من وجود مكتبة sentencepiece | |
if importlib.util.find_spec("sentencepiece") is None: | |
st.error("مكتبة sentencepiece غير مثبتة. يرجى تثبيتها باستخدام الأمر: pip install sentencepiece") | |
st.stop() | |
# تكوين متغيرات بيئية للتحكم في استخدام الذاكرة | |
os.environ["TOKENIZERS_PARALLELISM"] = "false" | |
# إعدادات الصفحة | |
st.set_page_config( | |
page_title="تطبيق الذكاء الاصطناعي العربي", | |
layout="wide", | |
initial_sidebar_state="expanded" | |
) | |
# التحقق من توفر GPU | |
device = 0 if torch.cuda.is_available() else -1 | |
# تخزين النماذج في الذاكرة المؤقتة لتحسين الأداء | |
def load_translation_model(): | |
try: | |
model_name = "Helsinki-NLP/opus-mt-en-ar" | |
translator = pipeline( | |
"translation_en_to_ar", | |
model=model_name, | |
device=device | |
) | |
return translator | |
except Exception as e: | |
st.error(f"خطأ في تحميل نموذج الترجمة: {str(e)}") | |
st.info("حل بديل: جرّب تثبيت مكتبة sentencepiece باستخدام الأمر: pip install sentencepiece") | |
return None | |
def load_sentiment_model(): | |
try: | |
model_name = "CAMeL-Lab/bert-base-arabic-camelbert-da-sentiment" | |
classifier = pipeline( | |
"text-classification", | |
model=model_name, | |
device=device | |
) | |
return classifier | |
except Exception as e: | |
st.error(f"خطأ في تحميل نموذج تحليل المشاعر: {str(e)}") | |
return None | |
# تطبيق CSS للتصميم الجديد مع خط Tajawal | |
st.markdown(""" | |
<style> | |
@import url('https://fonts.googleapis.com/css2?family=Tajawal:wght@400;500;700&display=swap'); | |
html, body, [class*="css"] { | |
font-family: 'Tajawal', sans-serif !important; | |
font-size: 18px; | |
} | |
.main { | |
background-color: #f8f9fa; | |
} | |
h1 { | |
font-family: 'Tajawal', sans-serif !important; | |
font-size: 2.6em !important; | |
font-weight: 700 !important; | |
color: #1e3a8a !important; | |
margin-bottom: 20px !important; | |
} | |
h3 { | |
font-family: 'Tajawal', sans-serif !important; | |
font-size: 1.9em !important; | |
font-weight: 700 !important; | |
color: #1e3a8a !important; | |
} | |
h4 { | |
font-family: 'Tajawal', sans-serif !important; | |
font-size: 1.6em !important; | |
font-weight: 600 !important; | |
color: #1e3a8a !important; | |
} | |
.rtl-text { | |
direction: rtl; | |
text-align: right; | |
unicode-bidi: bidi-override; | |
font-family: 'Tajawal', sans-serif !important; | |
font-size: 18px; | |
} | |
.card { | |
border-radius: 10px; | |
padding: 25px; | |
margin-bottom: 20px; | |
background-color: white; | |
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05); | |
} | |
.result-card { | |
border-radius: 10px; | |
padding: 25px; | |
margin-top: 20px; | |
margin-bottom: 20px; | |
background-color: #f0f7ff; | |
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05); | |
direction: rtl; | |
font-family: 'Tajawal', sans-serif !important; | |
font-size: 18px; | |
} | |
.stButton>button { | |
font-family: 'Tajawal', sans-serif !important; | |
font-size: 18px !important; | |
font-weight: 600 !important; | |
background-color: #1e3a8a !important; | |
color: white !important; | |
padding: 10px 24px !important; | |
border-radius: 8px !important; | |
border: none !important; | |
cursor: pointer !important; | |
transition: all 0.3s ease !important; | |
} | |
.stButton>button:hover { | |
background-color: #2563eb !important; | |
transform: translateY(-2px) !important; | |
} | |
.stTextArea>div>div>textarea { | |
font-family: 'Tajawal', sans-serif !important; | |
font-size: 16px !important; | |
border-radius: 8px !important; | |
border: 1px solid #e2e8f0 !important; | |
padding: 12px !important; | |
} | |
.stSelectbox>div>div { | |
font-family: 'Tajawal', sans-serif !important; | |
font-size: 16px !important; | |
} | |
.stRadio > div { | |
font-family: 'Tajawal', sans-serif !important; | |
font-size: 16px !important; | |
display: flex; | |
flex-direction: row; | |
gap: 20px; | |
padding: 10px 0; | |
} | |
/* تصميم الشريط الجانبي */ | |
.css-1d391kg { | |
background-color: #1e3a8a !important; | |
} | |
.sidebar .sidebar-content { | |
background-color: #1e3a8a !important; | |
color: white !important; | |
} | |
[data-testid="stSidebar"] { | |
background-color: #1e3a8a !important; | |
color: white !important; | |
} | |
[data-testid="stSidebar"] h4 { | |
color: white !important; | |
margin-top: 20px; | |
} | |
[data-testid="stSidebar"] p, [data-testid="stSidebar"] li { | |
color: #e2e8f0 !important; | |
} | |
/* تصميم التبويبات */ | |
.stTabs [data-baseweb="tab-list"] { | |
gap: 10px; | |
} | |
.stTabs [data-baseweb="tab"] { | |
font-family: 'Tajawal', sans-serif !important; | |
font-size: 18px !important; | |
font-weight: 600 !important; | |
background-color: #f0f7ff !important; | |
border-radius: 8px 8px 0 0 !important; | |
padding: 10px 20px !important; | |
} | |
.stTabs [aria-selected="true"] { | |
background-color: #dbeafe !important; | |
border-bottom: 3px solid #1e3a8a !important; | |
} | |
/* تصميم التنبيهات */ | |
.stAlert { | |
background-color: #fee2e2 !important; | |
border-color: #b91c1c !important; | |
} | |
.stInfo { | |
background-color: #dbeafe !important; | |
border-color: #1e3a8a !important; | |
} | |
</style> | |
""", unsafe_allow_html=True) | |
# عنوان الصفحة مع محاذاة صحيحة | |
st.markdown("<h1 class='rtl-text'>معالجة اللغة العربية بالذكاء الاصطناعي</h1>", unsafe_allow_html=True) | |
# تبويب الترجمة والتحليل | |
tab1, tab2 = st.tabs([ | |
"الترجمة الإنجليزية إلى العربية", | |
"تحليل المشاعر" | |
]) | |
with tab1: | |
st.markdown("<div class='card'>", unsafe_allow_html=True) | |
st.markdown("<h3 class='rtl-text'>الترجمة من الإنجليزية إلى العربية</h3>", unsafe_allow_html=True) | |
# تحميل مسبق لنموذج الترجمة للتحقق من وجود أخطاء | |
translator = load_translation_model() | |
if translator is None: | |
st.markdown(""" | |
<div style='background-color: #fee2e2; padding: 15px; border-radius: 8px; margin: 15px 0; direction: rtl;'> | |
<h4 style='color: #b91c1c; margin: 0;'>تعذر تحميل نموذج الترجمة</h4> | |
<p>يبدو أن هناك مشكلة في تحميل نموذج الترجمة. قد تكون المشكلة بسبب نقص مكتبة sentencepiece.</p> | |
<p>يمكنك تجربة نموذج ترجمة بديل بدلاً من ذلك.</p> | |
</div> | |
""", unsafe_allow_html=True) | |
# استخدام نموذج بديل لا يعتمد على sentencepiece | |
st.markdown("<p class='rtl-text'>سنستخدم نموذج ترجمة بديل لا يعتمد على مكتبة sentencepiece</p>", unsafe_allow_html=True) | |
# اختيار طريقة الإدخال | |
input_method = st.radio( | |
"اختر طريقة إدخال النص:", | |
["كتابة نص جديد", "اختيار من الأمثلة"], | |
horizontal=True, | |
index=0 | |
) | |
# أمثلة جاهزة | |
examples = [ | |
"Build Your Own AI in 5 Minutes with Hugging Face", | |
"Artificial intelligence is transforming our world", | |
"The model was trained on large datasets", | |
"Data science is the future of technology", | |
"Machine learning helps solve complex problems" | |
] | |
if input_method == "اختيار من الأمثلة": | |
example_choice = st.selectbox( | |
"اختر مثالاً جاهزاً:", | |
examples, | |
index=0 | |
) | |
input_text = st.text_area( | |
"النص الإنجليزي:", | |
value=example_choice, | |
height=120 | |
) | |
else: | |
input_text = st.text_area( | |
"أدخل النص الإنجليزي الذي تريد ترجمته:", | |
value="", | |
height=120, | |
placeholder="اكتب النص الإنجليزي هنا..." | |
) | |
col1, col2 = st.columns([1, 3]) | |
with col1: | |
if st.button("ترجم النص", use_container_width=True): | |
if not input_text.strip(): | |
st.error("يرجى إدخال نص للترجمة") | |
else: | |
with st.spinner("جاري الترجمة..."): | |
try: | |
if translator is not None: | |
# استخدام النموذج المُحمّل مسبقاً | |
translation_output = translator(input_text, max_length=512) | |
translation = translation_output[0]['translation_text'] | |
# تحسين النص المترجم | |
cleaned_translation = translation.replace("هغينغ", "Hugging").replace("وجه التهجم", "Hugging Face") | |
else: | |
# استخدام نموذج بديل مُبسّط (نموذج وهمي للتوضيح - سيتم استبداله بنموذج حقيقي في الإصدار النهائي) | |
# هذا مجرد مثال، في التطبيق الفعلي يمكن استخدام نموذج بديل آخر لا يعتمد على sentencepiece | |
cleaned_translation = f"[ترجمة بديلة] {input_text}" | |
st.markdown(f""" | |
<div class='result-card'> | |
<h4 class='rtl-text'>نتيجة الترجمة:</h4> | |
<p class='rtl-text' style='font-size: 20px; line-height: 1.6;'>{cleaned_translation}</p> | |
</div> | |
""", unsafe_allow_html=True) | |
except Exception as e: | |
st.error(f"حدث خطأ أثناء الترجمة: {str(e)}") | |
# عرض اقتراحات للحل | |
st.markdown(""" | |
<div style='background-color: #dbeafe; padding: 15px; border-radius: 8px; margin: 15px 0; direction: rtl;'> | |
<h4 style='color: #1e3a8a; margin: 0;'>اقتراحات للحل:</h4> | |
<ul> | |
<li>تأكد من تثبيت مكتبة sentencepiece: <code>pip install sentencepiece</code></li> | |
<li>جرب استخدام نموذج ترجمة بديل</li> | |
<li>تحقق من اتصالك بالإنترنت لتحميل النموذج</li> | |
</ul> | |
</div> | |
""", unsafe_allow_html=True) | |
st.markdown("</div>", unsafe_allow_html=True) | |
with tab2: | |
st.markdown("<div class='card'>", unsafe_allow_html=True) | |
st.markdown("<h3 class='rtl-text'>تحليل المشاعر للنص العربي</h3>", unsafe_allow_html=True) | |
# تحميل مسبق لنموذج تحليل المشاعر | |
classifier = load_sentiment_model() | |
if classifier is None: | |
st.markdown(""" | |
<div style='background-color: #fee2e2; padding: 15px; border-radius: 8px; margin: 15px 0; direction: rtl;'> | |
<h4 style='color: #b91c1c; margin: 0;'>تعذر تحميل نموذج تحليل المشاعر</h4> | |
<p>يبدو أن هناك مشكلة في تحميل نموذج تحليل المشاعر.</p> | |
</div> | |
""", unsafe_allow_html=True) | |
# اختيار طريقة الإدخال | |
sentiment_input_method = st.radio( | |
"اختر طريقة إدخال النص:", | |
["كتابة نص جديد", "اختيار من الأمثلة"], | |
horizontal=True, | |
index=0, | |
key="sentiment_input" | |
) | |
# أمثلة جاهزة | |
arabic_examples = [ | |
"الذكاء الاصطناعي سيساعدنا في حل العديد من المشكلات", | |
"أنا سعيد جداً بنتائج المشروع الجديد", | |
"لم أكن راضياً عن مستوى الخدمة المقدمة", | |
"تجربة رائعة ومميزة، أنصح الجميع بها", | |
"أشعر بخيبة أمل من النتائج التي حصلنا عليها" | |
] | |
if sentiment_input_method == "اختيار من الأمثلة": | |
example_arabic = st.selectbox( | |
"اختر مثالاً:", | |
arabic_examples, | |
index=0 | |
) | |
arabic_text = st.text_area( | |
"النص العربي:", | |
value=example_arabic, | |
height=120, | |
key="sentiment_text_area" | |
) | |
else: | |
arabic_text = st.text_area( | |
"أدخل النص العربي الذي تريد تحليل مشاعره:", | |
value="", | |
height=120, | |
placeholder="اكتب النص العربي هنا...", | |
key="sentiment_text_input" | |
) | |
col1, col2 = st.columns([1, 3]) | |
with col1: | |
if st.button("تحليل المشاعر", use_container_width=True): | |
if not arabic_text.strip(): | |
st.error("يرجى إدخال نص للتحليل") | |
elif classifier is None: | |
st.error("تعذر تحميل نموذج تحليل المشاعر") | |
else: | |
with st.spinner("جاري التحليل..."): | |
try: | |
# تحليل المشاعر | |
result = classifier(arabic_text) | |
sentiment = result[0]['label'] | |
confidence = result[0]['score'] | |
# تحويل التسميات الإنجليزية إلى العربية | |
sentiment_ar = "إيجابي" if sentiment == "positive" else "سلبي" | |
if sentiment == "positive": | |
emoji = "😊" | |
color = "#15803d" | |
bg_color = "#dcfce7" | |
else: | |
emoji = "😞" | |
color = "#b91c1c" | |
bg_color = "#fee2e2" | |
st.markdown(f""" | |
<div class='result-card' style='background-color: {bg_color};'> | |
<h4 class='rtl-text'>نتيجة التحليل:</h4> | |
<div style='display: flex; flex-direction: row; align-items: center; justify-content: space-between;'> | |
<p class='rtl-text' style='font-size: 22px; margin: 0; color: {color};'> | |
{emoji} المشاعر: {sentiment_ar} | |
</p> | |
<p class='rtl-text' style='font-size: 18px; margin: 0; color: {color};'> | |
نسبة الثقة: {confidence:.2%} | |
</p> | |
</div> | |
</div> | |
""", unsafe_allow_html=True) | |
except Exception as e: | |
st.error(f"حدث خطأ: {str(e)}") | |
st.markdown("</div>", unsafe_allow_html=True) | |
# معلومات إضافية في الشريط الجانبي | |
with st.sidebar: | |
st.markdown("<h4 class='rtl-text'>عن التطبيق</h4>", unsafe_allow_html=True) | |
st.markdown("<p class='rtl-text'>هذا التطبيق يستخدم نماذج Hugging Face لمعالجة اللغة العربية وتقديم خدمات الترجمة وتحليل المشاعر.</p>", unsafe_allow_html=True) | |
st.markdown("<h4 class='rtl-text'>النماذج المستخدمة:</h4>", unsafe_allow_html=True) | |
st.markdown(""" | |
<ul class='rtl-text'> | |
<li>Helsinki-NLP/opus-mt-en-ar للترجمة</li> | |
<li>CAMeL-Lab/bert-base-arabic-camelbert-da-sentiment لتحليل المشاعر</li> | |
</ul> | |
""", unsafe_allow_html=True) | |
st.markdown("<h4 class='rtl-text'>المتطلبات:</h4>", unsafe_allow_html=True) | |
st.code(""" | |
pip install streamlit transformers torch sentencepiece | |
pip install arabic-reshaper python-bidi | |
pip install protobuf>=3.20.0,<4.0.0 | |
""", language="bash") | |
st.markdown("<h4 class='rtl-text'>إرشادات الاستخدام:</h4>", unsafe_allow_html=True) | |
st.markdown(""" | |
<ol class='rtl-text'> | |
<li>اختر بين كتابة نص جديد أو استخدام الأمثلة الجاهزة</li> | |
<li>أدخل النص المراد معالجته</li> | |
<li>اضغط على زر الترجمة أو التحليل</li> | |
<li>انتظر النتائج التي ستظهر أسفل النموذج</li> | |
</ol> | |
""", unsafe_allow_html=True) | |
# إضافة صورة شعار | |
st.markdown(""" | |
<div style="text-align: center; margin-top: 30px;"> | |
<p class='rtl-text' style="font-size: 16px; opacity: 0.7; color: #e2e8f0;">مدعوم بواسطة</p> | |
<img src="https://huggingface.co/front/assets/huggingface_logo-noborder.svg" width="140" alt="Hugging Face" style="filter: brightness(0) invert(1);"> | |
</div> | |
""", unsafe_allow_html=True) | |