la04 commited on
Commit
afd6605
·
verified ·
1 Parent(s): b0a7bef

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +47 -76
app.py CHANGED
@@ -1,106 +1,77 @@
1
- from transformers import pipeline, AutoModelForQuestionAnswering, AutoTokenizer
 
2
  import gradio as gr
3
  from PyPDF2 import PdfReader
4
  import re
5
 
6
- # Modell und Tokenizer laden
7
- model_name = "deepset/roberta-base-squad2"
8
- model = AutoModelForQuestionAnswering.from_pretrained(model_name)
9
- tokenizer = AutoTokenizer.from_pretrained(model_name)
10
- qa_pipeline = pipeline("question-answering", model=model, tokenizer=tokenizer)
11
 
12
  # Funktion zum Extrahieren und Bereinigen von Text aus PDF
13
  def extract_text_from_pdf(pdf_path):
14
  reader = PdfReader(pdf_path)
15
  text = ""
16
  for page in reader.pages:
17
- text += page.extract_text()
 
 
18
  return text
19
 
20
  def clean_text(text):
21
- text = re.sub(r'\s+', ' ', text) # Mehrere Leerzeichen und Zeilenumbrüche reduzieren
22
- text = re.sub(r'[^\w\s.,-]', '', text) # Entfernen von Sonderzeichen
 
23
  return text.strip()
24
 
25
- def split_text_into_paragraphs(text, max_length=500):
26
- paragraphs = text.split("\n")
27
- refined_paragraphs = []
28
- temp = ""
29
- for para in paragraphs:
30
- if len(temp) + len(para) <= max_length:
31
- temp += " " + para
32
- else:
33
- refined_paragraphs.append(temp.strip())
34
- temp = para
35
- if temp:
36
- refined_paragraphs.append(temp.strip())
37
- return refined_paragraphs
38
 
39
- # Funktion zur Relevanzbewertung von Abschnitten
40
- def find_relevant_parts(question, context_parts):
41
- keywords = question.lower().split()
42
- relevant_parts = [
43
- part for part in context_parts if any(keyword in part.lower() for keyword in keywords)
44
- ]
45
- if not relevant_parts:
46
- # Fallback: Abschnitte mit den meisten Übereinstimmungen wählen
47
- keyword_counts = [
48
- (part, sum(part.lower().count(keyword) for keyword in keywords))
49
- for part in context_parts
50
- ]
51
- keyword_counts.sort(key=lambda x: x[1], reverse=True)
52
- relevant_parts = [keyword_counts[0][0]] if keyword_counts else context_parts
53
- return relevant_parts
54
 
55
- # Funktion für Antwort-Postprocessing
56
- def refine_answer(answer, question, context):
57
- if not answer or len(answer.split()) < 3:
58
- # Versuche, die Antwort direkt aus dem Kontext zu extrahieren
59
- keywords = question.lower().split()
60
- relevant_sentences = [
61
- sentence for sentence in context.split('.')
62
- if any(keyword in sentence.lower() for keyword in keywords)
63
- ]
64
- if relevant_sentences:
65
- return " ".join(relevant_sentences).strip()
66
- return "Die Antwort konnte nicht eindeutig aus dem Dokument ermittelt werden."
67
- return answer.capitalize().strip()
68
 
69
- # Hauptfunktion für den Chatbot
70
- def chatbot_response(pdf_path, question):
71
- # Text extrahieren und bereinigen
72
- context = clean_text(extract_text_from_pdf(pdf_path))
73
- context_parts = split_text_into_paragraphs(context)
74
-
75
- # Relevante Abschnitte finden
76
- relevant_parts = find_relevant_parts(question, context_parts)
77
-
78
- # Antworten aus relevanten Abschnitten generieren
79
- answers = []
80
- for part in relevant_parts:
81
- try:
82
- result = qa_pipeline(question=question, context=part)
83
- answers.append(result['answer'])
84
- except Exception:
85
- continue
86
 
87
- # Beste Antwort auswählen und verfeinern
88
- combined_context = " ".join(relevant_parts)
89
- final_answer = refine_answer(" ".join(answers).strip(), question, combined_context)
90
- return final_answer
91
 
92
  # Gradio-Interface erstellen
93
  pdf_input = gr.File(label="PDF-Datei hochladen", type="filepath")
94
  question_input = gr.Textbox(label="Frage eingeben", placeholder="Stelle eine Frage zu dem PDF-Dokument")
95
- response_output = gr.Textbox(label="Antwort")
96
 
