LoveJesus commited on
Commit
04252ea
·
verified ·
1 Parent(s): f40c12a

Deploy Passage Difficulty Simplifier Gradio Space

Browse files
Files changed (2) hide show
  1. app.py +361 -0
  2. requirements.txt +8 -0
app.py ADDED
@@ -0,0 +1,361 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # For God so loved the world that he gave his only begotten Son,
2
+ # that whoever believes in him should not perish but have eternal life. - John 3:16
3
+
4
+ """
5
+ app.py - HuggingFace Space for the Passage Difficulty Scorer & Simplifier.
6
+ Loads the fine-tuned Flan-T5-small from HuggingFace Hub and provides a Gradio
7
+ interface with two tabs: Simplify and Difficulty.
8
+ """
9
+
10
+ import gradio as gr
11
+ import torch
12
+ from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
13
+
14
+ # HuggingFace model ID
15
+ MODEL_ID_CHIRHO = "LoveJesus/passage-difficulty-simplifier-chirho"
16
+
17
+ MAX_INPUT_LENGTH_CHIRHO = 256
18
+ MAX_TARGET_LENGTH_CHIRHO = 256
19
+
20
+ # Global model holders
21
+ model_chirho = None
22
+ tokenizer_chirho = None
23
+ device_chirho = None
24
+
25
+
26
+ def load_model_chirho():
27
+ """Load the Flan-T5-small dual-task model from HuggingFace Hub."""
28
+ global model_chirho, tokenizer_chirho, device_chirho
29
+
30
+ # Device detection
31
+ if torch.cuda.is_available():
32
+ device_chirho = torch.device("cuda")
33
+ elif hasattr(torch.backends, "mps") and torch.backends.mps.is_available():
34
+ device_chirho = torch.device("cpu") # Use CPU for Gradio to avoid MPS issues
35
+ else:
36
+ device_chirho = torch.device("cpu")
37
+
38
+ print(f"Using device: {device_chirho}")
39
+
40
+ print("Loading model...")
41
+ tokenizer_chirho = AutoTokenizer.from_pretrained(MODEL_ID_CHIRHO)
42
+ model_chirho = AutoModelForSeq2SeqLM.from_pretrained(MODEL_ID_CHIRHO)
43
+ model_chirho.to(device_chirho)
44
+ model_chirho.eval()
45
+
46
+ param_count_chirho = sum(p_chirho.numel() for p_chirho in model_chirho.parameters())
47
+ print(f"Model loaded: {param_count_chirho:,} parameters")
48
+
49
+
50
+ def generate_chirho(input_text_chirho: str) -> str:
51
+ """Generate output from the model."""
52
+ inputs_chirho = tokenizer_chirho(
53
+ input_text_chirho,
54
+ return_tensors="pt",
55
+ max_length=MAX_INPUT_LENGTH_CHIRHO,
56
+ truncation=True,
57
+ )
58
+ inputs_chirho = {
59
+ k_chirho: v_chirho.to(device_chirho) for k_chirho, v_chirho in inputs_chirho.items()
60
+ }
61
+
62
+ with torch.no_grad():
63
+ outputs_chirho = model_chirho.generate(
64
+ **inputs_chirho,
65
+ max_length=MAX_TARGET_LENGTH_CHIRHO,
66
+ num_beams=4,
67
+ early_stopping=True,
68
+ )
69
+
70
+ result_chirho = tokenizer_chirho.decode(outputs_chirho[0], skip_special_tokens=True)
71
+ return result_chirho
72
+
73
+
74
+ # ─── Tab 1: Simplify ───
75
+
76
+ def simplify_verse_chirho(text_chirho: str) -> str:
77
+ """Simplify a Bible verse into plain language."""
78
+ if not text_chirho.strip():
79
+ return "Please enter a verse to simplify."
80
+
81
+ input_text_chirho = f"simplify: {text_chirho.strip()}"
82
+ result_chirho = generate_chirho(input_text_chirho)
83
+ return result_chirho
84
+
85
+
86
+ # ─── Tab 2: Difficulty ───
87
+
88
+ def rate_difficulty_chirho(text_chirho: str) -> tuple:
89
+ """Rate the reading difficulty of a Bible passage."""
90
+ if not text_chirho.strip():
91
+ return "Please enter a verse to analyze.", "", "", ""
92
+
93
+ input_text_chirho = f"rate difficulty: {text_chirho.strip()}"
94
+ raw_result_chirho = generate_chirho(input_text_chirho)
95
+
96
+ # Parse structured output
97
+ reading_level_chirho = "N/A"
98
+ vocab_complexity_chirho = "N/A"
99
+ archaic_forms_chirho = "N/A"
100
+ difficulty_chirho = "N/A"
101
+
102
+ import re
103
+
104
+ rl_match_chirho = re.search(r"reading_level:\s*(\d+)", raw_result_chirho)
105
+ if rl_match_chirho:
106
+ level_chirho = int(rl_match_chirho.group(1))
107
+ grade_labels_chirho = {
108
+ 1: "Grade 1 (Age 6-7)",
109
+ 2: "Grade 2 (Age 7-8)",
110
+ 3: "Grade 3 (Age 8-9)",
111
+ 4: "Grade 4 (Age 9-10)",
112
+ 5: "Grade 5 (Age 10-11)",
113
+ 6: "Grade 6 (Age 11-12)",
114
+ 7: "Grade 7 (Age 12-13)",
115
+ 8: "Grade 8 (Age 13-14)",
116
+ 9: "Grade 9 (Age 14-15)",
117
+ 10: "Grade 10 (Age 15-16)",
118
+ 11: "Grade 11 (Age 16-17)",
119
+ 12: "Grade 12+ (Age 17+)",
120
+ }
121
+ reading_level_chirho = grade_labels_chirho.get(level_chirho, f"Grade {level_chirho}")
122
+
123
+ vc_match_chirho = re.search(r"vocab_complexity:\s*(\w+)", raw_result_chirho)
124
+ if vc_match_chirho:
125
+ vc_val_chirho = vc_match_chirho.group(1)
126
+ vc_labels_chirho = {
127
+ "low": "Low - Common everyday words",
128
+ "medium": "Medium - Some specialized vocabulary",
129
+ "high": "High - Many uncommon or archaic terms",
130
+ }
131
+ vocab_complexity_chirho = vc_labels_chirho.get(vc_val_chirho, vc_val_chirho)
132
+
133
+ af_match_chirho = re.search(r"archaic_forms:\s*(\d+)", raw_result_chirho)
134
+ if af_match_chirho:
135
+ af_count_chirho = int(af_match_chirho.group(1))
136
+ if af_count_chirho == 0:
137
+ archaic_forms_chirho = "None detected"
138
+ elif af_count_chirho <= 2:
139
+ archaic_forms_chirho = f"{af_count_chirho} (few)"
140
+ else:
141
+ archaic_forms_chirho = f"{af_count_chirho} (many)"
142
+
143
+ df_match_chirho = re.search(r"difficulty:\s*(\w+)", raw_result_chirho)
144
+ if df_match_chirho:
145
+ df_val_chirho = df_match_chirho.group(1)
146
+ df_labels_chirho = {
147
+ "easy": "Easy - Accessible to most readers",
148
+ "medium": "Medium - May require some familiarity with biblical language",
149
+ "hard": "Hard - Contains archaic or complex language",
150
+ }
151
+ difficulty_chirho = df_labels_chirho.get(df_val_chirho, df_val_chirho)
152
+
153
+ return reading_level_chirho, vocab_complexity_chirho, archaic_forms_chirho, difficulty_chirho
154
+
155
+
156
+ # ─── Build Gradio Interface ───
157
+
158
+ def build_demo_chirho() -> gr.Blocks:
159
+ """Build the Gradio demo with two tabs."""
160
+ with gr.Blocks(
161
+ title="Passage Difficulty Scorer & Simplifier - loveJesus/models-chirho",
162
+ theme=gr.themes.Soft(),
163
+ ) as demo_chirho:
164
+ gr.Markdown("# Passage Difficulty Scorer & Plain-Language Simplifier")
165
+ gr.Markdown(
166
+ "*For God so loved the world that he gave his only begotten Son, "
167
+ "that whoever believes in him should not perish but have eternal life. - John 3:16*"
168
+ )
169
+ gr.Markdown(
170
+ "A fine-tuned **Flan-T5-small** model for two tasks: "
171
+ "(1) assessing Bible passage reading difficulty, and "
172
+ "(2) simplifying archaic or complex passages into plain modern English. "
173
+ "Trained on KJV, BBE, WEB, ASV, YLT, and Darby translations."
174
+ )
175
+
176
+ with gr.Tab("Simplify"):
177
+ gr.Markdown("### Simplify Bible Passages")
178
+ gr.Markdown(
179
+ "Enter a Bible verse (especially from KJV, ASV, YLT, or Darby) "
180
+ "and receive a plain-language version."
181
+ )
182
+
183
+ simplify_input_chirho = gr.Textbox(
184
+ label="Original Verse",
185
+ placeholder="Enter a Bible verse to simplify...",
186
+ lines=3,
187
+ )
188
+ simplify_btn_chirho = gr.Button("Simplify", variant="primary")
189
+ simplify_output_chirho = gr.Textbox(
190
+ label="Simplified Version",
191
+ lines=3,
192
+ interactive=False,
193
+ )
194
+
195
+ simplify_btn_chirho.click(
196
+ simplify_verse_chirho,
197
+ inputs=[simplify_input_chirho],
198
+ outputs=[simplify_output_chirho],
199
+ )
200
+
201
+ gr.Examples(
202
+ examples=[
203
+ [
204
+ "For God so loved the world, that he gave his only begotten Son, "
205
+ "that whosoever believeth in him should not perish, but have everlasting life."
206
+ ],
207
+ [
208
+ "And the LORD God formed man of the dust of the ground, and breathed "
209
+ "into his nostrils the breath of life; and man became a living soul."
210
+ ],
211
+ [
212
+ "Wherefore, as by one man sin entered into the world, and death by sin; "
213
+ "and so death passed upon all men, for that all have sinned:"
214
+ ],
215
+ [
216
+ "Blessed are the poor in spirit: for theirs is the kingdom of heaven."
217
+ ],
218
+ [
219
+ "But the fruit of the Spirit is love, joy, peace, longsuffering, "
220
+ "gentleness, goodness, faith, Meekness, temperance: against such there is no law."
221
+ ],
222
+ [
223
+ "In the beginning was the Word, and the Word was with God, "
224
+ "and the Word was God."
225
+ ],
226
+ [
227
+ "Verily, verily, I say unto thee, Except a man be born again, "
228
+ "he cannot see the kingdom of God."
229
+ ],
230
+ [
231
+ "For all have sinned, and come short of the glory of God;"
232
+ ],
233
+ ],
234
+ inputs=[simplify_input_chirho],
235
+ )
236
+
237
+ with gr.Tab("Difficulty"):
238
+ gr.Markdown("### Assess Passage Difficulty")
239
+ gr.Markdown(
240
+ "Enter a Bible verse to get its reading level, vocabulary complexity, "
241
+ "archaic form count, and overall difficulty rating."
242
+ )
243
+
244
+ difficulty_input_chirho = gr.Textbox(
245
+ label="Verse Text",
246
+ placeholder="Enter a Bible verse to assess difficulty...",
247
+ lines=3,
248
+ )
249
+ difficulty_btn_chirho = gr.Button("Assess Difficulty", variant="primary")
250
+
251
+ with gr.Row():
252
+ reading_level_output_chirho = gr.Textbox(
253
+ label="Reading Level", interactive=False
254
+ )
255
+ difficulty_output_chirho = gr.Textbox(
256
+ label="Overall Difficulty", interactive=False
257
+ )
258
+
259
+ with gr.Row():
260
+ vocab_output_chirho = gr.Textbox(
261
+ label="Vocabulary Complexity", interactive=False
262
+ )
263
+ archaic_output_chirho = gr.Textbox(
264
+ label="Archaic Forms", interactive=False
265
+ )
266
+
267
+ difficulty_btn_chirho.click(
268
+ rate_difficulty_chirho,
269
+ inputs=[difficulty_input_chirho],
270
+ outputs=[
271
+ reading_level_output_chirho,
272
+ vocab_output_chirho,
273
+ archaic_output_chirho,
274
+ difficulty_output_chirho,
275
+ ],
276
+ )
277
+
278
+ gr.Examples(
279
+ examples=[
280
+ [
281
+ "In the beginning God created the heaven and the earth."
282
+ ],
283
+ [
284
+ "For God so loved the world, that he gave his only begotten Son, "
285
+ "that whosoever believeth in him should not perish, but have everlasting life."
286
+ ],
287
+ [
288
+ "God is love."
289
+ ],
290
+ [
291
+ "And the LORD God formed man of the dust of the ground, "
292
+ "and breathed into his nostrils the breath of life; "
293
+ "and man became a living soul."
294
+ ],
295
+ [
296
+ "Wherefore seeing we also are compassed about with so great a cloud "
297
+ "of witnesses, let us lay aside every weight, and the sin which doth "
298
+ "so easily beset us, and let us run with patience the race that is set before us,"
299
+ ],
300
+ [
301
+ "Jesus wept."
302
+ ],
303
+ ],
304
+ inputs=[difficulty_input_chirho],
305
+ )
306
+
307
+ with gr.Tab("About"):
308
+ gr.Markdown("""# Passage Difficulty Scorer & Plain-Language Simplifier
309
+
310
+ ## What This Does
311
+ This model performs two tasks on Bible passages:
312
+
313
+ ### 1. Difficulty Scoring
314
+ Analyzes a passage and outputs:
315
+ - **Reading Level** (Grade 1-12): Approximate grade level needed to understand the text
316
+ - **Vocabulary Complexity** (Low/Medium/High): How many uncommon or specialized words
317
+ - **Archaic Forms**: Count of archaic English words (thee, thou, hath, etc.)
318
+ - **Overall Difficulty** (Easy/Medium/Hard): Combined difficulty assessment
319
+
320
+ ### 2. Simplification
321
+ Converts archaic or complex Bible passages into plain modern English, trained on:
322
+ - **KJV -> BBE**: King James Version to Bible in Basic English (850-word vocabulary)
323
+ - **KJV -> WEB**: King James Version to World English Bible (modern)
324
+ - **ASV -> BBE**: American Standard Version to Basic English
325
+ - **YLT -> WEB**: Young's Literal Translation to modern English
326
+
327
+ ## Model Details
328
+ - **Base Model**: google/flan-t5-small (60M parameters)
329
+ - **Training**: Multi-task learning with both tasks mixed together
330
+ - **Data**: ~160K examples from 6 public-domain Bible translations
331
+ - **Source**: ScrollMapper Bible Databases (GitHub)
332
+
333
+ ## Translations Used
334
+ | Translation | Style | Role |
335
+ |---|---|---|
336
+ | KJV (King James Version) | Formal, archaic | Complex source |
337
+ | ASV (American Standard Version) | Formal, dated | Complex source |
338
+ | YLT (Young's Literal Translation) | Ultra-literal | Complex source |
339
+ | Darby Bible | Literal, dated | Complex source |
340
+ | BBE (Bible in Basic English) | 850-word vocabulary, Grade 4 | Simple target |
341
+ | WEB (World English Bible) | Modern, public domain | Simple target |
342
+
343
+ ## Limitations
344
+ - Trained only on Bible text; may not generalize well to other domains
345
+ - Simplification quality varies by verse length and complexity
346
+ - Difficulty scoring is based on algorithmic features, not human annotation
347
+ - Small model (60M params) trades accuracy for speed and accessibility
348
+
349
+ ---
350
+ Built with love for Jesus. Published by [loveJesus](https://huggingface.co/LoveJesus).
351
+ """)
352
+
353
+ return demo_chirho
354
+
355
+
356
+ # Load model at startup
357
+ load_model_chirho()
358
+
359
+ # Launch
360
+ demo_chirho = build_demo_chirho()
361
+ demo_chirho.launch()
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ # For God so loved the world that he gave his only begotten Son,
2
+ # that whoever believes in him should not perish but have eternal life. - John 3:16
3
+
4
+ transformers>=4.40
5
+ torch>=2.3
6
+ sentencepiece>=0.2
7
+ protobuf>=4.25
8
+ gradio>=4.0