Quizzz / app.py
CodeKing555's picture
Create app.py
d0fff4c verified
import gradio as gr
import pdfplumber
import torch
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
# ------------------------------------------------------------------------------
# 1) Modell laden (valhalla/t5-base-qg-hl)
# ------------------------------------------------------------------------------
MODEL_NAME = "valhalla/t5-base-qg-hl"
print(f"Lade Tokenizer und Modell: {MODEL_NAME}")
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
model = AutoModelForSeq2SeqLM.from_pretrained(MODEL_NAME)
# Optional: auf CPU behalten (gratis, aber langsamer) oder GPU nutzen, wenn Hugging Face
# Community GPU verfügbar ist (dann model.to("cuda"))
device = torch.device("cpu")
model.to(device)
# ------------------------------------------------------------------------------
# 2) PDF-Text extrahieren
# ------------------------------------------------------------------------------
def extract_text_from_pdf(pdf_file):
"""
Extrahiert den Text aller Seiten aus einem hochgeladenen PDF.
"""
if pdf_file is None:
return ""
text = ""
with pdfplumber.open(pdf_file) as pdf:
for page in pdf.pages:
text += page.extract_text() + "\n"
# Minimales Cleaning
text = " ".join(text.split())
return text
# ------------------------------------------------------------------------------
# 3) Question Generation mit T5
# Dieses Modell ("valhalla/t5-base-qg-hl") nutzt einen 'Highlight-basierten'
# Ansatz. Am einfachsten probieren wir, den gesamten Text an das Modell zu geben.
# Für bessere Qualität könnte man (a) Text kürzen, (b) "answer highlighting" machen.
# ------------------------------------------------------------------------------
def generate_questions(text_chunk, max_length=128):
"""
Fragt das T5-QG-Modell nach Fragen für den gegebenen Text.
Achtung: 'valhalla/t5-base-qg-hl' erwartet i.d.R. 'question: ... context: ...' oder
'generate question: ...' Prompts. Wir machen ein einfaches prompt-engineering.
"""
# Einfacher Prompt: wir fügen "generate question:" voran
prompt_text = f"generate question: {text_chunk}"
inputs = tokenizer.encode(prompt_text, return_tensors="pt").to(device)
output = model.generate(
inputs,
max_length=max_length,
num_beams=4,
early_stopping=True
)
question = tokenizer.decode(output[0], skip_special_tokens=True)
return question
# ------------------------------------------------------------------------------
# 4) Gradio-Workflows
# ------------------------------------------------------------------------------
def process_pdf(pdf_file, num_questions):
"""
1) PDF extrahieren
2) Kürzen (Text chunk)
3) Mehrere Fragen generieren
"""
if pdf_file is None:
return "Keine PDF hochgeladen."
# PDF-Text holen
text = extract_text_from_pdf(pdf_file.name)
if not text:
return "Text konnte nicht extrahiert werden oder PDF ist leer."
# Ggf. nur ersten 1500 Zeichen nehmen, damit wir das Modell nicht überfüttern
text_chunk = text[:1500]
# Generiere mehrere Fragen
questions_output = []
for i in range(num_questions):
q = generate_questions(text_chunk)
questions_output.append(f"Frage {i+1}: {q}")
# Kombiniere das als Ausgabe
final_output = "\n\n".join(questions_output)
return final_output
def build_app():
with gr.Blocks() as demo:
gr.Markdown("# QG-PDF – Fragegenerierung aus PDF (ohne OpenAI)")
gr.Markdown(
"Lade ein PDF hoch und wähle, wie viele Fragen generiert werden sollen. "
"Wir verwenden das Modell **valhalla/t5-base-qg-hl**, "
"das (meist) eine offene Frage ausgibt."
)
with gr.Row():
pdf_file = gr.File(label="📄 PDF hochladen")
q_slider = gr.Slider(
minimum=1,
maximum=5,
step=1,
value=3,
label="Anzahl Fragen"
)
generate_btn = gr.Button("Fragen generieren")
output_box = gr.Textbox(
label="Generierte Fragen",
lines=10
)
def on_click_generate(pdf, q_num):
return process_pdf(pdf, q_num)
generate_btn.click(
fn=on_click_generate,
inputs=[pdf_file, q_slider],
outputs=[output_box]
)
return demo
demo = build_app()
if __name__ == "__main__":
demo.launch()