Ronak0 commited on
Commit
bb43cbc
·
verified ·
1 Parent(s): 617882f

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +97 -0
app.py ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import fitz # PyMuPDF
2
+ import gradio as gr
3
+ import torch
4
+ from transformers import AutoConfig, AutoTokenizer, T5ForConditionalGeneration
5
+
6
+ MODEL_REPO = "CaseLoop/pdf"
7
+ FALLBACK_BASE = "google/flan-t5-base"
8
+
9
+ # Load Tokenizer
10
+ try:
11
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_REPO, legacy=False)
12
+ except Exception:
13
+ tokenizer = AutoTokenizer.from_pretrained(FALLBACK_BASE, legacy=False)
14
+
15
+ # Load Model
16
+ try:
17
+ model = T5ForConditionalGeneration.from_pretrained(MODEL_REPO)
18
+ except Exception:
19
+ try:
20
+ config = AutoConfig.from_pretrained(FALLBACK_BASE)
21
+ model = T5ForConditionalGeneration.from_pretrained(
22
+ MODEL_REPO, config=config
23
+ )
24
+ except Exception:
25
+ model = T5ForConditionalGeneration.from_pretrained(FALLBACK_BASE)
26
+
27
+ model.eval()
28
+
29
+
30
+ def extract_chunks(pdf_path: str, chunk_size: int = 180, max_chunks: int = 6):
31
+ doc = fitz.open(pdf_path)
32
+ lines = []
33
+ for page in doc:
34
+ text = page.get_text("text")
35
+ lines.extend([
36
+ line.strip()
37
+ for line in text.split("\n")
38
+ if len(line.strip().split()) >= 5
39
+ ])
40
+
41
+ words = " ".join(lines).split()
42
+ if not words:
43
+ return []
44
+ return [
45
+ " ".join(words[i : i + chunk_size])
46
+ for i in range(0, len(words), chunk_size)
47
+ ][:max_chunks]
48
+
49
+
50
+ def simplify_document(pdf_file):
51
+ if pdf_file is None:
52
+ return "Please upload a valid PDF file."
53
+
54
+ chunks = extract_chunks(pdf_file.name)
55
+ if not chunks:
56
+ return (
57
+ "No readable text found in document. It may contain scanned image pages."
58
+ )
59
+
60
+ takeaways = []
61
+ for idx, chunk in enumerate(chunks, 1):
62
+ prompt = f"simplify bureaucratic text into simple language: {chunk}"
63
+ inputs = tokenizer(
64
+ prompt, return_tensors="pt", max_length=512, truncation=True
65
+ )
66
+ with torch.no_grad():
67
+ output_tokens = model.generate(
68
+ **inputs,
69
+ max_length=120,
70
+ min_length=20,
71
+ num_beams=4,
72
+ no_repeat_ngram_size=3,
73
+ repetition_penalty=2.5,
74
+ early_stopping=True,
75
+ )
76
+ summary = tokenizer.decode(output_tokens[0], skip_special_tokens=True)
77
+ takeaways.append(f"{idx}. {summary}")
78
+
79
+ return "\n\n".join(takeaways)
80
+
81
+
82
+ demo = gr.Interface(
83
+ fn=simplify_document,
84
+ inputs=gr.File(label="Upload Civic / RTI PDF", file_types=[".pdf"]),
85
+ outputs=gr.Textbox(
86
+ label="Plain-Language Takeaways", lines=10, interactive=False
87
+ ),
88
+ title="📄 Civic & RTI PDF Simplifier",
89
+ description=(
90
+ "Upload complex bureaucratic documents to extract simplified summaries"
91
+ " using fine-tuned FLAN-T5."
92
+ ),
93
+ flagging_mode="never",
94
+ )
95
+
96
+ if __name__ == "__main__":
97
+ demo.launch()