97
  interface = gr.Interface(
98
  fn=chatbot_response,
99
  inputs=[pdf_input, question_input],
100
  outputs=response_output,
101
- title="Verbesserte PDF-Fragebeantwortung",
102
- description="Lade eine PDF-Datei hoch und stelle Fragen zu ihrem Inhalt. Antworten basieren nur auf den PDF-Inhalten."
103
  )
104
 
105
- if __name__ == "__main__":
106
- interface.launch()
 
1
+ import torch
2
+ from transformers import RagRetriever, RagTokenizer, RagSequenceForGeneration
3
  import gradio as gr
4
  from PyPDF2 import PdfReader
5
  import re
6
 
7
+ # Laden des Tokenizers, des Retrievers und des Modells (auf CPU)
8
+ model_name = "facebook/rag-token-nq"
9
+ tokenizer = RagTokenizer.from_pretrained(model_name)
10
+ retriever = RagRetriever.from_pretrained(model_name, index_name="exact")
11
+ model = RagSequenceForGeneration.from_pretrained(model_name).to("cpu") # Modell auf CPU laden
12
 
13
  # Funktion zum Extrahieren und Bereinigen von Text aus PDF
14
  def extract_text_from_pdf(pdf_path):
15
  reader = PdfReader(pdf_path)
16
  text = ""
17
  for page in reader.pages:
18
+ page_text = page.extract_text()
19
+ if page_text:
20
+ text += page_text
21
  return text
22
 
23
  def clean_text(text):
24
+ # Entfernen unnötiger Zeichen, Reduktion von Leerzeichen
25
+ text = re.sub(r'\s+', ' ', text)
26
+ text = re.sub(r'[^\w\s.,-]', '', text)
27
  return text.strip()
28
 
29
+ # Funktion zum Aufteilen langer Texte in Abschnitte
30
+ def split_text_into_chunks(text, chunk_size=1000):
31
+ words = text.split()
32
+ chunks = [' '.join(words[i:i + chunk_size]) for i in range(0, len(words), chunk_size)]
33
+ return chunks
 
 
 
 
 
 
 
 
34
 
35
+ # Hauptfunktion für die Fragebeantwortung mit RAG
36
+ def chatbot_response(pdf_path, question):
37
+ try:
38
+ # PDF-Inhalt extrahieren und bereinigen
39
+ context = clean_text(extract_text_from_pdf(pdf_path))
40
+ if not context:
41
+ return "Das Dokument enthält keinen Text oder konnte nicht gelesen werden."
 
 
 
 
 
 
 
 
42
 
43
+ # Dokumenttext in Abschnitte aufteilen, um Speicher zu sparen
44
+ chunks = split_text_into_chunks(context)
 
 
 
 
 
 
 
 
 
 
 
45
 
46
+ # Antwortgenerierung mit minimalem Speicherverbrauch
47
+ answers = []
48
+ with torch.no_grad(): # Verhindert das Speichern von Gradienten (für CPU wichtig)
49
+ for chunk in chunks:
50
+ retriever.index = [chunk]
51
+ inputs = tokenizer(question, return_tensors="pt").to("cpu") # Sicherstellen, dass Inputs auf CPU bleiben
52
+ generated_ids = model.generate(**inputs, max_length=150) # Kürzere Antwortlänge
53
+ answer = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
54
+ if answer:
55
+ answers.append(answer)
56
+
57
+ final_answer = " / ".join(answers) if answers else "Keine spezifische Antwort gefunden."
58
+ return final_answer
 
 
 
 
59
 
60
+ except Exception as e:
61
+ return f"Es ist ein Fehler aufgetreten: {str(e)}"
 
 
62
 
63
  # Gradio-Interface erstellen
64
  pdf_input = gr.File(label="PDF-Datei hochladen", type="filepath")
65
  question_input = gr.Textbox(label="Frage eingeben", placeholder="Stelle eine Frage zu dem PDF-Dokument")
66
+ response_output = gr.Textbox(label="Antwort", lines=4)
67
 
68
  interface = gr.Interface(
69
  fn=chatbot_response,
70
  inputs=[pdf_input, question_input],
71
  outputs=response_output,
72
+ title="RAG PDF-Fragebeantwortung auf CPU",
73
+ description="Lade eine PDF-Datei hoch und stelle Fragen zu ihrem Inhalt. Das System verwendet Retrieval-Augmented Generation (RAG) auf CPU zur Beantwortung.",
74
  )
75
 
76
+ # Interface für Hugging Face Spaces
77
+ interface.launch(share=True)