Leon4gr45 commited on
Commit
220c4be
·
verified ·
1 Parent(s): 07c118d

Delete benchmarks/search/local_dense.py

Browse files
Files changed (1) hide show
  1. benchmarks/search/local_dense.py +0 -181
benchmarks/search/local_dense.py DELETED
@@ -1,181 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from typing import Any
4
-
5
- from search.dataset import split_corpus
6
- from search.metrics import aggregate_query_metrics, mrr, ndcg_at_k, recall_at_k
7
- from search.rank_pool import doc_texts
8
-
9
- DEFAULT_BASE = "sentence-transformers/all-MiniLM-L6-v2"
10
-
11
-
12
- def score_ranked_first_stage(
13
- ranked: list[str],
14
- query_row: dict[str, Any],
15
- *,
16
- ks: tuple[int, ...],
17
- ) -> dict[str, float]:
18
- gold = {str(item) for item in (query_row.get("gold_doc_ids") or [])}
19
- grades = {
20
- str(doc_id): float(gain)
21
- for doc_id, gain in (query_row.get("gold_grades") or {}).items()
22
- if float(gain or 0) > 0
23
- }
24
- if grades:
25
- gold |= set(grades)
26
- metrics = {f"recall@{cut}": recall_at_k(ranked, gold, cut) for cut in ks}
27
- ndcg_ks = tuple(dict.fromkeys((*ks, 10, 20)))
28
- for cut in ndcg_ks:
29
- metrics[f"ndcg@{cut}"] = ndcg_at_k(ranked, gold, cut, grades=grades or None)
30
- metrics["ndcg"] = ndcg_at_k(ranked, gold, max(len(ranked), 1), grades=grades or None)
31
- metrics["mrr"] = mrr(ranked, gold)
32
- return metrics
33
-
34
-
35
- def hard_negative_texts_from_eval(
36
- eval_result: dict[str, Any],
37
- texts: dict[str, str],
38
- queries: list[dict[str, Any]],
39
- ) -> list[str]:
40
- by_qid = {str(query.get("qid") or ""): query for query in queries}
41
- bank: list[str] = []
42
- seen: set[str] = set()
43
- for row in eval_result.get("queries") or []:
44
- qid = str(row.get("qid") or "")
45
- source = by_qid.get(qid) or row
46
- gold = {str(item) for item in (source.get("gold_doc_ids") or [])}
47
- grades = source.get("gold_grades") or {}
48
- if isinstance(grades, dict):
49
- gold |= {
50
- str(doc_id)
51
- for doc_id, gain in grades.items()
52
- if float(gain or 0) > 0
53
- }
54
- for doc_id in row.get("hit_ids") or []:
55
- key = str(doc_id)
56
- if key in gold or key in seen:
57
- continue
58
- text = texts.get(key) or ""
59
- if not text:
60
- continue
61
- seen.add(key)
62
- bank.append(text)
63
- return bank
64
-
65
-
66
- def retrieve_dense(
67
- model: Any,
68
- queries: list[dict[str, Any]],
69
- docs: list[dict[str, Any]],
70
- *,
71
- k: int,
72
- batch_size: int = 32,
73
- ) -> tuple[dict[str, list[str]], float]:
74
- import time
75
-
76
- import numpy as np
77
-
78
- texts = doc_texts(docs)
79
- doc_ids = [str(doc.get("doc_id") or "") for doc in docs if doc.get("doc_id")]
80
- doc_passages = [texts.get(doc_id) or doc_id for doc_id in doc_ids]
81
- start = time.perf_counter()
82
- doc_emb = model.encode(
83
- doc_passages,
84
- batch_size=batch_size,
85
- convert_to_numpy=True,
86
- normalize_embeddings=True,
87
- show_progress_bar=False,
88
- )
89
- q_texts = [str(query.get("query") or "") for query in queries]
90
- q_emb = model.encode(
91
- q_texts,
92
- batch_size=batch_size,
93
- convert_to_numpy=True,
94
- normalize_embeddings=True,
95
- show_progress_bar=False,
96
- )
97
- elapsed_ms = (time.perf_counter() - start) * 1000.0
98
- scores = np.matmul(q_emb, doc_emb.T)
99
- ranked_by_qid: dict[str, list[str]] = {}
100
- cut = max(1, min(int(k), len(doc_ids)))
101
- for index, query in enumerate(queries):
102
- order = np.argsort(-scores[index])[:cut]
103
- qid = str(query.get("qid") or "")
104
- ranked_by_qid[qid] = [doc_ids[int(pos)] for pos in order]
105
- return ranked_by_qid, elapsed_ms
106
-
107
-
108
- def evaluate_dense(
109
- ranked_by_qid: dict[str, list[str]],
110
- queries: list[dict[str, Any]],
111
- *,
112
- ks: tuple[int, ...],
113
- encode_ms: float,
114
- ) -> tuple[dict[str, Any], list[dict[str, Any]]]:
115
- per_query: list[dict[str, Any]] = []
116
- per_q_ms = encode_ms / max(1, len(queries))
117
- for query in queries:
118
- qid = str(query.get("qid") or "")
119
- ranked = ranked_by_qid.get(qid) or []
120
- metrics = score_ranked_first_stage(ranked, query, ks=ks)
121
- per_query.append(
122
- {
123
- "qid": qid,
124
- "query": query.get("query"),
125
- "slice": query.get("slice") or "unspecified",
126
- "gold_doc_ids": list(query.get("gold_doc_ids") or []),
127
- "gold_grades": query.get("gold_grades") or {},
128
- "hit_ids": ranked,
129
- "metrics": metrics,
130
- "n_hits": len(ranked),
131
- "retrieve_ms": per_q_ms,
132
- "embed_ms": per_q_ms,
133
- "client_wall_ms": per_q_ms,
134
- }
135
- )
136
- metrics = aggregate_query_metrics(per_query, ks=ks) if per_query else {}
137
- return metrics, per_query
138
-
139
-
140
- def run_local_dense(
141
- rows: list[dict[str, Any]],
142
- *,
143
- model_name: str,
144
- dataset_name: str,
145
- k: int = 50,
146
- ks: tuple[int, ...] = (5, 10, 20, 50),
147
- brain_id: str | None = None,
148
- protocol: str | None = None,
149
- ) -> dict[str, Any]:
150
- from sentence_transformers import SentenceTransformer
151
-
152
- docs, queries = split_corpus(rows)
153
- model = SentenceTransformer(model_name)
154
- ranked_by_qid, encode_ms = retrieve_dense(model, queries, docs, k=k)
155
- metrics, per_query = evaluate_dense(
156
- ranked_by_qid, queries, ks=ks, encode_ms=encode_ms
157
- )
158
- return {
159
- "status": "ok",
160
- "brain_id": brain_id or "harness-local",
161
- "dataset": dataset_name,
162
- "fusion": "none",
163
- "rerank": "none",
164
- "channels": ["harness-dense"],
165
- "rank_pool": False,
166
- "skip_enrichment": True,
167
- "k": k,
168
- "ks": list(ks),
169
- "n_docs": len(docs),
170
- "n_queries": len(queries),
171
- "n_docs_mapped": len(docs),
172
- "ce_model": model_name,
173
- "protocol": protocol
174
- or (
175
- "local dual-encoder over search_esci_74.jsonl; not BrainAPI embeddings; "
176
- "not Reddy 0.857"
177
- ),
178
- "metrics": metrics,
179
- "queries": per_query,
180
- "ingest": {"status": "completed", "n_docs": 0, "tasks": [], "reused": True},
181
- }