Spaces:
Running on Zero
Running on Zero
File size: 5,393 Bytes
3d9ba5b ca8888d b4255e9 3d9ba5b ca8888d 3d9ba5b b4255e9 ca8888d b4255e9 3d9ba5b ca8888d 3d9ba5b ca8888d 3d9ba5b b4255e9 3d9ba5b b4255e9 3d9ba5b ca8888d 3d9ba5b b4255e9 3d9ba5b b4255e9 ca8888d b4255e9 ca8888d 79d7dca b4255e9 ca8888d b4255e9 79d7dca b4255e9 79d7dca b4255e9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | """
Bilingual Arabic-English Text Summarization Suite
Production Hugging Face Space (Gradio 5.x + API Endpoint).
"""
import os
import sys
import time
from typing import Optional
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
if PROJECT_ROOT not in sys.path:
sys.path.insert(0, PROJECT_ROOT)
# ZeroGPU decorator support
try:
import spaces
has_spaces = True
except ImportError:
has_spaces = False
def gpu_decorator(func):
if has_spaces and hasattr(spaces, "GPU"):
return spaces.GPU(func)
return func
import gradio as gr
from nlp_core.language_detector import LanguageDetector
from nlp_core.tokenizer import BilingualTokenizer
from models.extractive.textrank import TextRankSummarizer
from models.extractive.lsa import LSASummarizer
from models.extractive.hybrid_scorer import HybridSummarizer
from models.abstractive.seq2seq_model import Seq2SeqSummarizer
from evaluation.metrics_manager import MetricsManager
lang_detector = LanguageDetector()
tokenizer = BilingualTokenizer()
metrics_mgr = MetricsManager()
CKPT_AR = os.path.join(PROJECT_ROOT, "checkpoints", "seq2seq_arabic.pt")
CKPT_EN = os.path.join(PROJECT_ROOT, "checkpoints", "seq2seq_english.pt")
seq_ar = Seq2SeqSummarizer.load_checkpoint(CKPT_AR, device="cpu") if os.path.exists(CKPT_AR) else None
seq_en = Seq2SeqSummarizer.load_checkpoint(CKPT_EN, device="cpu") if os.path.exists(CKPT_EN) else None
@gpu_decorator
def summarize_text(text, algorithm="Seq2Seq with Bahdanau Attention (Abstractive 20-Ep)", sentences=3, beam_width=3):
"""Core summarization engine exposed to both Gradio UI and REST API."""
if not text or not str(text).strip():
return "Please enter text to summarize.", "N/A", "0%", "0 ms"
text = str(text).strip()
t0 = time.time()
detected_lang = lang_detector.detect_language(text)
if "lsa" in str(algorithm).lower():
res = LSASummarizer().summarize(text, num_sentences=int(sentences), lang=detected_lang)
summary = res["summary"]
elif "hybrid" in str(algorithm).lower():
res = HybridSummarizer().summarize(text, num_sentences=int(sentences), lang=detected_lang)
summary = res["summary"]
elif "textrank" in str(algorithm).lower():
res = TextRankSummarizer().summarize(text, num_sentences=int(sentences), lang=detected_lang)
summary = res["summary"]
else: # Seq2Seq Abstractive
model = seq_ar if detected_lang == "ar" else seq_en
if model:
toks = tokenizer.tokenize_words(text, lang=detected_lang)
gen_toks = model.summarize_beam(toks, beam_width=int(beam_width), max_len=60)
summary = " ".join(gen_toks)
else:
res = HybridSummarizer().summarize(text, num_sentences=int(sentences), lang=detected_lang)
summary = res["summary"] + " (Used Hybrid fallback)"
latency = f"{(time.time() - t0)*1000.0:.1f} ms"
orig_w = len(text.split())
sum_w = len(summary.split())
reduction = f"{(1 - (sum_w/orig_w))*100:.1f}%" if orig_w > 0 else "0%"
return summary, detected_lang.upper(), reduction, latency
# Build Gradio UI with named API endpoints
with gr.Blocks(title="Bilingual Arabic-English Text Summarization AI", theme=gr.themes.Soft()) as demo:
gr.Markdown("# 📖 Bilingual Arabic-English Text Summarization AI System")
gr.Markdown("""
**Production NLP Platform** supporting Extractive (TextRank, LSA, Hybrid) and Abstractive (Seq2Seq + Bahdanau Attention) summarization.
""")
with gr.Row():
with gr.Column():
input_text = gr.Textbox(
label="Source Document Text | النص الأصلي",
placeholder="Paste Arabic or English article text here...",
lines=10
)
algorithm = gr.Dropdown(
label="Summarization Algorithm | خوارزمية التلخيص",
choices=[
"Seq2Seq with Bahdanau Attention (Abstractive 20-Ep)",
"Hybrid Scorer (Extractive)",
"TextRank (Extractive)",
"LSA (Extractive)"
],
value="Seq2Seq with Bahdanau Attention (Abstractive 20-Ep)"
)
with gr.Row():
sentences = gr.Slider(minimum=1, maximum=10, value=3, step=1, label="Sentences (Extractive)")
beam_width = gr.Slider(minimum=1, maximum=6, value=3, step=1, label="Beam Width (Seq2Seq)")
btn = gr.Button("✨ Generate Summary | توليد الملخص", variant="primary")
with gr.Column():
output_summary = gr.Textbox(label="Generated Summary | الملخص الناتج", lines=8)
with gr.Row():
out_lang = gr.Textbox(label="Detected Language", lines=1)
out_reduc = gr.Textbox(label="Word Reduction", lines=1)
out_lat = gr.Textbox(label="Latency (ms)", lines=1)
btn.click(
fn=summarize_text,
inputs=[input_text, algorithm, sentences, beam_width],
outputs=[output_summary, out_lang, out_reduc, out_lat],
api_name="summarize"
)
# Launch Gradio app directly (required for Hugging Face Space supervisor)
demo.queue()
demo.launch(server_name="0.0.0.0", server_port=7860, ssr_mode=False)
|