abersbail commited on
Commit
0b41e68
·
verified ·
1 Parent(s): 1c8848b

Add text summarizer CPU Space

Browse files
Files changed (5) hide show
  1. README.md +7 -6
  2. app.py +44 -0
  3. requirements.txt +5 -0
  4. summary_tool/__init__.py +3 -0
  5. summary_tool/service.py +65 -0
README.md CHANGED
@@ -1,12 +1,13 @@
1
  ---
2
- title: Text Summarizer Cpu
3
- emoji: 📊
4
- colorFrom: pink
5
- colorTo: blue
6
  sdk: gradio
7
- sdk_version: 6.10.0
8
  app_file: app.py
9
  pinned: false
 
10
  ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
1
  ---
2
+ title: Text Summarizer CPU
3
+ colorFrom: blue
4
+ colorTo: green
 
5
  sdk: gradio
 
6
  app_file: app.py
7
  pinned: false
8
+ license: apache-2.0
9
  ---
10
 
11
+ # Text Summarizer CPU
12
+
13
+ Free CPU text summarizer using `google/flan-t5-small`.
app.py ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+
3
+ from summary_tool.service import SummaryService
4
+
5
+
6
+ service = SummaryService()
7
+
8
+
9
+ def summarize_text(text, style, max_words):
10
+ return service.summarize(text, style, int(max_words))
11
+
12
+
13
+ with gr.Blocks(
14
+ title="Text Summarizer CPU",
15
+ theme=gr.themes.Soft(primary_hue="blue", secondary_hue="green"),
16
+ ) as demo:
17
+ gr.Markdown(
18
+ """
19
+ # Text Summarizer CPU
20
+ Paste long text and generate a short AI summary on free CPU.
21
+ """
22
+ )
23
+
24
+ text_input = gr.Textbox(label="Input Text", lines=12, placeholder="Paste article, notes, or long text here")
25
+ style_input = gr.Dropdown(
26
+ choices=["Short", "Balanced", "Detailed", "Bullet Points"],
27
+ value="Balanced",
28
+ label="Summary Style",
29
+ )
30
+ max_words_input = gr.Slider(40, 240, value=120, step=10, label="Max Words")
31
+ run_button = gr.Button("Summarize", variant="primary")
32
+
33
+ summary_output = gr.Textbox(label="Summary", lines=8)
34
+ status_output = gr.Textbox(label="Status", lines=2)
35
+
36
+ run_button.click(
37
+ fn=summarize_text,
38
+ inputs=[text_input, style_input, max_words_input],
39
+ outputs=[summary_output, status_output],
40
+ )
41
+
42
+
43
+ if __name__ == "__main__":
44
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ gradio>=5.23.0
2
+ huggingface_hub>=0.34.0,<1.0
3
+ safetensors>=0.5.3
4
+ torch>=2.3.0
5
+ transformers>=4.49.0
summary_tool/__init__.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ from .service import SummaryService
2
+
3
+ __all__ = ["SummaryService"]
summary_tool/service.py ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ import torch
4
+
5
+
6
+ MODEL_ID = "google/flan-t5-small"
7
+
8
+
9
+ class SummaryService:
10
+ def __init__(self):
11
+ self.pipe = None
12
+ cpu_count = os.cpu_count() or 1
13
+ torch.set_num_threads(max(1, min(4, cpu_count)))
14
+
15
+ def summarize(self, text, style, max_words):
16
+ clean_text = " ".join((text or "").split())
17
+ if not clean_text:
18
+ return "", "Paste text first."
19
+
20
+ try:
21
+ prompt = self._build_prompt(clean_text, style, max_words)
22
+ summary = self._run_model(prompt)
23
+ if style == "Bullet Points":
24
+ summary = self._normalize_bullets(summary)
25
+ return summary, f"Generated summary with {MODEL_ID}."
26
+ except Exception as exc:
27
+ return "", f"Summarization failed: {type(exc).__name__}: {exc}"
28
+
29
+ def _load_pipeline(self):
30
+ if self.pipe is not None:
31
+ return
32
+
33
+ from transformers import pipeline
34
+
35
+ self.pipe = pipeline(
36
+ "text2text-generation",
37
+ model=MODEL_ID,
38
+ device=-1,
39
+ )
40
+
41
+ def _run_model(self, prompt):
42
+ self._load_pipeline()
43
+ result = self.pipe(
44
+ prompt,
45
+ max_new_tokens=220,
46
+ do_sample=False,
47
+ )
48
+ return (result[0].get("generated_text") or "").strip()
49
+
50
+ def _build_prompt(self, text, style, max_words):
51
+ if style == "Short":
52
+ instruction = f"Summarize this text in under {max_words} words using plain language."
53
+ elif style == "Detailed":
54
+ instruction = f"Write a detailed summary in under {max_words} words."
55
+ elif style == "Bullet Points":
56
+ instruction = f"Summarize this text as concise bullet points in under {max_words} words."
57
+ else:
58
+ instruction = f"Write a balanced summary in under {max_words} words."
59
+ return f"{instruction}\n\nText:\n{text}"
60
+
61
+ def _normalize_bullets(self, text):
62
+ lines = [line.strip(" -") for line in text.splitlines() if line.strip()]
63
+ if not lines:
64
+ return text
65
+ return "\n".join(f"- {line}" for line in lines[:8])