Mukul Rayana commited on
Commit ·
4e44b55
1
Parent(s): d64bbe6
Fix Condition C ablation - pure FAISS order, no safety score bias - mean=0.50
Browse files- eval/ablation_results.json +13 -13
- eval/run_ablation.py +21 -21
eval/ablation_results.json
CHANGED
|
@@ -52,34 +52,39 @@
|
|
| 52 |
0
|
| 53 |
],
|
| 54 |
"condition_c_scores": [
|
| 55 |
-
0,
|
| 56 |
0,
|
| 57 |
0,
|
| 58 |
1,
|
|
|
|
| 59 |
0,
|
|
|
|
|
|
|
|
|
|
| 60 |
0,
|
| 61 |
0,
|
| 62 |
-
|
| 63 |
-
0,
|
| 64 |
-
0,
|
| 65 |
-
0,
|
| 66 |
0,
|
| 67 |
0,
|
| 68 |
1,
|
| 69 |
0,
|
|
|
|
| 70 |
0,
|
| 71 |
0,
|
| 72 |
0,
|
|
|
|
| 73 |
0,
|
| 74 |
0,
|
| 75 |
-
|
|
|
|
| 76 |
0,
|
| 77 |
1,
|
| 78 |
0,
|
| 79 |
0,
|
| 80 |
0,
|
| 81 |
0,
|
|
|
|
| 82 |
0,
|
|
|
|
| 83 |
0,
|
| 84 |
0,
|
| 85 |
1,
|
|
@@ -87,10 +92,6 @@
|
|
| 87 |
1,
|
| 88 |
0,
|
| 89 |
0,
|
| 90 |
-
1,
|
| 91 |
-
1,
|
| 92 |
-
1,
|
| 93 |
-
1,
|
| 94 |
0,
|
| 95 |
1,
|
| 96 |
1,
|
|
@@ -100,8 +101,7 @@
|
|
| 100 |
1,
|
| 101 |
1,
|
| 102 |
1,
|
| 103 |
-
|
| 104 |
-
1
|
| 105 |
],
|
| 106 |
"condition_d_scores": [
|
| 107 |
1,
|
|
@@ -156,7 +156,7 @@
|
|
| 156 |
1
|
| 157 |
],
|
| 158 |
"condition_a_mean": 0.3,
|
| 159 |
-
"condition_c_mean": 0.
|
| 160 |
"condition_d_mean": 0.88,
|
| 161 |
"n": 50
|
| 162 |
}
|
|
|
|
| 52 |
0
|
| 53 |
],
|
| 54 |
"condition_c_scores": [
|
|
|
|
| 55 |
0,
|
| 56 |
0,
|
| 57 |
1,
|
| 58 |
+
1,
|
| 59 |
0,
|
| 60 |
+
1,
|
| 61 |
+
1,
|
| 62 |
+
1,
|
| 63 |
0,
|
| 64 |
0,
|
| 65 |
+
1,
|
|
|
|
|
|
|
|
|
|
| 66 |
0,
|
| 67 |
0,
|
| 68 |
1,
|
| 69 |
0,
|
| 70 |
+
1,
|
| 71 |
0,
|
| 72 |
0,
|
| 73 |
0,
|
| 74 |
+
1,
|
| 75 |
0,
|
| 76 |
0,
|
| 77 |
+
1,
|
| 78 |
+
1,
|
| 79 |
0,
|
| 80 |
1,
|
| 81 |
0,
|
| 82 |
0,
|
| 83 |
0,
|
| 84 |
0,
|
| 85 |
+
1,
|
| 86 |
0,
|
| 87 |
+
1,
|
| 88 |
0,
|
| 89 |
0,
|
| 90 |
1,
|
|
|
|
| 92 |
1,
|
| 93 |
0,
|
| 94 |
0,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
0,
|
| 96 |
1,
|
| 97 |
1,
|
|
|
|
| 101 |
1,
|
| 102 |
1,
|
| 103 |
1,
|
| 104 |
+
0
|
|
|
|
| 105 |
],
|
| 106 |
"condition_d_scores": [
|
| 107 |
1,
|
|
|
|
| 156 |
1
|
| 157 |
],
|
| 158 |
"condition_a_mean": 0.3,
|
| 159 |
+
"condition_c_mean": 0.5,
|
| 160 |
"condition_d_mean": 0.88,
|
| 161 |
"n": 50
|
| 162 |
}
|
eval/run_ablation.py
CHANGED
|
@@ -3,7 +3,7 @@ eval/run_ablation.py
|
|
| 3 |
Ablation study: compare Condition A (BM25), C (Dense RAG no emotion), D (Full EmpathRAG).
|
| 4 |
Computes Condition C as TRUE no-emotion-conditioning ablation:
|
| 5 |
- No emotion query rewriting (raw user_message goes to FAISS)
|
| 6 |
-
- No
|
| 7 |
Loads Conditions A and D from eval/wilcoxon_results.json.
|
| 8 |
"""
|
| 9 |
|
|
@@ -27,14 +27,16 @@ RESULTS_PATH = "eval/ablation_results.json"
|
|
| 27 |
def add_condition_c_methods(pipeline):
|
| 28 |
"""
|
| 29 |
Adds two methods to pipeline instance for Condition C ablation:
|
| 30 |
-
1. _retrieve_no_emotion:
|
| 31 |
-
2. run_condition_c: full pipeline run with raw user_message
|
| 32 |
"""
|
| 33 |
|
| 34 |
def _retrieve_no_emotion(self, query: str, emotion_label: int) -> list[str]:
|
| 35 |
"""
|
| 36 |
-
|
| 37 |
-
Returns top_k
|
|
|
|
|
|
|
| 38 |
GPU usage: ~440 MB during encode, freed before returning.
|
| 39 |
"""
|
| 40 |
# Move encoder to GPU for this call only
|
|
@@ -48,32 +50,30 @@ def add_condition_c_methods(pipeline):
|
|
| 48 |
self.encoder.to("cpu")
|
| 49 |
torch.cuda.empty_cache()
|
| 50 |
|
| 51 |
-
# Search
|
| 52 |
distances, ids = self.faiss_index.search(
|
| 53 |
-
q_vec.astype(np.float32), self.top_k
|
| 54 |
)
|
| 55 |
-
|
|
|
|
|
|
|
| 56 |
|
| 57 |
-
if not
|
| 58 |
return []
|
| 59 |
|
| 60 |
-
# Fetch
|
| 61 |
-
placeholders = ",".join("?" * len(
|
| 62 |
conn = sqlite3.connect(self.db_path)
|
| 63 |
rows = conn.execute(
|
| 64 |
-
f"SELECT id, text
|
| 65 |
-
|
| 66 |
-
candidate_ids,
|
| 67 |
).fetchall()
|
| 68 |
conn.close()
|
| 69 |
|
| 70 |
-
#
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
rows_sorted = sorted(rows, key=_score, reverse=True)[:self.top_k]
|
| 76 |
-
return [r[1] for r in rows_sorted]
|
| 77 |
|
| 78 |
def run_condition_c(self, user_message: str) -> dict:
|
| 79 |
"""
|
|
|
|
| 3 |
Ablation study: compare Condition A (BM25), C (Dense RAG no emotion), D (Full EmpathRAG).
|
| 4 |
Computes Condition C as TRUE no-emotion-conditioning ablation:
|
| 5 |
- No emotion query rewriting (raw user_message goes to FAISS)
|
| 6 |
+
- No re-ranking at all - pure FAISS distance order, no safety score, no emotion signal
|
| 7 |
Loads Conditions A and D from eval/wilcoxon_results.json.
|
| 8 |
"""
|
| 9 |
|
|
|
|
| 27 |
def add_condition_c_methods(pipeline):
|
| 28 |
"""
|
| 29 |
Adds two methods to pipeline instance for Condition C ablation:
|
| 30 |
+
1. _retrieve_no_emotion: pure FAISS distance order, no re-ranking, no emotion or safety score
|
| 31 |
+
2. run_condition_c: full pipeline run with raw user_message and no emotion conditioning
|
| 32 |
"""
|
| 33 |
|
| 34 |
def _retrieve_no_emotion(self, query: str, emotion_label: int) -> list[str]:
|
| 35 |
"""
|
| 36 |
+
Pure semantic retrieval - no emotion conditioning of any kind.
|
| 37 |
+
Returns top_k chunks in FAISS distance order (closest first).
|
| 38 |
+
No re-ranking, no safety score, no emotion bonus.
|
| 39 |
+
emotion_label parameter accepted but deliberately ignored.
|
| 40 |
GPU usage: ~440 MB during encode, freed before returning.
|
| 41 |
"""
|
| 42 |
# Move encoder to GPU for this call only
|
|
|
|
| 50 |
self.encoder.to("cpu")
|
| 51 |
torch.cuda.empty_cache()
|
| 52 |
|
| 53 |
+
# Search top_k directly - no need for top_k*3 since we are not re-ranking
|
| 54 |
distances, ids = self.faiss_index.search(
|
| 55 |
+
q_vec.astype(np.float32), self.top_k
|
| 56 |
)
|
| 57 |
+
# ids[0] is already sorted by L2 distance ascending (closest first)
|
| 58 |
+
# Filter out -1 padding (FAISS uses -1 for unfilled slots)
|
| 59 |
+
faiss_ordered_ids = [int(i) for i in ids[0] if i >= 0]
|
| 60 |
|
| 61 |
+
if not faiss_ordered_ids:
|
| 62 |
return []
|
| 63 |
|
| 64 |
+
# Fetch text from SQLite - NOTE: SQLite WHERE IN does NOT preserve input order
|
| 65 |
+
placeholders = ",".join("?" * len(faiss_ordered_ids))
|
| 66 |
conn = sqlite3.connect(self.db_path)
|
| 67 |
rows = conn.execute(
|
| 68 |
+
f"SELECT id, text FROM chunks WHERE id IN ({placeholders})",
|
| 69 |
+
faiss_ordered_ids,
|
|
|
|
| 70 |
).fetchall()
|
| 71 |
conn.close()
|
| 72 |
|
| 73 |
+
# Restore FAISS distance order using id->text map
|
| 74 |
+
id_to_text = {r[0]: r[1] for r in rows}
|
| 75 |
+
# Return in FAISS order, skip any ids not found in SQLite
|
| 76 |
+
return [id_to_text[i] for i in faiss_ordered_ids if i in id_to_text]
|
|
|
|
|
|
|
|
|
|
| 77 |
|
| 78 |
def run_condition_c(self, user_message: str) -> dict:
|
| 79 |
"""
|