Spaces:
Sleeping
Sleeping
File size: 4,514 Bytes
d0fff4c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
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()
|