umerfarooq29 commited on
Commit
81c7f71
·
verified ·
1 Parent(s): 915ecb5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +123 -5
app.py CHANGED
@@ -1,7 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  def summarize_large_text(text, max_length=150, min_length=50):
2
  """Summarize long text by splitting into chunks and combining summaries."""
3
  chunks = chunk_text(text, max_words=800)
4
  summaries = []
 
5
  for chunk in chunks:
6
  inputs = tokenizer([chunk], max_length=1024, truncation=True, return_tensors='pt')
7
  summary_ids = model.generate(
@@ -28,15 +106,23 @@ def summarize_large_text(text, max_length=150, min_length=50):
28
  return final_summary
29
 
30
 
 
 
 
 
 
 
 
 
31
  def multi_document_summarize(documents):
32
- """Summarize multiple related documents using clustering + improved BART summarization."""
33
  results = {
34
  'individual_summaries': [],
35
  'cluster_summaries': [],
36
  'final_summary': None
37
  }
38
 
39
- # 1️⃣ Individual summaries (using improved function)
40
  for doc in documents:
41
  doc_summary = summarize_large_text(doc)
42
  results['individual_summaries'].append(doc_summary)
@@ -45,7 +131,7 @@ def multi_document_summarize(documents):
45
  if len(documents) > 1:
46
  n_clusters = min(3, len(documents))
47
  clusters = cluster_documents(documents, n_clusters=n_clusters)
48
-
49
  for cluster_id in np.unique(clusters):
50
  cluster_docs = [doc for doc, c in zip(documents, clusters) if c == cluster_id]
51
  combined_text = " ".join(cluster_docs)
@@ -54,16 +140,48 @@ def multi_document_summarize(documents):
54
  'doc_indices': [i for i, c in enumerate(clusters) if c == cluster_id],
55
  'summary': cluster_summary
56
  })
57
-
58
  # 3️⃣ Final overall summary
59
  all_summaries = results['individual_summaries'] + [cs['summary'] for cs in results['cluster_summaries']]
60
  results['final_summary'] = summarize_large_text(" ".join(all_summaries))
61
  else:
62
  results['final_summary'] = results['individual_summaries'][0]
63
-
64
  return results
65
 
66
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
 
68
  # --------------------------- STREAMLIT UI ---------------------------
69
 
 
1
+ # --------------------------------------------------------
2
+ # 📘 Multi-Document Summarizer (using BART + Clustering)
3
+ # --------------------------------------------------------
4
+
5
+ import numpy as np
6
+ import streamlit as st
7
+ from transformers import BartTokenizer, BartForConditionalGeneration
8
+ from sklearn.feature_extraction.text import TfidfVectorizer
9
+ from sklearn.cluster import KMeans
10
+ from nltk.tokenize import sent_tokenize
11
+ import nltk
12
+ import PyPDF2
13
+ from io import BytesIO
14
+
15
+ # ✅ Streamlit Page Configuration
16
+ st.set_page_config(page_title="Multi-Document Summarizer", layout="centered")
17
+
18
+ # --------------------------------------------------------
19
+ # 📦 Download NLTK data
20
+ # --------------------------------------------------------
21
+ @st.cache_resource
22
+ def download_nltk_data():
23
+ try:
24
+ nltk.data.find('tokenizers/punkt')
25
+ except LookupError:
26
+ nltk.download('punkt', quiet=True)
27
+ nltk.download('punkt_tab', quiet=True)
28
+
29
+ download_nltk_data()
30
+
31
+ # --------------------------------------------------------
32
+ # 🤖 Load BART Model
33
+ # --------------------------------------------------------
34
+ @st.cache_resource
35
+ def load_model():
36
+ tokenizer = BartTokenizer.from_pretrained('facebook/bart-large-cnn')
37
+ model = BartForConditionalGeneration.from_pretrained('facebook/bart-large-cnn')
38
+ return tokenizer, model
39
+
40
+ tokenizer, model = load_model()
41
+
42
+ # --------------------------------------------------------
43
+ # 🧰 Helper Functions
44
+ # --------------------------------------------------------
45
+ def extract_text_from_pdf(file) -> str:
46
+ """Extract text from uploaded PDF file."""
47
+ pdf_reader = PyPDF2.PdfReader(BytesIO(file.read()))
48
+ text = ""
49
+ for page in pdf_reader.pages:
50
+ text += page.extract_text() or ""
51
+ return text.strip()
52
+
53
+
54
+ def chunk_text(text, max_words=800):
55
+ """Split long text into smaller chunks for summarization."""
56
+ if len(text.split()) <= max_words:
57
+ return [text]
58
+
59
+ sentences = sent_tokenize(text)
60
+ chunks, current_chunk, current_word_count = [], [], 0
61
+
62
+ for sentence in sentences:
63
+ sentence_words = len(sentence.split())
64
+ if current_word_count + sentence_words <= max_words:
65
+ current_chunk.append(sentence)
66
+ current_word_count += sentence_words
67
+ else:
68
+ chunks.append(" ".join(current_chunk))
69
+ current_chunk = [sentence]
70
+ current_word_count = sentence_words
71
+
72
+ if current_chunk:
73
+ chunks.append(" ".join(current_chunk))
74
+
75
+ return chunks
76
+
77
+
78
  def summarize_large_text(text, max_length=150, min_length=50):
