Hamzasajjad38 commited on
Commit
09e53de
·
verified ·
1 Parent(s): 581e80c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +67 -57
app.py CHANGED
@@ -2,66 +2,76 @@ import subprocess, sys
2
  subprocess.run([sys.executable, "-m", "spacy", "download", "en_core_web_sm"],
3
  stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
4
 
5
- import gradio as gr
6
- import spacy, torch
 
7
  from transformers import T5ForConditionalGeneration, AutoTokenizer
8
 
9
- MODEL_ID = "Hamzasajjad38/t5-small-qg"
10
- tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, use_fast=True)
11
- model = T5ForConditionalGeneration.from_pretrained(MODEL_ID)
12
- device = "cuda" if torch.cuda.is_available() else "cpu"
13
- model = model.to(device)
14
- nlp = spacy.load("en_core_web_sm")
15
 
16
- def generate_questions(passage, num_questions, question_type):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  if not passage or len(passage.strip()) < 30:
18
- return "Please enter a longer passage (at least 30 characters)."
19
- doc = nlp(passage)
20
- candidates = [e.text for e in doc.ents]
21
- if len(candidates) < num_questions:
22
- candidates += [c.text for c in doc.noun_chunks]
23
- seen, unique = set(), []
24
- for c in candidates:
25
- cl = c.lower().strip()
26
- if cl not in seen and 1 < len(c.split()) <= 5:
27
- seen.add(cl)
28
- unique.append(c)
29
- candidates = unique[:int(num_questions)]
30
- if not candidates:
31
- return "Could not extract answer candidates. Try a more detailed passage."
32
- lines = []
33
- for i, answer in enumerate(candidates):
34
- highlighted = passage.replace(answer, f"<hl> {answer} <hl>", 1)
35
- inp = tokenizer(f"generate question: {highlighted}",
36
- return_tensors="pt", max_length=512,
37
- truncation=True).to(device)
38
- out = model.generate(**inp, max_new_tokens=64,
39
- num_beams=4, early_stopping=True)
40
- q = tokenizer.decode(out[0], skip_special_tokens=True)
41
- if question_type == "True / False":
42
- q = f"True or False: {q.rstrip('?')}?"
43
- lines.append(f"Q{i+1}: {q}")
44
- lines.append(f" Answer: {answer}\n")
45
- return "\n".join(lines)
 
 
46
 
47
- demo = gr.Interface(
48
- fn=generate_questions,
49
- inputs=[
50
- gr.Textbox(lines=8, label="Input Passage",
51
- placeholder="Paste any educational paragraph here..."),
52
- gr.Slider(1, 5, value=3, step=1, label="Number of Questions"),
53
- gr.Radio(["Short answer", "True / False"],
54
- value="Short answer", label="Question Type"),
55
- ],
56
- outputs=gr.Textbox(lines=14, label="Generated Questions"),
57
- title="Automatic Question Generator",
58
- description="Fine-tuned T5-small on SQuAD 1.1 — paste any passage to generate questions.",
59
- examples=[
60
- ["Photosynthesis is a process used by plants to convert light energy into chemical energy stored in glucose. It occurs inside chloroplasts using chlorophyll to absorb sunlight.", 3, "Short answer"],
61
- ["The Industrial Revolution began in Britain in the late 18th century. The steam engine invented by James Watt transformed manufacturing and transportation across the country.", 3, "Short answer"],
62
- ["Machine learning is a subset of artificial intelligence where systems learn from data to improve performance without being explicitly programmed.", 2, "True / False"],
63
- ],
64
- allow_flagging="never",
65
- )
66
 
67
- demo.launch()
 
 
 
 
2
  subprocess.run([sys.executable, "-m", "spacy", "download", "en_core_web_sm"],
3
  stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
4
 
5
+ import streamlit as st
6
+ import torch
7
+ import spacy
8
  from transformers import T5ForConditionalGeneration, AutoTokenizer
9
 
10
+ st.set_page_config(page_title="Question Generator", page_icon="🧠")
 
 
 
 
 
11
 
12
+ @st.cache_resource
13
+ def load_model():
14
+ MODEL_ID = "Hamzasajjad38/t5-small-qg"
15
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, use_fast=True)
16
+ model = T5ForConditionalGeneration.from_pretrained(MODEL_ID)
17
+ device = "cuda" if torch.cuda.is_available() else "cpu"
18
+ model = model.to(device)
19
+ nlp = spacy.load("en_core_web_sm")
20
+ return tokenizer, model, device, nlp
21
+
22
+ tokenizer, model, device, nlp = load_model()
23
+
24
+ st.title("🧠 Automatic Question Generator")
25
+ st.markdown("**Fine-tuned T5-small on SQuAD 1.1** — paste any passage to generate questions.")
26
+
27
+ passage = st.text_area("Input Passage", height=200,
28
+ placeholder="Paste any educational paragraph here...")
29
+ num_q = st.slider("Number of Questions", 1, 5, 3)
30
+ q_type = st.radio("Question Type", ["Short answer", "True / False"])
31
+ gen_clicked = st.button("⚡ Generate Questions", type="primary")
32
+
33
+ if gen_clicked:
34
  if not passage or len(passage.strip()) < 30:
35
+ st.warning("Please enter a longer passage.")
36
+ else:
37
+ with st.spinner("Generating questions..."):
38
+ doc = nlp(passage)
39
+ candidates = [e.text for e in doc.ents]
40
+ if len(candidates) < num_q:
41
+ candidates += [c.text for c in doc.noun_chunks]
42
+ seen, unique = set(), []
43
+ for c in candidates:
44
+ cl = c.lower().strip()
45
+ if cl not in seen and 1 < len(c.split()) <= 5:
46
+ seen.add(cl)
47
+ unique.append(c)
48
+ candidates = unique[:num_q]
49
+
50
+ if not candidates:
51
+ st.error("Could not extract candidates. Try a more detailed passage.")
52
+ else:
53
+ results = []
54
+ for i, answer in enumerate(candidates):
55
+ highlighted = passage.replace(answer, f"<hl> {answer} <hl>", 1)
56
+ inp = tokenizer(f"generate question: {highlighted}",
57
+ return_tensors="pt", max_length=512,
58
+ truncation=True).to(device)
59
+ out = model.generate(**inp, max_new_tokens=64,
60
+ num_beams=4, early_stopping=True)
61
+ q = tokenizer.decode(out[0], skip_special_tokens=True)
62
+ if q_type == "True / False":
63
+ q = f"True or False: {q.rstrip('?')}?"
64
+ results.append((i+1, q, answer))
65
 
66
+ st.success(f"Generated {len(results)} questions!")
67
+ output_text = ""
68
+ for i, q, ans in results:
69
+ st.markdown(f"**Q{i}: {q}**")
70
+ st.markdown(f"Answer: `{ans}`")
71
+ st.divider()
72
+ output_text += f"Q{i}: {q}\nAnswer: {ans}\n\n"
 
 
 
 
 
 
 
 
 
 
 
 
73
 
74
+ st.download_button("📄 Download as TXT",
75
+ data=output_text,
76
+ file_name="questions.txt",
77
+ mime="text/plain")