pythonprincess commited on
Commit
50cdb50
·
verified ·
1 Parent(s): afc0da4

Delete bias_utils.py

Browse files
Files changed (1) hide show
  1. bias_utils.py +0 -197
bias_utils.py DELETED
@@ -1,197 +0,0 @@
1
- # models/bias/bias_utils.py
2
-
3
- """
4
- Bias Detection Utilities for Penny
5
-
6
- Provides zero-shot classification for detecting potential bias in text responses.
7
- Uses a classification model to identify neutral content vs. biased language patterns.
8
- """
9
-
10
- import asyncio
11
- from typing import Dict, Any, Optional, List
12
- import logging
13
-
14
- # --- Logging Setup ---
15
- logger = logging.getLogger(__name__)
16
-
17
- # --- Model Loader Import ---
18
- try:
19
- from app.model_loader import load_model_pipeline
20
- MODEL_LOADER_AVAILABLE = True
21
- except ImportError:
22
- MODEL_LOADER_AVAILABLE = False
23
- logger.warning("Could not import load_model_pipeline. Bias detection will operate in fallback mode.")
24
-
25
- # Global variable to store the loaded pipeline for re-use
26
- BIAS_PIPELINE: Optional[Any] = None
27
- AGENT_NAME = "penny-bias-checker"
28
-
29
- # Define the labels for Zero-Shot Classification.
30
- CANDIDATE_LABELS = [
31
- "neutral and objective",
32
- "contains political bias",
33
- "uses emotional language",
34
- "is factually biased",
35
- ]
36
-
37
-
38
- def _initialize_bias_pipeline() -> bool:
39
- """
40
- Initializes the bias detection pipeline only once.
41
-
42
- Returns:
43
- bool: True if pipeline loaded successfully, False otherwise
44
- """
45
- global BIAS_PIPELINE
46
-
47
- if BIAS_PIPELINE is not None:
48
- return True
49
-
50
- if not MODEL_LOADER_AVAILABLE:
51
- logger.warning(f"{AGENT_NAME}: Model loader not available, pipeline initialization skipped")
52
- return False
53
-
54
- try:
55
- logger.info(f"Loading {AGENT_NAME}...")
56
- BIAS_PIPELINE = load_model_pipeline(AGENT_NAME)
57
- logger.info(f"Model {AGENT_NAME} loaded successfully")
58
- return True
59
- except Exception as e:
60
- logger.error(f"Failed to load {AGENT_NAME}: {e}", exc_info=True)
61
- BIAS_PIPELINE = None
62
- return False
63
-
64
-
65
- # Attempt to initialize pipeline at module load
66
- _initialize_bias_pipeline()
67
-
68
-
69
- async def check_bias(text: str) -> Dict[str, Any]:
70
- """
71
- Runs zero-shot classification to check for bias in the input text.
72
-
73
- Uses a pre-loaded classification model to analyze text for:
74
- - Neutral and objective language
75
- - Political bias
76
- - Emotional language
77
- - Factual bias
78
-
79
- Args:
80
- text: The string of text to analyze for bias
81
-
82
- Returns:
83
- Dictionary containing:
84
- - analysis: List of labels with confidence scores, sorted by score
85
- - available: Whether the bias detection service is operational
86
- - message: Optional error or status message
87
-
88
- Example:
89
- >>> result = await check_bias("This is neutral text.")
90
- >>> result['analysis'][0]['label']
91
- 'neutral and objective'
92
- """
93
- global BIAS_PIPELINE
94
-
95
- # Input validation
96
- if not text or not isinstance(text, str):
97
- logger.warning("check_bias called with invalid text input")
98
- return {
99
- "analysis": [],
100
- "available": False,
101
- "message": "Invalid input: text must be a non-empty string"
102
- }
103
-
104
- # Strip text to avoid processing whitespace
105
- text = text.strip()
106
- if not text:
107
- logger.warning("check_bias called with empty text after stripping")
108
- return {
109
- "analysis": [],
110
- "available": False,
111
- "message": "Invalid input: text is empty"
112
- }
113
-
114
- # Ensure pipeline is initialized
115
- if BIAS_PIPELINE is None:
116
- logger.warning(f"{AGENT_NAME} pipeline not available, attempting re-initialization")
117
- if not _initialize_bias_pipeline():
118
- return {
119
- "analysis": [],
120
- "available": False,
121
- "message": "Bias detection service is currently unavailable"
122
- }
123
-
124
- try:
125
- loop = asyncio.get_event_loop()
126
-
127
- # Run inference in thread pool to avoid blocking
128
- results = await loop.run_in_executor(
129
- None,
130
- lambda: BIAS_PIPELINE(
131
- text,
132
- CANDIDATE_LABELS,
133
- multi_label=True
134
- )
135
- )
136
-
137
- # Validate results structure
138
- if not results or not isinstance(results, dict):
139
- logger.error(f"Bias detection returned unexpected format: {type(results)}")
140
- return {
141
- "analysis": [],
142
- "available": True,
143
- "message": "Inference returned unexpected format"
144
- }
145
-
146
- labels = results.get('labels', [])
147
- scores = results.get('scores', [])
148
-
149
- if not labels or not scores:
150
- logger.warning("Bias detection returned empty labels or scores")
151
- return {
152
- "analysis": [],
153
- "available": True,
154
- "message": "No classification results returned"
155
- }
156
-
157
- # Build analysis results
158
- analysis = [
159
- {"label": label, "score": float(score)}
160
- for label, score in zip(labels, scores)
161
- ]
162
-
163
- # Sort by confidence score (descending)
164
- analysis.sort(key=lambda x: x['score'], reverse=True)
165
-
166
- logger.debug(f"Bias check completed successfully, top result: {analysis[0]['label']} ({analysis[0]['score']:.3f})")
167
-
168
- return {
169
- "analysis": analysis,
170
- "available": True
171
- }
172
-
173
- except asyncio.CancelledError:
174
- logger.warning("Bias detection task was cancelled")
175
- raise
176
-
177
- except Exception as e:
178
- logger.error(f"Error during bias detection inference: {e}", exc_info=True)
179
- return {
180
- "analysis": [],
181
- "available": False,
182
- "message": f"Bias detection error: {str(e)}"
183
- }
184
-
185
-
186
- def get_bias_pipeline_status() -> Dict[str, Any]:
187
- """
188
- Returns the current status of the bias detection pipeline.
189
-
190
- Returns:
191
- Dictionary with pipeline availability status
192
- """
193
- return {
194
- "agent_name": AGENT_NAME,
195
- "available": BIAS_PIPELINE is not None,
196
- "model_loader_available": MODEL_LOADER_AVAILABLE
197
- }