sable-sphynx 0.7.0.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sable_sphynx-0.7.0.dev0.dist-info/METADATA +152 -0
- sable_sphynx-0.7.0.dev0.dist-info/RECORD +174 -0
- sable_sphynx-0.7.0.dev0.dist-info/WHEEL +5 -0
- sable_sphynx-0.7.0.dev0.dist-info/top_level.txt +1 -0
- sphynx/__init__.py +469 -0
- sphynx/__init__.pyi +376 -0
- sphynx/_analytical_client.py +77 -0
- sphynx/_analytical_values.py +252 -0
- sphynx/_audit_client.py +173 -0
- sphynx/_comparison_adapters.py +113 -0
- sphynx/_componentized_full_rag.py +34 -0
- sphynx/_composed_pipeline.py +109 -0
- sphynx/_full_rag_grading.py +218 -0
- sphynx/_full_rag_trace.py +221 -0
- sphynx/_local_eval.py +268 -0
- sphynx/_pipeline_core.py +243 -0
- sphynx/_pr_client.py +237 -0
- sphynx/_rag_diagnostics_calibration.py +285 -0
- sphynx/_rag_diagnostics_catalog.py +39 -0
- sphynx/_rag_diagnostics_common.py +26 -0
- sphynx/_rag_diagnostics_contracts.py +186 -0
- sphynx/_rag_diagnostics_engine.py +243 -0
- sphynx/_rag_diagnostics_importers.py +242 -0
- sphynx/_rag_diagnostics_ranking.py +81 -0
- sphynx/_rag_diagnostics_semantic.py +325 -0
- sphynx/_rag_ranking.py +149 -0
- sphynx/_speech_benchmark_scoring.py +140 -0
- sphynx/_speech_benchmark_sources.py +275 -0
- sphynx/_speech_complete_scoring.py +218 -0
- sphynx/_speech_complete_source.py +118 -0
- sphynx/_speech_kido.py +294 -0
- sphynx/_speech_scoring.py +77 -0
- sphynx/_track_capture.py +213 -0
- sphynx/analytical_views.py +515 -0
- sphynx/assessment_contracts.py +378 -0
- sphynx/assessment_selection.py +57 -0
- sphynx/audit_access.py +245 -0
- sphynx/audit_contracts.py +204 -0
- sphynx/audit_requests.py +180 -0
- sphynx/authoring.py +188 -0
- sphynx/benchmarks.py +568 -0
- sphynx/candidates.py +62 -0
- sphynx/catalog.py +272 -0
- sphynx/chunking.py +372 -0
- sphynx/clickhouse_reader.py +169 -0
- sphynx/client.py +486 -0
- sphynx/comparison_core.py +149 -0
- sphynx/comparison_views.py +223 -0
- sphynx/components.py +1661 -0
- sphynx/contracts.py +514 -0
- sphynx/customer_rerank.py +299 -0
- sphynx/customer_retrieval.py +146 -0
- sphynx/data/benchmark-releases.v1.json +164 -0
- sphynx/data/public-benchmark-release.v1.json +354 -0
- sphynx/data/rag-diagnostics-synthetic.v1.json +6982 -0
- sphynx/data/rag-paper-references.v1.json +176 -0
- sphynx/data/rag-paper-schemas.v1.json +1069 -0
- sphynx/data/rag-rerank-v1.json +507 -0
- sphynx/dataset_catalog_data.py +1214 -0
- sphynx/dataset_readiness.py +138 -0
- sphynx/dataset_v3.py +999 -0
- sphynx/demo.py +130 -0
- sphynx/demo_candidates/__init__.py +1 -0
- sphynx/demo_candidates/dense.py +11 -0
- sphynx/demo_candidates/lexical.py +21 -0
- sphynx/diagnostics.py +207 -0
- sphynx/documentation.py +737 -0
- sphynx/documentation_candidate.py +939 -0
- sphynx/evals.py +538 -0
- sphynx/evaluation_protocols.py +124 -0
- sphynx/evaluator_bindings.py +370 -0
- sphynx/evidence.py +352 -0
- sphynx/execution_capabilities.py +109 -0
- sphynx/fast_search.py +285 -0
- sphynx/full_rag.py +341 -0
- sphynx/hosted/__init__.py +18 -0
- sphynx/hosted/benchmark_intake.py +218 -0
- sphynx/hosted/contracts.py +361 -0
- sphynx/hosted/model_admission.py +130 -0
- sphynx/hosted/model_artifacts.py +298 -0
- sphynx/hosted/model_contracts.py +63 -0
- sphynx/hosted/model_gcs.py +181 -0
- sphynx/hosted/model_history.py +84 -0
- sphynx/hosted/model_session.py +233 -0
- sphynx/hosted/public_suite.py +74 -0
- sphynx/hosted/registry.py +97 -0
- sphynx/hosted/revisions.py +126 -0
- sphynx/hosted/sandbox.py +105 -0
- sphynx/hosted/submission.py +287 -0
- sphynx/hosted_workflow.py +451 -0
- sphynx/http_transport.py +86 -0
- sphynx/integrated_rag.py +352 -0
- sphynx/integrated_workflow.py +552 -0
- sphynx/integration_contracts.py +474 -0
- sphynx/invocation.py +791 -0
- sphynx/invocation_candidates.py +392 -0
- sphynx/invocation_catalog_data.py +40 -0
- sphynx/learned_catalog_data.py +30 -0
- sphynx/learned_rerank.py +267 -0
- sphynx/legacy_full_rag.py +67 -0
- sphynx/lifecycle.py +885 -0
- sphynx/lifecycle_workflow.py +490 -0
- sphynx/metric_views.py +474 -0
- sphynx/metrics.py +282 -0
- sphynx/model_adapters.py +438 -0
- sphynx/model_catalog_data.py +30 -0
- sphynx/official_benchmarks.py +385 -0
- sphynx/packs.py +258 -0
- sphynx/pipeline.py +313 -0
- sphynx/pipeline_workflow.py +551 -0
- sphynx/pr_evaluations.py +560 -0
- sphynx/progress.py +89 -0
- sphynx/public_bundle.py +173 -0
- sphynx/public_eval.py +62 -0
- sphynx/public_rerank.py +355 -0
- sphynx/py.typed +0 -0
- sphynx/pytest_plugin.py +62 -0
- sphynx/question_robustness.py +437 -0
- sphynx/rag.py +329 -0
- sphynx/rag_diagnostics.py +309 -0
- sphynx/rag_papers/__init__.py +29 -0
- sphynx/rag_papers/__main__.py +45 -0
- sphynx/rag_papers/candidates.py +19 -0
- sphynx/rag_papers/contracts.py +282 -0
- sphynx/rag_papers/datasets.py +291 -0
- sphynx/rag_papers/experiments.py +116 -0
- sphynx/rag_papers/judges.py +308 -0
- sphynx/rag_papers/registry.py +33 -0
- sphynx/rag_papers/runner.py +176 -0
- sphynx/rag_papers/sable.py +135 -0
- sphynx/rag_papers/schemas.py +12 -0
- sphynx/rag_papers/scoring.py +249 -0
- sphynx/rag_papers/semantic.py +288 -0
- sphynx/rag_papers/trec.py +80 -0
- sphynx/recorded_scores.py +352 -0
- sphynx/records.py +124 -0
- sphynx/reflex_traces.py +193 -0
- sphynx/report_rendering.py +71 -0
- sphynx/rerank_family_contracts.py +150 -0
- sphynx/rerank_workflow.py +424 -0
- sphynx/research_candidate.py +190 -0
- sphynx/results.py +852 -0
- sphynx/retrieval.py +750 -0
- sphynx/retrieval_candidates.py +295 -0
- sphynx/retrieval_catalog_data.py +19 -0
- sphynx/retrieval_recordings.py +125 -0
- sphynx/reviewer_audit.py +266 -0
- sphynx/routing_policies.py +375 -0
- sphynx/runner.py +544 -0
- sphynx/sable_rerank.py +489 -0
- sphynx/score_reliability.py +393 -0
- sphynx/speech_benchmarks.py +204 -0
- sphynx/speech_campaigns.py +378 -0
- sphynx/speech_complete.py +236 -0
- sphynx/speech_contracts.py +225 -0
- sphynx/speech_evidence.py +429 -0
- sphynx/speech_listening.py +115 -0
- sphynx/speech_multilingual.py +71 -0
- sphynx/speech_tts.py +479 -0
- sphynx/sql/001_sync_v1.sql +30 -0
- sphynx/stage_contracts.py +199 -0
- sphynx/statistical_catalog_data.py +53 -0
- sphynx/statistical_rerank.py +232 -0
- sphynx/sync.py +797 -0
- sphynx/workbench.py +378 -0
- sphynx/workbench_catalog_data.py +13 -0
- sphynx/workbench_tracks.py +78 -0
- sphynx/workflow_async.py +197 -0
- sphynx/workflow_contracts.py +594 -0
- sphynx/workflow_decisions.py +211 -0
- sphynx/workflow_defaults.py +16 -0
- sphynx/workflow_extensions.py +212 -0
- sphynx/workflow_registry.py +513 -0
- sphynx/workflows.py +792 -0
sphynx/public_bundle.py
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"""Prepare and verify a separate public-only reranking data bundle.
|
|
2
|
+
|
|
3
|
+
The SDK wheel contains no benchmark texts. A release owner must authorize data
|
|
4
|
+
distribution separately. Hashes bind bytes; they are not a signature or proof
|
|
5
|
+
that an arbitrary supplied source has redistribution permission.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from dataclasses import dataclass
|
|
10
|
+
import hashlib
|
|
11
|
+
import json
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
import re
|
|
14
|
+
|
|
15
|
+
from ._local_eval import read_json, require
|
|
16
|
+
from .public_rerank import DOMAINS, PUBLIC_POOL_SHA256, load_public_rerank_pack
|
|
17
|
+
|
|
18
|
+
SCHEMA = "sphynx.public-rerank.bundle.v1"
|
|
19
|
+
FILES = ("frozen-pools.json", "DATA_SOURCES.md")
|
|
20
|
+
ROW_FIELDS = ("dataset", "split", "query_id", "task_id", "query")
|
|
21
|
+
PASSAGE_FIELDS = ("candidate_id", "document_id", "input", "first_stage_rank", "first_stage_score", "grade")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _hash(raw: bytes) -> str:
|
|
25
|
+
return hashlib.sha256(raw).hexdigest()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _json(value: object) -> bytes:
|
|
29
|
+
return (json.dumps(value, sort_keys=True, indent=2, ensure_ascii=False, allow_nan=False) + "\n").encode("utf-8")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass(frozen=True)
|
|
33
|
+
class PublicRerankBundle:
|
|
34
|
+
path: Path
|
|
35
|
+
manifest_sha256: str
|
|
36
|
+
dataset_sha256: str
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def dataset_path(self) -> Path:
|
|
40
|
+
return self.path / "frozen-pools.json"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def prepare_public_rerank_bundle(source: str | Path, output_dir: str | Path, *,
|
|
44
|
+
expected_source_sha256: str = PUBLIC_POOL_SHA256) -> PublicRerankBundle:
|
|
45
|
+
"""Export only six public domains and explicit grading fields to a new folder.
|
|
46
|
+
|
|
47
|
+
Default input is the pinned research source. An explicit different hash is
|
|
48
|
+
a caller-approved custom source, not an official Sphynx benchmark release.
|
|
49
|
+
No network calls, cloud uploads or model execution occur.
|
|
50
|
+
"""
|
|
51
|
+
source = Path(source).expanduser().resolve(strict=True)
|
|
52
|
+
source_raw = source.read_bytes()
|
|
53
|
+
expected = expected_source_sha256.removeprefix("sha256:")
|
|
54
|
+
require(_hash(source_raw) == expected, "public source SHA-256 differs")
|
|
55
|
+
packs = [load_public_rerank_pack(source, split=split, expected_sha256=expected)
|
|
56
|
+
for split in ("development", "confirmation")]
|
|
57
|
+
rows = []
|
|
58
|
+
for pack in packs:
|
|
59
|
+
for row in pack.rows:
|
|
60
|
+
rows.append({**{key: row[key] for key in ROW_FIELDS},
|
|
61
|
+
"candidates": [{key: c[key] for key in PASSAGE_FIELDS} for c in row["candidates"]]})
|
|
62
|
+
payload = {"schema_version": "expanded-reranker.frozen-pools.v1", "candidate_depth": 15,
|
|
63
|
+
"first_stage": "bm25_okapi_public_screen", "queries": rows}
|
|
64
|
+
notices = ["# Public reranking data sources", "",
|
|
65
|
+
"This is a frozen excerpt of six BEIR datasets, not the full BEIR benchmark.",
|
|
66
|
+
"Keep this notice with the data. The SDK license does not license third-party data.",
|
|
67
|
+
"BEIR's dataset disclaimer: https://github.com/beir-cellar/beir#-disclaimer", "",
|
|
68
|
+
"Each BEIR-maintained card below declares CC BY-SA 4.0. Check the original",
|
|
69
|
+
"dataset terms and attribution before use or redistribution. This notice records",
|
|
70
|
+
"the published declaration; it is not a legal clearance of source content.",
|
|
71
|
+
"License text: https://creativecommons.org/licenses/by-sa/4.0/", ""]
|
|
72
|
+
notices.extend(f"- {domain}: https://huggingface.co/datasets/BeIR/{domain}" for domain in DOMAINS)
|
|
73
|
+
notices.extend(["", "Changes: select 30 queries per domain (15 per split), preserve the frozen",
|
|
74
|
+
"15-passage BM25 pools and native qrels, remove duplicate title/text fields",
|
|
75
|
+
"and unrelated metadata. Seven internal illustrative cases are excluded.",
|
|
76
|
+
"Both splits were previously opened and support exploratory comparisons.",
|
|
77
|
+
"Candidate inputs omit ground truths. Local owners can read public qrels.", ""])
|
|
78
|
+
contents = {"frozen-pools.json": _json(payload), "DATA_SOURCES.md": "\n".join(notices).encode("utf-8")}
|
|
79
|
+
manifest = {"schema_version": SCHEMA, "pack_id": "rag.rerank.beir.v1", "query_count": 180,
|
|
80
|
+
"split_counts": {"development": 90, "confirmation": 90}, "domains": list(DOMAINS),
|
|
81
|
+
"candidate_depth": 15, "source_sha256": expected,
|
|
82
|
+
"source_authority": "pinned_research_source" if expected == PUBLIC_POOL_SHA256 else "caller_approved_custom",
|
|
83
|
+
"data_distribution": "separate_owner_authorization_required",
|
|
84
|
+
"files": {name: {"sha256": _hash(raw), "size_bytes": len(raw)} for name, raw in contents.items()}}
|
|
85
|
+
root = Path(output_dir).expanduser().absolute()
|
|
86
|
+
require(not root.exists() and not root.is_symlink(), "bundle output must be a new folder")
|
|
87
|
+
root.mkdir(parents=True, exist_ok=False)
|
|
88
|
+
for name, raw in contents.items():
|
|
89
|
+
with (root / name).open("xb") as stream:
|
|
90
|
+
stream.write(raw)
|
|
91
|
+
raw = _json(manifest)
|
|
92
|
+
with (root / "manifest.json").open("xb") as stream:
|
|
93
|
+
stream.write(raw)
|
|
94
|
+
return load_public_rerank_bundle(root, expected_manifest_sha256=_hash(raw))
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def load_public_rerank_bundle(data_dir: str | Path, *, expected_manifest_sha256: str) -> PublicRerankBundle:
|
|
98
|
+
"""Verify an owner-supplied manifest pin before loading any experiment data.
|
|
99
|
+
|
|
100
|
+
Get the pin from your release owner through a trusted channel. Do not replace
|
|
101
|
+
it with a freshly computed hash when verification fails.
|
|
102
|
+
"""
|
|
103
|
+
expected = expected_manifest_sha256.removeprefix("sha256:")
|
|
104
|
+
require(re.fullmatch(r"[0-9a-f]{64}", expected) is not None, "manifest pin must be a lowercase SHA-256")
|
|
105
|
+
root = Path(data_dir).expanduser().resolve(strict=True)
|
|
106
|
+
require(root.is_dir(), "bundle must be a directory")
|
|
107
|
+
paths = {path.name for path in root.iterdir()}
|
|
108
|
+
require(paths == {*FILES, "manifest.json"}, "bundle inventory must contain exactly the approved three files")
|
|
109
|
+
for name in paths:
|
|
110
|
+
path = root / name
|
|
111
|
+
require(path.is_file() and not path.is_symlink() and path.resolve().parent == root, "unsafe bundle file")
|
|
112
|
+
raw = (root / "manifest.json").read_bytes()
|
|
113
|
+
require(_hash(raw) == expected, "bundle manifest SHA-256 differs")
|
|
114
|
+
manifest = read_json(root / "manifest.json")
|
|
115
|
+
require(manifest.get("schema_version") == SCHEMA and manifest.get("pack_id") == "rag.rerank.beir.v1"
|
|
116
|
+
and manifest.get("query_count") == 180 and manifest.get("domains") == list(DOMAINS)
|
|
117
|
+
and manifest.get("split_counts") == {"development": 90, "confirmation": 90}
|
|
118
|
+
and manifest.get("candidate_depth") == 15, "unsupported bundle identity")
|
|
119
|
+
require(isinstance(manifest.get("files"), dict) and set(manifest["files"]) == set(FILES), "invalid bundle inventory")
|
|
120
|
+
for name in FILES:
|
|
121
|
+
raw = (root / name).read_bytes()
|
|
122
|
+
record = manifest["files"][name]
|
|
123
|
+
require(isinstance(record, dict) and set(record) == {"sha256", "size_bytes"}
|
|
124
|
+
and _hash(raw) == record["sha256"] and len(raw) == record["size_bytes"], "bundle file differs: " + name)
|
|
125
|
+
dataset = root / "frozen-pools.json"
|
|
126
|
+
data = read_json(dataset)
|
|
127
|
+
require(set(data) == {"schema_version", "candidate_depth", "first_stage", "queries"}, "non-public bundle metadata")
|
|
128
|
+
require(isinstance(data["queries"], list) and len(data["queries"]) == 180, "bundle must contain 180 public cases")
|
|
129
|
+
for row in data["queries"]:
|
|
130
|
+
require(isinstance(row, dict) and set(row) == {*ROW_FIELDS, "candidates"}
|
|
131
|
+
and row.get("dataset") in DOMAINS, "non-public bundle row")
|
|
132
|
+
require(isinstance(row["candidates"], list) and all(isinstance(c, dict) and set(c) == set(PASSAGE_FIELDS)
|
|
133
|
+
for c in row["candidates"]), "non-public passage metadata")
|
|
134
|
+
pin = manifest["files"]["frozen-pools.json"]["sha256"]
|
|
135
|
+
for split in ("development", "confirmation"):
|
|
136
|
+
load_public_rerank_pack(dataset, split=split, expected_sha256=pin)
|
|
137
|
+
return PublicRerankBundle(root, expected, pin)
|
|
138
|
+
|
|
139
|
+
RELEASE_BUNDLE_SCHEMA = "sphynx.public-rerank.release-bundle.v1"
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def load_public_release_bundle(data_dir: str | Path, *, release_id: str,
|
|
143
|
+
expected_manifest_sha256: str) -> PublicRerankBundle:
|
|
144
|
+
"""Verify a separate revised pool bundle against a trusted manifest pin.
|
|
145
|
+
|
|
146
|
+
An owner supplies the exact pinned source bytes and its attribution notice.
|
|
147
|
+
The SDK does not distribute the source dataset or infer distribution rights.
|
|
148
|
+
"""
|
|
149
|
+
from .public_rerank import load_public_pool_release
|
|
150
|
+
expected = expected_manifest_sha256.removeprefix("sha256:")
|
|
151
|
+
require(re.fullmatch(r"[0-9a-f]{64}", expected) is not None, "manifest pin must be a lowercase SHA-256")
|
|
152
|
+
root = Path(data_dir).expanduser().resolve(strict=True)
|
|
153
|
+
require(root.is_dir() and {p.name for p in root.iterdir()} == {*FILES, "manifest.json"},
|
|
154
|
+
"release bundle inventory must contain exactly three approved files")
|
|
155
|
+
for name in (*FILES, "manifest.json"):
|
|
156
|
+
path = root / name
|
|
157
|
+
require(path.is_file() and not path.is_symlink() and path.resolve().parent == root, "unsafe release bundle file")
|
|
158
|
+
raw = (root / "manifest.json").read_bytes()
|
|
159
|
+
require(_hash(raw) == expected, "release bundle manifest SHA-256 differs")
|
|
160
|
+
manifest = read_json(root / "manifest.json")
|
|
161
|
+
require(set(manifest) == {"schema_version", "release_id", "dataset_id", "files"}
|
|
162
|
+
and manifest.get("schema_version") == RELEASE_BUNDLE_SCHEMA
|
|
163
|
+
and manifest.get("release_id") == release_id, "release bundle identity differs")
|
|
164
|
+
records = manifest.get("files")
|
|
165
|
+
require(isinstance(records, dict) and set(records) == set(FILES), "invalid release bundle inventory")
|
|
166
|
+
for name in FILES:
|
|
167
|
+
raw = (root / name).read_bytes(); record = records[name]
|
|
168
|
+
require(isinstance(record, dict) and set(record) == {"sha256", "size_bytes"}
|
|
169
|
+
and type(record["size_bytes"]) is int and record["size_bytes"] == len(raw)
|
|
170
|
+
and record["sha256"] == _hash(raw), "release bundle file differs: " + name)
|
|
171
|
+
pack = load_public_pool_release(root / "frozen-pools.json", release_id=release_id)
|
|
172
|
+
require(manifest["dataset_id"] == pack.identity["dataset_id"], "release bundle dataset identity differs")
|
|
173
|
+
return PublicRerankBundle(root, expected, pack.identity["dataset_digest"].removeprefix("sha256:"))
|
sphynx/public_eval.py
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""Public hosted evaluation metadata; no corpus, labels, runner or cloud SDK."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from .evals import ArtifactBinding, ArtifactReference, EvaluationDefinition
|
|
4
|
+
|
|
5
|
+
EVALUATION_ID = "rag.rerank.public.v1"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
BENCHMARK_REF = "beir.scifact.bm25-top15.dev15@1.0.0"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
LABEL_REF = "beir.scifact.native-qrels.dev15@1.0.0"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
MANIFEST_DIGEST = "sha256:9335ce0aaa3e53942c8cba2deff126af5ad93319d383cb4eb70fceb443990835"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
BENCHMARK_DIGEST = "sha256:fda436c6e006233a4f53eaadf8633b05111f0c1c21b2b099972c518e02aa9971"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
LABEL_DIGEST = "sha256:18b60b759c05ac9a8d5ac14477ff509e67ec9c38ffd760c20b0b0f54313ad198"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
GRADER_RELEASE = "rag.rerank.scifact.dev15.grader.v1"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
METRIC_RELEASE = "rag.rerank.beir.metric.v1"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
INPUT_DIGEST = "sha256:3a80c8b09cb26c96c7551d6b194d8195fc848ea7a0491c8f014a30e505bf5140"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _object(properties, *, required=(), default=None):
|
|
33
|
+
value = {"type": "object", "properties": properties, "required": list(required), "additionalProperties": False}
|
|
34
|
+
if default is not None:
|
|
35
|
+
value["default"] = default
|
|
36
|
+
return value
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def public_definition():
|
|
40
|
+
"""Explicit benchmark selection is required; protocol choices are fixed."""
|
|
41
|
+
schema = _object({
|
|
42
|
+
"benchmark": {"type": "string", "enum": [BENCHMARK_REF]},
|
|
43
|
+
"label_release": {"type": "string", "enum": [LABEL_REF], "default": LABEL_REF},
|
|
44
|
+
"split": {"type": "string", "enum": ["development"], "default": "development"},
|
|
45
|
+
"top_k": {"type": "integer", "enum": [5], "default": 5},
|
|
46
|
+
"relevance_threshold": {"type": "integer", "enum": [1], "default": 1},
|
|
47
|
+
"runtime": _object({"trials": {"type": "integer", "enum": [1], "default": 1},
|
|
48
|
+
"per_case_timeout_seconds": {"type": "integer", "enum": [30], "default": 30}}, default={}),
|
|
49
|
+
"reporting": _object({"format": {"type": "string", "enum": ["markdown", "json"], "default": "markdown"}}, default={}),
|
|
50
|
+
}, required=("benchmark",))
|
|
51
|
+
return EvaluationDefinition(EVALUATION_ID, "v1", "SciFact development reranking on fixed passage pools", "runnable",
|
|
52
|
+
"sphynx.rag.rerank.v1", {"adapter": "hosted-public-rerank.v1", "grader": GRADER_RELEASE, "metrics": METRIC_RELEASE, "capture_policy": "public-rerank.streams.v1"},
|
|
53
|
+
schema, ("/benchmark", "/label_release", "/split", "/top_k", "/relevance_threshold", "/runtime"),
|
|
54
|
+
("/runtime",), (ArtifactBinding("/benchmark", "benchmark_release"), ArtifactBinding("/label_release", "label_release")),
|
|
55
|
+
("ndcg_at_5", "hit_at_5", "mrr_at_5", "pool_oracle_coverage", "runner_latency_ms", "valid_response_coverage", "candidate_failure_rate"))
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def public_artifacts():
|
|
59
|
+
return (ArtifactReference(BENCHMARK_REF, "benchmark_release", "1.0.0", BENCHMARK_DIGEST, public=True),
|
|
60
|
+
ArtifactReference(LABEL_REF, "label_release", "1.0.0", LABEL_DIGEST, public=True))
|
|
61
|
+
|
|
62
|
+
|
sphynx/public_rerank.py
ADDED
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
"""Versioned six-domain public BEIR frozen-pool reranking development pack."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
import math
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from ._local_eval import (LocalEvaluationRef, LocalRunRef, LocalScorecard, capture, compare_scorecards,
|
|
10
|
+
digest, identity, metric, percentile, read_json, report_evaluation, require,
|
|
11
|
+
save_evaluation, text, verified_capture)
|
|
12
|
+
from .contracts import (CandidateSpec, INTERFACE_VERSION, REQUEST_SCHEMA_VERSION,
|
|
13
|
+
validate_candidate_request, validate_candidate_response, ranked_candidate_ids)
|
|
14
|
+
from .invocation import _execute_candidate
|
|
15
|
+
|
|
16
|
+
PUBLIC_RERANK_PACK_ID = "rag.rerank.beir.v1"
|
|
17
|
+
PUBLIC_POOL_SHA256 = "89b713acfd071cafd65fc40581d721399aeee79a132c87e20b03a2b6c401941e"
|
|
18
|
+
DOMAINS = ("scifact", "nfcorpus", "fiqa", "arguana", "trec-covid", "scidocs")
|
|
19
|
+
METRIC_RELEASE = "rag.rerank.beir.metric.v1"
|
|
20
|
+
GRADER_RELEASE = "rag.rerank.beir.grader.v1"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class PublicRerankPack:
|
|
24
|
+
"""Owner-authorized external data; native public qrels remain grader-only."""
|
|
25
|
+
|
|
26
|
+
def __init__(self, source_digest: str, split: str, rows: list[dict[str, Any]]):
|
|
27
|
+
self.rows = rows
|
|
28
|
+
self.split = split
|
|
29
|
+
self.identity = {"pack_id": PUBLIC_RERANK_PACK_ID, "pack_release": "v1.external",
|
|
30
|
+
"dataset_digest": source_digest, "cohort_digest": identity(rows), "split": split,
|
|
31
|
+
"domains": list(DOMAINS), "candidate_depth": 15,
|
|
32
|
+
"first_stage": "bm25_okapi_public_screen", "relevance_threshold": 1,
|
|
33
|
+
"label_status": "public_qrels", "development_only": True,
|
|
34
|
+
"confirmation_status": "previously_opened_exploratory"}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def load_public_rerank_pack(dataset_path: str | Path, *, split: str = "development",
|
|
38
|
+
expected_sha256: str = PUBLIC_POOL_SHA256) -> PublicRerankPack:
|
|
39
|
+
"""Select exactly one original split; exclude every Sable illustrative fixture."""
|
|
40
|
+
require(split in ("development", "confirmation"), "split must be development or confirmation")
|
|
41
|
+
source = Path(dataset_path).expanduser().resolve(strict=True)
|
|
42
|
+
source_digest = digest(source.read_bytes())
|
|
43
|
+
require(source_digest == "sha256:" + expected_sha256.removeprefix("sha256:"), "public dataset SHA-256 differs")
|
|
44
|
+
data = read_json(source)
|
|
45
|
+
require(data.get("schema_version") == "expanded-reranker.frozen-pools.v1"
|
|
46
|
+
and data.get("candidate_depth") == 15 and data.get("first_stage") == "bm25_okapi_public_screen",
|
|
47
|
+
"unsupported public pool source or first-stage policy")
|
|
48
|
+
require(isinstance(data.get("queries"), list), "public queries must be a list")
|
|
49
|
+
selected = []
|
|
50
|
+
ids = set()
|
|
51
|
+
for item in data["queries"]:
|
|
52
|
+
if item.get("dataset") not in DOMAINS:
|
|
53
|
+
continue
|
|
54
|
+
require(item.get("split") in ("development", "confirmation"), "unexpected public split")
|
|
55
|
+
key = (item["dataset"], text(item.get("query_id"), "query_id"))
|
|
56
|
+
require(key not in ids, "public query must appear in only one split")
|
|
57
|
+
ids.add(key)
|
|
58
|
+
text(item.get("query"), "query")
|
|
59
|
+
text(item.get("task_id"), "task_id")
|
|
60
|
+
candidates = item.get("candidates")
|
|
61
|
+
require(isinstance(candidates, list) and len(candidates) == 15, "public pools must have depth 15")
|
|
62
|
+
seen = set()
|
|
63
|
+
documents = set()
|
|
64
|
+
for index, candidate in enumerate(candidates):
|
|
65
|
+
cid = text(candidate.get("candidate_id"), "candidate_id")
|
|
66
|
+
document = text(candidate.get("document_id"), "document_id")
|
|
67
|
+
require(cid not in seen and document not in documents, "duplicate public pool candidate or document")
|
|
68
|
+
seen.add(cid)
|
|
69
|
+
documents.add(document)
|
|
70
|
+
text(candidate.get("input"), "candidate.input")
|
|
71
|
+
require(type(candidate.get("first_stage_rank")) is int and candidate["first_stage_rank"] == index + 1,
|
|
72
|
+
"public first-stage ranks must equal frozen pool order")
|
|
73
|
+
score = candidate.get("first_stage_score")
|
|
74
|
+
require(type(score) in (int, float) and math.isfinite(score), "invalid public first-stage score")
|
|
75
|
+
require(type(candidate.get("grade")) is int and 0 <= candidate["grade"] <= 3,
|
|
76
|
+
"public relevance grades must retain native nonnegative qrels")
|
|
77
|
+
if item["split"] == split:
|
|
78
|
+
selected.append(item)
|
|
79
|
+
require(all(sum(row["dataset"] == domain for row in selected) == 15 for domain in DOMAINS),
|
|
80
|
+
"public split must contain the original 15 queries in each of six domains")
|
|
81
|
+
require(len({row["task_id"] for row in selected}) == len(selected), "public task IDs must be unique")
|
|
82
|
+
return PublicRerankPack(source_digest, split, selected)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def build_public_rerank_request(pack: PublicRerankPack, case_id: str) -> dict[str, Any]:
|
|
86
|
+
row = next((row for row in pack.rows if row["task_id"] == case_id), None)
|
|
87
|
+
require(row is not None, "case does not belong to public reranking split")
|
|
88
|
+
pool = row["candidates"]
|
|
89
|
+
if "dataset_id" in pack.identity:
|
|
90
|
+
# The legacy request protocol requires dense_rank to equal request position.
|
|
91
|
+
pool = sorted(pool, key=lambda candidate: candidate["first_stage_rank"])
|
|
92
|
+
candidates = [{"candidate_id": c["candidate_id"], "input": c["input"],
|
|
93
|
+
"dense_rank": c["first_stage_rank"], "dense_score": c["first_stage_score"]}
|
|
94
|
+
for c in pool]
|
|
95
|
+
# dense_* are legacy names; the pack identity declares BM25 or the Snowflake proxy.
|
|
96
|
+
value = {"schema_version": REQUEST_SCHEMA_VERSION, "pack_id": PUBLIC_RERANK_PACK_ID,
|
|
97
|
+
"case_id": row["task_id"], "query_id": row["query_id"], "query": row["query"],
|
|
98
|
+
"versions": {"corpus": pack.identity["dataset_digest"], "index": pack.identity["first_stage"],
|
|
99
|
+
"chunking": "public-document-v1",
|
|
100
|
+
"embedding": identity(pack.identity["first_stage_identity"])
|
|
101
|
+
if "first_stage_identity" in pack.identity else "none-bm25"},
|
|
102
|
+
"pool_digest": identity({"query": row["query"], "candidates": candidates}), "candidates": candidates}
|
|
103
|
+
return validate_candidate_request(value).to_dict()
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _policy(pack: PublicRerankPack | None = None) -> dict[str, Any]:
|
|
107
|
+
revised = pack is not None and "dataset_id" in pack.identity
|
|
108
|
+
return {"policy_version": "rag.rerank.beir.policy.v2" if revised else "rag.rerank.beir.policy.v1", "timeout_seconds": 30.0, "trials": 1,
|
|
109
|
+
"candidate_depth": 15, "ranking_depth": 5, "isolation": "local_unsandboxed",
|
|
110
|
+
"cache_policy": "caller_managed_not_observed"}
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _rank_public_response(pack, row, response, request):
|
|
114
|
+
"""Retain the original source-pool tie order on revised releases only."""
|
|
115
|
+
if "dataset_id" not in pack.identity:
|
|
116
|
+
return ranked_candidate_ids(response, request)
|
|
117
|
+
require(pack.identity.get("ranking_tie_policy") == "frozen_candidate_source_rank",
|
|
118
|
+
"revised public ranking tie policy differs")
|
|
119
|
+
source_rank = {candidate["candidate_id"]: candidate["candidate_source_rank"]
|
|
120
|
+
for candidate in row["candidates"]}
|
|
121
|
+
values = {score.candidate_id: score.ranking_score for score in response.scores}
|
|
122
|
+
return tuple(sorted(values, key=lambda cid: (-values[cid], source_rank[cid])))
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def run_public_rerank(candidate: CandidateSpec, dataset_path: str | Path, output_dir: str | Path, *,
|
|
126
|
+
split: str = "development", expected_sha256: str = PUBLIC_POOL_SHA256,
|
|
127
|
+
release_id: str | None = None) -> LocalRunRef:
|
|
128
|
+
require(isinstance(candidate, CandidateSpec) and candidate.interface_version == INTERFACE_VERSION,
|
|
129
|
+
"use a reranking CandidateSpec with sphynx.rag.rerank.v1")
|
|
130
|
+
pack = _load_selected(dataset_path, split, expected_sha256, release_id)
|
|
131
|
+
requests = [build_public_rerank_request(pack, row["task_id"]) for row in pack.rows]
|
|
132
|
+
|
|
133
|
+
def execute(raw: bytes, request: dict[str, Any]):
|
|
134
|
+
stdout, stderr, exit_code, failure, latency = _execute_candidate(candidate, raw, 30.0)
|
|
135
|
+
return stdout, stderr, exit_code, failure, latency, {}
|
|
136
|
+
|
|
137
|
+
return capture(pack.identity, {"name": candidate.name, "version": candidate.version,
|
|
138
|
+
"interface_version": candidate.interface_version, "argv": list(candidate.argv),
|
|
139
|
+
"identity_authority": "caller_declared_not_code_attestation"}, _policy(pack), requests, execute, output_dir)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def _compute(run: LocalRunRef, pack: PublicRerankPack) -> dict[str, Any]:
|
|
143
|
+
requests = [build_public_rerank_request(pack, row["task_id"]) for row in pack.rows]
|
|
144
|
+
revised = "dataset_id" in pack.identity
|
|
145
|
+
domain_ids = tuple(pack.identity["domains"])
|
|
146
|
+
manifest, captures = verified_capture(run, pack.identity, requests, _policy(pack))
|
|
147
|
+
cases = []
|
|
148
|
+
for row, request, record in zip(pack.rows, requests, captures):
|
|
149
|
+
failure = record["failure"]
|
|
150
|
+
ranking = None
|
|
151
|
+
if failure is None:
|
|
152
|
+
try:
|
|
153
|
+
parsed_request = validate_candidate_request(request)
|
|
154
|
+
response = validate_candidate_response(record["response"], parsed_request)
|
|
155
|
+
ranking = _rank_public_response(pack, row, response, parsed_request)
|
|
156
|
+
except (ValueError, TypeError, KeyError):
|
|
157
|
+
failure = "invalid_response"
|
|
158
|
+
grades = {c["candidate_id"]: c["grade"] for c in row["candidates"]}
|
|
159
|
+
labels_complete = all(grade is not None for grade in grades.values())
|
|
160
|
+
oracle = any(grade is not None and grade > 0 for grade in grades.values())
|
|
161
|
+
if revised and not oracle and not labels_complete:
|
|
162
|
+
oracle = None
|
|
163
|
+
scores = {key: None for key in ("ndcg_at_5", "hit_at_5", "mrr_at_5")}
|
|
164
|
+
if failure is None and oracle and labels_complete:
|
|
165
|
+
relevance = [grades[cid] for cid in ranking[:5]]
|
|
166
|
+
def dcg(values):
|
|
167
|
+
return sum((2 ** grade - 1) / math.log2(i + 2) for i, grade in enumerate(values))
|
|
168
|
+
scores["ndcg_at_5"] = dcg(relevance) / dcg(sorted(grades.values(), reverse=True)[:5])
|
|
169
|
+
scores["hit_at_5"] = float(any(grade > 0 for grade in relevance))
|
|
170
|
+
scores["mrr_at_5"] = next((1 / (i + 1) for i, grade in enumerate(relevance) if grade > 0), 0.0)
|
|
171
|
+
case = {"case_id": row["task_id"], "domain": row["dataset"], "failure": failure,
|
|
172
|
+
"pool_oracle": oracle, "metrics": scores, "runner_latency_ms": record["runner_latency_ms"]}
|
|
173
|
+
if revised:
|
|
174
|
+
case.update(labels_complete=labels_complete, quality_eligible=oracle is True and labels_complete)
|
|
175
|
+
cases.append(case)
|
|
176
|
+
eligible = lambda row: row["pool_oracle"] and row.get("labels_complete", True)
|
|
177
|
+
metrics = {key: metric([row["metrics"][key] for row in cases if eligible(row)])
|
|
178
|
+
for key in ("ndcg_at_5", "hit_at_5", "mrr_at_5")}
|
|
179
|
+
for entry in metrics.values():
|
|
180
|
+
entry["undefined_count"] = sum(row["pool_oracle"] is False and row.get("labels_complete", True) for row in cases)
|
|
181
|
+
if revised:
|
|
182
|
+
entry["blocked_reference_count"] = sum(not row["labels_complete"] for row in cases)
|
|
183
|
+
metrics["pool_oracle_coverage"] = metric([None if row["pool_oracle"] is None else float(row["pool_oracle"]) for row in cases])
|
|
184
|
+
metrics["valid_response_coverage"] = metric([float(row["failure"] is None) for row in cases])
|
|
185
|
+
metrics["candidate_failure_rate"] = metric([float(row["failure"] is not None) for row in cases])
|
|
186
|
+
spans = [row["runner_latency_ms"] for row in cases]
|
|
187
|
+
observed_spans = [value for value in spans if value is not None]
|
|
188
|
+
metrics["runner_latency_ms"] = {**metric(spans),
|
|
189
|
+
"value": percentile(observed_spans, .5) if observed_spans else None,
|
|
190
|
+
"p95": percentile(observed_spans, .95) if observed_spans else None}
|
|
191
|
+
domains = {}
|
|
192
|
+
for domain in domain_ids:
|
|
193
|
+
selected = [row for row in cases if row["domain"] == domain]
|
|
194
|
+
domains[domain] = {key: metric([row["metrics"][key] for row in selected if eligible(row)])
|
|
195
|
+
for key in ("ndcg_at_5", "hit_at_5", "mrr_at_5")}
|
|
196
|
+
domains[domain]["pool_oracle_coverage"] = metric([None if row["pool_oracle"] is None else float(row["pool_oracle"]) for row in selected])
|
|
197
|
+
macro = {key: metric([domains[domain][key]["value"] for domain in domain_ids])
|
|
198
|
+
for key in ("ndcg_at_5", "hit_at_5", "mrr_at_5")}
|
|
199
|
+
return {"schema_version": "sphynx.public-rerank.scorecard.v1", "pack_id": PUBLIC_RERANK_PACK_ID,
|
|
200
|
+
"track": "rag.rerank.public", "pack": pack.identity, "candidate": manifest["candidate"],
|
|
201
|
+
"execution_policy": _policy(pack), "runtime": manifest["runtime"], "trust_tier": "local_unverified", "development_only": True,
|
|
202
|
+
"label_status": "public_qrels", "metric_semantics": (
|
|
203
|
+
"Native qrels >0; conditional on frozen-pool oracle and complete qrels. Declared release domains. Previously opened splits."
|
|
204
|
+
if revised else "Native qrels >0; conditional on BM25 pool oracle. Previously opened splits."),
|
|
205
|
+
"metric_release": "rag.rerank.beir.metric.v2" if revised else METRIC_RELEASE,
|
|
206
|
+
"grader_release": "rag.rerank.beir.grader.v2" if revised else GRADER_RELEASE,
|
|
207
|
+
"metrics": metrics, "domain_slices": domains, "equal_domain_macro": macro, "cases": cases,
|
|
208
|
+
"counts": {"attempted_count": len(cases), "success_count": sum(row["failure"] is None for row in cases),
|
|
209
|
+
"failure_count": sum(row["failure"] is not None for row in cases)}}
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def grade_public_rerank(run: LocalRunRef, dataset_path: str | Path, *, split: str = "development",
|
|
213
|
+
expected_sha256: str = PUBLIC_POOL_SHA256, release_id: str | None = None) -> LocalEvaluationRef:
|
|
214
|
+
pack = _load_selected(dataset_path, split, expected_sha256, release_id)
|
|
215
|
+
return save_evaluation(run, _compute(run, pack))
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def report_public_rerank(evaluation: LocalEvaluationRef, dataset_path: str | Path, *, split: str = "development",
|
|
219
|
+
expected_sha256: str = PUBLIC_POOL_SHA256, release_id: str | None = None) -> LocalScorecard:
|
|
220
|
+
pack = _load_selected(dataset_path, split, expected_sha256, release_id)
|
|
221
|
+
return report_evaluation(evaluation, lambda annotations: _compute(evaluation.run, pack))
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def compare_public_rerank(a: LocalEvaluationRef, b: LocalEvaluationRef, dataset_path: str | Path, *,
|
|
225
|
+
split: str = "development", expected_sha256: str = PUBLIC_POOL_SHA256,
|
|
226
|
+
release_id: str | None = None) -> dict[str, Any]:
|
|
227
|
+
options = {"split": split, "expected_sha256": expected_sha256, "release_id": release_id}
|
|
228
|
+
return compare_scorecards(report_public_rerank(a, dataset_path, **options), report_public_rerank(b, dataset_path, **options))
|
|
229
|
+
|
|
230
|
+
# Available revised pools have separate immutable identities and loader policy.
|
|
231
|
+
|
|
232
|
+
def _load_selected(dataset_path, split, expected_sha256, release_id):
|
|
233
|
+
if release_id is None:
|
|
234
|
+
return load_public_rerank_pack(dataset_path, split=split, expected_sha256=expected_sha256)
|
|
235
|
+
require(split == "confirmation", "revised releases require split='confirmation'")
|
|
236
|
+
pack = load_public_pool_release(dataset_path, release_id=release_id)
|
|
237
|
+
require(expected_sha256 == PUBLIC_POOL_SHA256 or
|
|
238
|
+
"sha256:" + expected_sha256.removeprefix("sha256:") == pack.identity["dataset_digest"],
|
|
239
|
+
"explicit public release SHA-256 differs")
|
|
240
|
+
return pack
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
@dataclass(frozen=True)
|
|
244
|
+
class PublicPoolRelease:
|
|
245
|
+
release_id: str
|
|
246
|
+
dataset_id: str
|
|
247
|
+
source_sha256: str
|
|
248
|
+
domains: tuple[str, ...]
|
|
249
|
+
config_sha256: str
|
|
250
|
+
candidate_identity_sha256: str
|
|
251
|
+
previous_pool_sha256: str | tuple[tuple[str, str], ...]
|
|
252
|
+
previous_field: str
|
|
253
|
+
schema_version: str = "expanded-reranker.fresh-snowflake-pools.v1"
|
|
254
|
+
queries_per_domain: int = 20
|
|
255
|
+
candidate_depth: int = 15
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
PUBLIC_POOL_RELEASES = (
|
|
259
|
+
PublicPoolRelease("fresh-e2", "beir.fresh-e2.confirmation.v1",
|
|
260
|
+
"1168a3f2079ae192bc54ed681976004ad375882fbc7800b611c5bb50fbf7b8b4", DOMAINS,
|
|
261
|
+
"809cc4988a9faba34b460576968ebf1c04a2723d7adefbc878c4e20f54351218",
|
|
262
|
+
"34c1da7ccc31aef04a9a88992334944b3ca07a06e9aa9f35ac84f385a54fe5ce",
|
|
263
|
+
PUBLIC_POOL_SHA256, "previous_pools_sha256"),
|
|
264
|
+
PublicPoolRelease("guarded-jina", "beir.guarded-jina.confirmation.v1",
|
|
265
|
+
"8a519db2b0e62622705c7e05d71aac3c526d4a3dc97308e248839c5558f9ce49",
|
|
266
|
+
("scifact", "nfcorpus", "fiqa", "arguana", "scidocs", "webis-touche2020"),
|
|
267
|
+
"edf1b7a2fd789f7dc11e9d8d264e6868fa88bdfaef694278f687b55cdd397c36",
|
|
268
|
+
"4aa6c61bf60a4692bc577c7b4372ef8d71de1a08fbf8c7160894bf2035409612",
|
|
269
|
+
(("expanded-reranker\\data\\frozen-pools.json", PUBLIC_POOL_SHA256),
|
|
270
|
+
("expanded-reranker\\fresh-e2\\data\\snowflake-pools.json",
|
|
271
|
+
"1168a3f2079ae192bc54ed681976004ad375882fbc7800b611c5bb50fbf7b8b4")), "previous_pool_sha256"),
|
|
272
|
+
)
|
|
273
|
+
SNOWFLAKE_FIRST_STAGE = {
|
|
274
|
+
"model_id": "Snowflake/snowflake-arctic-embed-m-v1.5",
|
|
275
|
+
"revision": "e58a8f756156a1293d763f17e3aae643474e9b8a",
|
|
276
|
+
"query_prompt": "query", "similarity": "dot_product",
|
|
277
|
+
"role": "public Snowflake dense proxy; not a reproduction of the unavailable production Snowflake service",
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
def list_public_pool_releases() -> tuple[PublicPoolRelease, ...]:
|
|
282
|
+
"""List revised content-free identities without opening data or models."""
|
|
283
|
+
return PUBLIC_POOL_RELEASES
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
def load_public_pool_release(dataset_path: str | Path, *, release_id: str) -> PublicRerankPack:
|
|
287
|
+
"""Load one pinned 120-query release; preserve null/missing qrels as unknown.
|
|
288
|
+
|
|
289
|
+
These sources previously defaulted absent native qrels to zero. Retained
|
|
290
|
+
integer zero is a source judgment policy, not proof of negative review.
|
|
291
|
+
This loader performs no scoring and does not execute Snowflake or Jina.
|
|
292
|
+
"""
|
|
293
|
+
release = next((r for r in PUBLIC_POOL_RELEASES if r.release_id == release_id), None)
|
|
294
|
+
require(release is not None, "unknown revised public release")
|
|
295
|
+
source = Path(dataset_path).expanduser().resolve(strict=True)
|
|
296
|
+
source_digest = digest(source.read_bytes())
|
|
297
|
+
require(source_digest == "sha256:" + release.source_sha256, "public release SHA-256 differs")
|
|
298
|
+
data = read_json(source)
|
|
299
|
+
require(isinstance(data, dict), "public release must be a JSON object")
|
|
300
|
+
require(data.get("schema_version") == release.schema_version
|
|
301
|
+
and data.get("candidate_depth") == release.candidate_depth
|
|
302
|
+
and data.get("config_sha256") == release.config_sha256
|
|
303
|
+
and data.get("candidate_identity_pools_sha256") == release.candidate_identity_sha256
|
|
304
|
+
and data.get(release.previous_field) == (dict(release.previous_pool_sha256)
|
|
305
|
+
if isinstance(release.previous_pool_sha256, tuple) else release.previous_pool_sha256)
|
|
306
|
+
and data.get("first_stage") == SNOWFLAKE_FIRST_STAGE,
|
|
307
|
+
"public release schema, provenance or first-stage identity differs")
|
|
308
|
+
rows = data.get("queries")
|
|
309
|
+
require(isinstance(rows, list) and len(rows) == len(release.domains) * release.queries_per_domain,
|
|
310
|
+
"revised public release must contain exactly its 120 queries")
|
|
311
|
+
ids, tasks = set(), set()
|
|
312
|
+
unknown = 0
|
|
313
|
+
for row in rows:
|
|
314
|
+
require(isinstance(row, dict) and row.get("dataset") in release.domains
|
|
315
|
+
and row.get("split") == "confirmation", "revised public domain or split differs")
|
|
316
|
+
key = (row["dataset"], text(row.get("query_id"), "query_id"))
|
|
317
|
+
task = text(row.get("task_id"), "task_id")
|
|
318
|
+
require(key not in ids and task not in tasks, "duplicate revised public query or task")
|
|
319
|
+
ids.add(key); tasks.add(task)
|
|
320
|
+
text(row.get("query"), "query")
|
|
321
|
+
candidates = row.get("candidates")
|
|
322
|
+
require(isinstance(candidates, list) and len(candidates) == release.candidate_depth,
|
|
323
|
+
"revised public candidate depth differs")
|
|
324
|
+
cids, docs, ranks, source_ranks = set(), set(), set(), set()
|
|
325
|
+
for index, candidate in enumerate(candidates):
|
|
326
|
+
require(isinstance(candidate, dict), "invalid revised public candidate")
|
|
327
|
+
cid = text(candidate.get("candidate_id"), "candidate_id")
|
|
328
|
+
doc = text(candidate.get("document_id"), "document_id")
|
|
329
|
+
require(cid not in cids and doc not in docs, "duplicate revised public candidate or document")
|
|
330
|
+
cids.add(cid); docs.add(doc)
|
|
331
|
+
text(candidate.get("input"), "candidate.input")
|
|
332
|
+
for field, seen in (("first_stage_rank", ranks), ("candidate_source_rank", source_ranks)):
|
|
333
|
+
rank = candidate.get(field)
|
|
334
|
+
require(type(rank) is int and 1 <= rank <= release.candidate_depth and rank not in seen,
|
|
335
|
+
"revised public ranks must be complete permutations")
|
|
336
|
+
seen.add(rank)
|
|
337
|
+
require(candidate["candidate_source_rank"] == index + 1, "BM25 source ranks differ from pool order")
|
|
338
|
+
for field in ("first_stage_score", "candidate_source_score"):
|
|
339
|
+
score = candidate.get(field)
|
|
340
|
+
require(type(score) in (int, float) and math.isfinite(score), "invalid revised public score")
|
|
341
|
+
grade = candidate.get("grade")
|
|
342
|
+
require(grade is None or (type(grade) is int and 0 <= grade <= 3), "invalid revised public qrel")
|
|
343
|
+
unknown += int(grade is None)
|
|
344
|
+
# Keep the source order, dense ranks and unknown grades intact.
|
|
345
|
+
require(all(sum(row["dataset"] == domain for row in rows) == release.queries_per_domain
|
|
346
|
+
for domain in release.domains), "revised public domain population differs")
|
|
347
|
+
pack = PublicRerankPack(source_digest, "confirmation", rows)
|
|
348
|
+
pack.identity.update(dataset_id=release.dataset_id, pack_release=release.dataset_id,
|
|
349
|
+
domains=list(release.domains), first_stage="snowflake_arctic_embed_m_v1_5_public_proxy",
|
|
350
|
+
ranking_tie_policy="frozen_candidate_source_rank",
|
|
351
|
+
first_stage_identity=dict(SNOWFLAKE_FIRST_STAGE), candidate_source="bm25_top15_frozen_identities",
|
|
352
|
+
judgment_policy="source_absent_native_qrels_default_zero_explicit_null_unknown",
|
|
353
|
+
unknown_qrel_count=unknown, reference_digest=source_digest,
|
|
354
|
+
confirmation_status="previously_opened_exploratory")
|
|
355
|
+
return pack
|
sphynx/py.typed
ADDED
|
File without changes
|