Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import faiss | |
| import numpy as np | |
| from transformers import AutoTokenizer, AutoModel | |
| from sentence_transformers import SentenceTransformer | |
| from langchain.text_splitter import RecursiveCharacterTextSplitter | |
| from pdfminer.high_level import extract_text | |
| import docx | |
| # Initialize global variables | |
| embedding_model = SentenceTransformer('CAMeL-Lab/bert-base-arabic-camelbert-mix') | |
| index = None | |
| texts = [] | |
| def extract_text_from_pdf(file_path): | |
| try: | |
| return extract_text(file_path) | |
| except Exception as e: | |
| print(f"Error extracting from PDF: {e}") | |
| return "" | |
| def extract_text_from_docx(file_path): | |
| try: | |
| doc = docx.Document(file_path) | |
| return "\n".join([para.text for para in doc.paragraphs]) | |
| except Exception as e: | |
| print(f"Error extracting from DOCX: {e}") | |
| return "" | |
| def process_files(files, progress=gr.Progress()): | |
| global index, texts | |
| if not files or len(files) == 0: | |
| return "⚠️ لم يتم رفع أي ملفات. الرجاء رفع كتاب واحد على الأقل." | |
| texts = [] | |
| try: | |
| # Step 1: Extract text | |
| progress(0.1, desc="جاري استخراج النصوص من الكتب...") | |
| for file_path in files: | |
| if isinstance(file_path, str): | |
| if file_path.endswith(".pdf"): | |
| text = extract_text_from_pdf(file_path) | |
| elif file_path.endswith(".docx") or file_path.endswith(".doc"): | |
| text = extract_text_from_docx(file_path) | |
| else: | |
| continue | |
| if text: | |
| texts.append(text) | |
| if len(texts) == 0: | |
| return "⚠️ لم يتم استخراج نصوص صالحة من الملفات." | |
| # Step 2: Chunk the text | |
| progress(0.4, desc="تقطيع النصوص إلى فقرات...") | |
| splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50) | |
| chunks = [] | |
| for text in texts: | |
| chunks.extend(splitter.split_text(text)) | |
| if len(chunks) == 0: | |
| return "⚠️ لا يوجد محتوى نصي كافٍ للتدريب." | |
| # Step 3: Embed the text | |
| progress(0.7, desc="تحويل الفقرات إلى متجهات...") | |
| embeddings = embedding_model.encode(chunks, show_progress_bar=True) | |
| # Step 4: Build FAISS index | |
| progress(0.9, desc="بناء قاعدة بيانات البحث...") | |
| embeddings = np.array(embeddings).astype(np.float32) | |
| index = faiss.IndexFlatL2(embeddings.shape[1]) | |
| index.add(embeddings) | |
| texts.clear() | |
| texts.extend(chunks) | |
| return "✅ النظام جاهز للإجابة على أسئلتك" | |
| except Exception as e: | |
| return f"❌ حدث خطأ أثناء التدريب: {str(e)}" | |
| def answer_question(question): | |
| global index, texts | |
| if index is None or len(texts) == 0: | |
| return "⚠️ الرجاء رفع كتبك وتدريب النظام أولاً." | |
| try: | |
| question_embedding = embedding_model.encode([question]) | |
| question_embedding = np.array(question_embedding).astype(np.float32) | |
| D, I = index.search(question_embedding, k=1) | |
| if I[0][0] == -1: | |
| return "❌ لم يتم العثور على إجابة." | |
| retrieved_chunk = texts[I[0][0]] | |
| return retrieved_chunk | |
| except Exception as e: | |
| return f"❌ حدث خطأ أثناء الإجابة: {str(e)}" | |
| with gr.Blocks() as demo: | |
| gr.Markdown("# 📚 نظام محاكاة دماغ المؤلف العربي\nارفع كتبك ودرب النظام للإجابة على أسئلتك باللغة العربية فقط.") | |
| with gr.Row(): | |
| file_input = gr.File(label="📄 ارفع ملفات الكتب (PDF أو DOCX)", file_types=['.pdf', '.docx', '.doc'], file_count="multiple") | |
| with gr.Row(): | |
| train_button = gr.Button("🚀 ابدأ التدريب على الكتب") | |
| output_text = gr.Textbox(label="🔵 حالة التدريب") | |
| with gr.Row(): | |
| question_input = gr.Textbox(label="✍️ اكتب سؤالك هنا") | |
| answer_output = gr.Textbox(label="🧠 إجابة النظام") | |
| train_button.click(fn=process_files, inputs=[file_input], outputs=[output_text]) | |
| question_input.submit(fn=answer_question, inputs=[question_input], outputs=[answer_output]) | |
| demo.launch() | |