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"""[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)}"