Mail_Analyser_2 / utils.py
NathanPap's picture
Update utils.py
1b225dc verified
raw
history blame
4.69 kB
import pandas as pd
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
# Globale Analyseinstanz
_analyzer = None
def get_analyzer():
"""Singleton-Muster zur Vermeidung der Modellneuinitialisierung bei jedem Aufruf"""
global _analyzer
if _analyzer is None:
_analyzer = CSVAnalysierer()
return _analyzer
class CSVAnalysierer:
def __init__(self):
self.model_name = "mistralai/Mistral-7B-Instruct-v0.2"
try:
print("Modell wird initialisiert...")
# Tokenizer-Initialisierung mit spezifischer Konfiguration
self.tokenizer = AutoTokenizer.from_pretrained(
self.model_name,
trust_remote_code=True,
use_fast=False
)
# Padding-Token-Konfiguration
if self.tokenizer.pad_token is None:
self.tokenizer.pad_token = self.tokenizer.eos_token
self.tokenizer.padding_side = "right"
# Modell-Initialisierung
self.model = AutoModelForCausalLM.from_pretrained(
self.model_name,
torch_dtype=torch.float16,
device_map="auto",
trust_remote_code=True
)
# Sicherstellen, dass das Modell das Padding-Token kennt
self.model.config.pad_token_id = self.tokenizer.pad_token_id
print("Modell erfolgreich initialisiert!")
except Exception as e:
print(f"Initialisierungsfehler: {str(e)}")
raise
def kontext_vorbereiten(self, df: pd.DataFrame) -> str:
"""Bereitet den Kontext mit den DataFrame-Daten vor."""
try:
kontext = "E-Mail-Informationen:\n\n"
# DataFrame in String umwandeln und fehlende Werte behandeln
df_str = df.fillna("Keine Angabe").astype(str)
# Jede Zeile verarbeiten
for index in range(len(df_str)):
zeile = df_str.iloc[index]
kontext += f"E-Mail {index + 1}:\n"
for spalte in df_str.columns:
kontext += f"{spalte}: {zeile[spalte]}\n"
kontext += "---\n"
return kontext.strip()
except Exception as e:
raise Exception(f"Fehler bei der Kontextvorbereitung: {str(e)}")
def antwort_generieren(self, kontext: str, frage: str) -> str:
"""Generiert eine Antwort auf die Frage unter Verwendung des Kontexts."""
prompt = f"""<s>[INST] Sie sind ein deutscher Assistent für Facility Management Datenanalyse.
Analysieren Sie die folgenden E-Mail-Daten:
{kontext}
Frage: {frage}
Wichtige Anweisungen:
1. Antworten Sie AUSSCHLIEßLICH auf Deutsch
2. Beziehen Sie sich auf die konkreten E-Mail-Daten (Datum, Absender, Betreff)
3. Fassen Sie den relevanten Inhalt präzise zusammen
4. Bei Bedarf erstellen Sie eine strukturierte Übersicht der wichtigsten Punkte
Ihre deutsche Antwort: [/INST]"""
try:
eingabe = self.tokenizer(
prompt,
return_tensors="pt",
padding=True,
truncation=True,
max_length=2048,
pad_to_multiple_of=8,
return_attention_mask=True
).to(self.model.device)
with torch.no_grad():
ausgabe = self.model.generate(
input_ids=eingabe["input_ids"],
attention_mask=eingabe["attention_mask"],
max_new_tokens=512,
temperature=0.7,
top_p=0.95,
repetition_penalty=1.15,
do_sample=True,
num_beams=1,
pad_token_id=self.tokenizer.pad_token_id,
eos_token_id=self.tokenizer.eos_token_id
)
antwort = self.tokenizer.decode(ausgabe[0], skip_special_tokens=True)
antwort = antwort.split("[/INST]")[-1].strip()
return antwort
except Exception as e:
return f"Generierungsfehler: {str(e)}"
def csv_analysieren(df: pd.DataFrame, frage: str) -> str:
"""Hauptfunktion zur CSV-Analyse und Fragenbeantwortung."""
try:
analysierer = get_analyzer() # Verwendet die einzige Instanz
kontext = analysierer.kontext_vorbereiten(df)
antwort = analysierer.antwort_generieren(kontext, frage)
return antwort
except Exception as e:
return f"Fehler bei der Analyse: {str(e)}"