Catello Vivenzio
[FEATURE] Riaddestramento integrato del modello reale attivato dalla deriva dei dati.
c5a9b29 | import os | |
| from transformers import pipeline | |
| from dotenv import load_dotenv | |
| from supabase import create_client, Client | |
| # --- GESTIONE DINAMICA DEL MODELLO --- | |
| ORIGINAL_MODEL_PATH = "cardiffnlp/twitter-roberta-base-sentiment-latest" | |
| FINE_TUNED_MODEL_PATH = "src/models/fine_tuned_roberta/" | |
| # ----------------------------------------------------------- | |
| # Carica le variabili dal file .env | |
| load_dotenv() | |
| class SentimentModel: | |
| # Inizializzazione globale del client Supabase | |
| supabase_url = os.getenv("SUPABASE_URL") | |
| supabase_key = os.getenv("SUPABASE_KEY") | |
| supabase: Client = create_client(supabase_url, supabase_key) if supabase_url and supabase_key else None | |
| """ | |
| Gestisce l'istanza e l'inferenza del modello RoBERTa e il log su Supabase. | |
| """ | |
| def __init__(self): | |
| """ | |
| Inizializza la pipeline di sentiment-analysis per il modello e supabase client. | |
| """ | |
| supabase_url = os.getenv("SUPABASE_URL") | |
| supabase_key = os.getenv("SUPABASE_KEY") | |
| self.supabase = None | |
| if supabase_url and supabase_key: | |
| try: | |
| # Se le chiavi sono presenti ma malformate | |
| # create_client potrebbe sollevare un'eccezione | |
| self.supabase = create_client(supabase_url, supabase_key) | |
| except Exception as e: | |
| print(f"[SUPABASE INIT ERROR] Invalid or malformed keys: {e}") | |
| else: | |
| print("[SUPABASE INIT WARNING] Credentials not found in the environment.") | |
| # --- MODIFICA MLOPS FASE 3: CARICAMENTO DINAMICO --- | |
| # Controlla se la pipeline di retraining ha salvato un modello aggiornato localmente | |
| if os.path.exists(FINE_TUNED_MODEL_PATH) and os.listdir(FINE_TUNED_MODEL_PATH): | |
| print(f"[MODEL MLOps] Trovato modello riaddestrato localmente! Caricamento da: {FINE_TUNED_MODEL_PATH}") | |
| self.analyzer = pipeline("sentiment-analysis", model=FINE_TUNED_MODEL_PATH, tokenizer=FINE_TUNED_MODEL_PATH) | |
| else: | |
| print(f"[MODEL MLOps] Nessun modello locale trovato. Caricamento modello originale da Hugging Face: {ORIGINAL_MODEL_PATH}") | |
| self.analyzer = pipeline("sentiment-analysis", model=ORIGINAL_MODEL_PATH) | |
| # --------------------------------------------------- | |
| def predict(self, text: str): | |
| """ | |
| Analizza il testo e restituisce dati pronti per il frontend. | |
| Returns: | |
| dict: Label, stringa per display e valore numerico per la barra. | |
| """ | |
| # Nel caso di input vuoto | |
| if not text or not text.strip(): | |
| return None | |
| result = self.analyzer(text)[0] | |
| confidence_pct = round(float(result['score']) * 100, 1) | |
| # Inserimento automatico su supabase | |
| if self.supabase: | |
| try: | |
| self.supabase.table("feedback_logs").insert({ | |
| "text": text, | |
| "label": result['label'].lower(), # Assicura consistenza con gli import di Evidently | |
| "score": result['score'] # Rispetta il vincolo NOT NULL della colonna 'score' | |
| }).execute() | |
| print(f"[SUPABASE LOG] Record saved successfully for text: {text[:20]}...") | |
| except Exception as e: | |
| # Cattura l'errore a log senza far crashare l'interfaccia utente | |
| print(f"[SUPABASE ERROR] Unable to save prediction to database: {e}") | |
| else: | |
| print("[SUPABASE WARNING] Client not initialized: credentials missing from environment.") | |
| return { | |
| "label": result['label'], | |
| "confidence_display": f"{confidence_pct}%", | |
| "confidence_value": confidence_pct | |
| } | |
| # Istanza globale del modello (Singleton) per ottimizzare | |
| # l'uso delle risorse. | |
| # Viene importata in api.py per gestire le richieste degli utenti. | |
| #model_instance = SentimentModel() | |