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