79
  """Summarize long text by splitting into chunks and combining summaries."""
80
  chunks = chunk_text(text, max_words=800)
81
  summaries = []
82
+
83
  for chunk in chunks:
84
  inputs = tokenizer([chunk], max_length=1024, truncation=True, return_tensors='pt')
85
  summary_ids = model.generate(
 
106
  return final_summary
107
 
108
 
109
+ def cluster_documents(documents, n_clusters=3):
110
+ """Cluster similar documents using TF-IDF + KMeans."""
111
+ vectorizer = TfidfVectorizer(stop_words='english')
112
+ X = vectorizer.fit_transform(documents)
113
+ kmeans = KMeans(n_clusters=n_clusters, random_state=42).fit(X)
114
+ return kmeans.labels_
115
+
116
+
117
  def multi_document_summarize(documents):
118
+ """Summarize multiple related documents using clustering + BART."""
119
  results = {
120
  'individual_summaries': [],
121
  'cluster_summaries': [],
122
  'final_summary': None
123
  }
124
 
125
+ # 1️⃣ Individual summaries
126
  for doc in documents:
127
  doc_summary = summarize_large_text(doc)
128
  results['individual_summaries'].append(doc_summary)
 
131
  if len(documents) > 1:
132
  n_clusters = min(3, len(documents))
133
  clusters = cluster_documents(documents, n_clusters=n_clusters)
134
+
135
  for cluster_id in np.unique(clusters):
136
  cluster_docs = [doc for doc, c in zip(documents, clusters) if c == cluster_id]
137
  combined_text = " ".join(cluster_docs)
 
140
  'doc_indices': [i for i, c in enumerate(clusters) if c == cluster_id],
141
  'summary': cluster_summary
142
  })
143
+
144
  # 3️⃣ Final overall summary
145
  all_summaries = results['individual_summaries'] + [cs['summary'] for cs in results['cluster_summaries']]
146
  results['final_summary'] = summarize_large_text(" ".join(all_summaries))
147
  else:
148
  results['final_summary'] = results['individual_summaries'][0]
149
+
150
  return results
151
 
152
 
153
+ # --------------------------------------------------------
154
+ # 🖥️ Streamlit Interface
155
+ # --------------------------------------------------------
156
+ st.title("🧠 Multi-Document Summarizer")
157
+ st.markdown("Upload one or more **PDFs or text files** to generate a smart summary using AI.")
158
+
159
+ uploaded_files = st.file_uploader("Upload your documents", type=["pdf", "txt"], accept_multiple_files=True)
160
+
161
+ if uploaded_files:
162
+ documents = []
163
+ for file in uploaded_files:
164
+ if file.name.endswith(".pdf"):
165
+ text = extract_text_from_pdf(file)
166
+ else:
167
+ text = file.read().decode("utf-8")
168
+ documents.append(text)
169
+
170
+ if st.button("Generate Summary"):
171
+ with st.spinner("Generating summary... please wait ⏳"):
172
+ results = multi_document_summarize(documents)
173
+
174
+ st.subheader("📄 Final Summary")
175
+ st.write(results['final_summary'])
176
+
177
+ st.download_button(
178
+ label="📥 Download Summary",
179
+ data=results['final_summary'],
180
+ file_name="summary.txt",
181
+ mime="text/plain"
182
+ )
183
+
184
+
185
 
186
  # --------------------------- STREAMLIT UI ---------------------------
187