Spaces:
Sleeping
Sleeping
File size: 7,106 Bytes
35d1965 |
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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# test_preloaded_model.py
import gradio as gr
import pickle
import os
# --- Dependencies needed for the Class Definition ---
from transformers import pipeline
import torch
# --- Define the Class to Hold Both Pipelines ---
# IMPORTANT: This exact class definition MUST be present here,
# identical to the one in save_combined_model.py, for unpickling to work.
class CombinedAnalyzer:
"""
A class to encapsulate sentiment analysis and AI text detection pipelines.
NOTE: This definition must match the one used when saving the .pkl file.
"""
def __init__(self, sentiment_model_name="distilbert-base-uncased-finetuned-sst-2-english",
detector_model_name="Hello-SimpleAI/chatgpt-detector-roberta"):
print("Initializing CombinedAnalyzer structure...")
self.device = 0 if torch.cuda.is_available() else -1
self.sentiment_model_name = sentiment_model_name
self.detector_model_name = detector_model_name
self.sentiment_pipeline = None
self.detector_pipeline = None
print(f"Class structure defined. Expecting pipelines for models: {sentiment_model_name}, {detector_model_name}")
def analyze(self, text):
"""
Analyzes the input text for both sentiment and authenticity.
"""
if not isinstance(text, str) or not text.strip():
return "Error: Input text cannot be empty."
results = []
# 1. Sentiment Analysis
if self.sentiment_pipeline and callable(self.sentiment_pipeline):
try:
sentiment_result = self.sentiment_pipeline(text)[0]
sentiment_label = sentiment_result['label']
sentiment_score = round(sentiment_result['score'] * 100, 2)
results.append(f"Sentiment: {sentiment_label} (Confidence: {sentiment_score}%)")
except Exception as e:
results.append(f"Sentiment Analysis Error in loaded model: {e}")
else:
results.append("Sentiment Analysis: Model not available or not callable in loaded object.")
# 2. AI Text Detection (Authenticity)
if self.detector_pipeline and callable(self.detector_pipeline):
try:
detector_result = self.detector_pipeline(text)[0]
auth_label_raw = detector_result['label']
auth_score = round(detector_result['score'] * 100, 2)
if auth_label_raw.lower() in ['chatgpt', 'ai', 'generated']:
auth_label_display = "Likely AI-Generated"
elif auth_label_raw.lower() in ['human', 'real']:
auth_label_display = "Likely Human-Written"
else:
auth_label_display = f"Label: {auth_label_raw}"
results.append(f"Authenticity: {auth_label_display} (Confidence: {auth_score}%)")
except Exception as e:
results.append(f"AI Text Detection Error in loaded model: {e}")
else:
results.append("Authenticity: AI Text Detector model not available or not callable in loaded object.")
return "\n".join(results)
# --- Load the Model Automatically on Startup ---
analyzer = None
pickle_filename = "combined_analyzer.pkl"
model_dir = "saved_model"
pickle_filepath = os.path.join(model_dir, pickle_filename)
model_load_error = None # Store potential loading error message
print(f"Attempting to load pre-saved model from: {pickle_filepath}")
try:
print("\n--- SECURITY WARNING ---")
print(f"Loading '{pickle_filepath}'. Unpickling data from untrusted sources is a security risk.")
print("Ensure this .pkl file was created by you or a trusted source.\n")
if not os.path.exists(pickle_filepath):
raise FileNotFoundError(f"Model file not found at {pickle_filepath}")
with open(pickle_filepath, 'rb') as f:
analyzer = pickle.load(f)
if not hasattr(analyzer, 'analyze') or not callable(analyzer.analyze):
raise TypeError("Loaded object is not a valid analyzer (missing 'analyze' method).")
else:
print("Model loaded successfully.")
sentiment_name = getattr(analyzer, 'sentiment_model_name', 'Unknown')
detector_name = getattr(analyzer, 'detector_model_name', 'Unknown')
print(f" -> Sentiment Model: {sentiment_name}")
print(f" -> Detector Model: {detector_name}")
except FileNotFoundError as e:
model_load_error = f"ERROR loading model: {e}"
print(model_load_error)
print("Please ensure 'save_combined_model.py' was run successfully and")
print(f"the file '{pickle_filename}' exists in the '{model_dir}' directory.")
except (pickle.UnpicklingError, TypeError, AttributeError) as e:
model_load_error = f"ERROR loading model: The pickle file might be corrupted, incompatible, or from a different version. Details: {e}"
print(model_load_error)
except Exception as e:
model_load_error = f"An unexpected ERROR occurred during model loading: {e}"
print(model_load_error)
# --- Define the Gradio Analysis Function ---
def analyze_text_interface(text_input):
"""Function called by Gradio to perform analysis using the pre-loaded model."""
if analyzer is None:
# Use the stored error message if available
error_msg = model_load_error or f"ERROR: The analyzer model could not be loaded from '{pickle_filepath}'."
return error_msg
if not text_input or not text_input.strip():
return "Please enter some text to analyze."
print(f"Analyzing text: '{text_input[:60]}...'")
try:
results = analyzer.analyze(text_input)
print("Analysis complete.")
return results
except Exception as e:
print(f"Error during analysis: {e}")
return f"An error occurred during analysis:\n{e}"
# --- Build the Gradio Interface ---
# **CORRECTION HERE:** Define the warning message string separately
warning_message_text = ""
if analyzer is None:
# Use newline characters safely outside the f-string expression
warning_message_text = "\n\n***WARNING: MODEL FAILED TO LOAD. ANALYSIS WILL NOT WORK.***"
# Construct the full description string
description_text = (
f"Enter text to analyze using the pre-loaded model from '{pickle_filepath}'.\n"
"Checks for sentiment (Positive/Negative) and predicts if text is Human-Written or AI-Generated."
f"{warning_message_text}" # Use the variable here
)
interface = gr.Interface(
fn=analyze_text_interface,
inputs=gr.Textbox(lines=7, label="Text to Analyze", placeholder="Enter review text here..."),
outputs=gr.Textbox(lines=7, label="Analysis Results", interactive=False),
title="Sentiment & Authenticity Analyzer",
description=description_text, # Use the constructed description string
allow_flagging='never'
)
# --- Launch the Interface ---
if __name__ == "__main__":
if analyzer is None:
print("\n--- Interface launched, but MODEL IS NOT LOADED. Analysis will fail. ---")
else:
print("\n--- Launching Gradio Interface with pre-loaded model ---")
interface.launch() |