Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| from transformers import pipeline | |
| import PyPDF2 | |
| import torch | |
| # ===== 1) اختر الموديل هنا ===== | |
| # موديل إنجليزي: | |
| # MODEL_NAME = "csebuetnlp/mT5_multilingual_XLSum" | |
| # موديل ملخص متعدد اللغات (يدعم العربية أفضل): | |
| MODEL_NAME = "csebuetnlp/mT5_multilingual_XLSum" | |
| # ===== 2) تجهيز الـ pipeline ===== | |
| device = 0 if torch.cuda.is_available() else -1 | |
| summarizer = pipeline( | |
| "summarization", | |
| model=MODEL_NAME, | |
| tokenizer=MODEL_NAME, | |
| device=device, | |
| ) | |
| # ===== 3) قراءة الـ PDF ===== | |
| def read_pdf(file_obj): | |
| """ | |
| يستقبل ملف PDF من Gradio (file_obj)، | |
| يرجّع النص المستخرج من كل الصفحات. | |
| """ | |
| if file_obj is None: | |
| return "" | |
| reader = PyPDF2.PdfReader(file_obj) | |
| text = "" | |
| for page in reader.pages: | |
| page_text = page.extract_text() | |
| if page_text: | |
| text += page_text + "\n" | |
| return text | |
| # ===== 4) تقسيم النص لقطع (عشان حدود الموديل) ===== | |
| def chunk_text(text, max_chars=2000): | |
| """ | |
| يقسم النص إلى قطع صغيرة بعدد حروف أقصاه max_chars | |
| عشان لا نتجاوز حدود الموديل. | |
| """ | |
| paragraphs = text.split("\n") | |
| chunks = [] | |
| current = "" | |
| for p in paragraphs: | |
| p = p.strip() | |
| if not p: | |
| continue | |
| # لو نقدر نضيف الفقرة للجزء الحالي بدون ما نتعدى الحد | |
| if len(current) + len(p) + 1 <= max_chars: | |
| current += ("\n" + p) if current else p | |
| else: | |
| # نخزن الجزء القديم ونبدأ جزء جديد | |
| if current.strip(): | |
| chunks.append(current.strip()) | |
| current = p | |
| if current.strip(): | |
| chunks.append(current.strip()) | |
| return chunks | |
| # ===== 5) دالة التلخيص الرئيسية ===== | |
| def summarize_pdf(file, max_summary_length=200): | |
| """ | |
| تستقبل ملف PDF من واجهة Gradio، | |
| تقرأ النص، تقسمه لقطع، تلخص كل جزء، | |
| ثم تلخص التلخيصات مرة ثانية (لو كانت كثيرة). | |
| """ | |
| if file is None: | |
| return "رجاءً ارفع ملف PDF أولاً." | |
| # 1) قراءة النص من الـ PDF | |
| text = read_pdf(file) | |
| if not text or len(text.strip()) < 50: | |
| return "لم أستطع قراءة نص واضح من الـ PDF. تأكد أن الملف ليس صورة ممسوحة فقط (scan)." | |
| # 2) تقسيم النص | |
| chunks = chunk_text(text, max_chars=2000) | |
| # 3) تلخيص كل جزء | |
| partial_summaries = [] | |
| for idx, ch in enumerate(chunks, start=1): | |
| # نضمن طول منطقي للتلخيص | |
| try: | |
| result = summarizer( | |
| ch, | |
| max_length=max_summary_length, | |
| min_length=int(max_summary_length / 3), | |
| do_sample=False, | |
| ) | |
| summary_text = result[0]["summary_text"] | |
| except Exception as e: | |
| summary_text = f"[خطأ في تلخيص الجزء {idx}: {e}]" | |
| partial_summaries.append(summary_text) | |
| combined = "\n\n".join(partial_summaries) | |
| # 4) لو الملف طويل جداً (أكثر من جزء واحد)، نلخص التلخيص النهائي | |
| if len(partial_summaries) > 1: | |
| try: | |
| final = summarizer( | |
| combined, | |
| max_length=max_summary_length, | |
| min_length=int(max_summary_length / 3), | |
| do_sample=False, | |
| )[0]["summary_text"] | |
| return final | |
| except Exception: | |
| # لو فشل التلخيص الثاني، نرجع دمج التلخيصات الأولية | |
| return combined | |
| else: | |
| return combined | |
| # ===== 6) واجهة Gradio ===== | |
| with gr.Blocks() as demo: | |
| gr.Markdown( | |
| """ | |
| # 📄 PDF Summarizer / ملخّص ملفات PDF | |
| ارفع ملف PDF وسيقوم النموذج بقراءة النص وتلخيصه بشكل تلقائي. | |
| يمكن تعديل طول التلخيص باستخدام الشريط أسفل. | |
| """ | |
| ) | |
| with gr.Row(): | |
| pdf_input = gr.File( | |
| label="📎 ارفع ملف PDF", | |
| file_types=[".pdf"], | |
| ) | |
| max_len = gr.Slider( | |
| minimum=50, | |
| maximum=400, | |
| step=50, | |
| value=200, | |
| label="أقصى طول للتلخيص (تقريبي)", | |
| ) | |
| output = gr.Textbox( | |
| label="ملخص الملف", | |
| lines=15, | |
| ) | |
| summarize_btn = gr.Button("✨ تلخيص PDF") | |
| summarize_btn.click( | |
| fn=summarize_pdf, | |
| inputs=[pdf_input, max_len], | |
| outputs=output, | |
| ) | |
| # مهم في Hugging Face Spaces: | |
| demo.launch() | |