Download src/sigir/data/serialization.py from inflaton/pakdd_mrd: direct link, hf CLI and curl.
- Browser
- Download file 2.09 kB
-
https://huggingface.co/spaces/inflaton/pakdd_mrd/resolve/main/src/sigir/data/serialization.py
- Command line
-
hf download hf://spaces/inflaton/pakdd_mrd/src/sigir/data/serialization.py
-
curl -L -o serialization.py https://huggingface.co/spaces/inflaton/pakdd_mrd/resolve/main/src/sigir/data/serialization.py
2.09 kB
| """Record serialization: rich (all fields, named) versus compact (short, fewer fields), separately versioned. | |
| The same fields and candidate information are used across model comparisons within an arm; the rich | |
| versus compact contrast is its own experiment (plan §6/§9). | |
| """ | |
| from __future__ import annotations | |
| import unicodedata | |
| from typing import Any, Sequence | |
| # Model inputs are NFKC-normalised (Nov 5, 2026, review note R2). SentencePiece applies nmt_nfkc, the transformers 5 | |
| # fast conversion of deberta-v3 does not: non-breaking spaces inside part numbers and symbols such as ™ became [UNK] | |
| # (30 of 4,000 texts); after NFKC the fast tokenizer equals SentencePiece on all 4,000. Applied to every arm's input | |
| # (encoders, decision head, judges) so comparisons see identical text. Retrieval (record_text) is not affected. | |
| TEXT_NORMALIZATION = "NFKC" | |
| SERIALIZERS: dict[str, dict[str, Any]] = { | |
| "rich_v1": {"max_chars_per_field": 400, "include_empty": True}, | |
| "compact_v1": {"max_chars_per_field": 80, "include_empty": False}, | |
| } | |
| def serialize_record(fields: dict[str, Any], order: Sequence[str] | None = None, version: str = "rich_v1", compact_fields: Sequence[str] | None = None, normalize: str | None = TEXT_NORMALIZATION) -> str: | |
| cfg = SERIALIZERS[version] | |
| keys = list(order) if order else list(fields.keys()) | |
| if version.startswith("compact") and compact_fields: | |
| keys = [k for k in keys if k in compact_fields] | |
| parts = [] | |
| for k in keys: | |
| v = str(fields.get(k, "") or "") | |
| v = (unicodedata.normalize(normalize, v) if normalize else v).strip() | |
| if not v and not cfg["include_empty"]: | |
| continue | |
| v = v[: cfg["max_chars_per_field"]] | |
| parts.append(f"{k}: {v}") | |
| return " | ".join(parts) | |
| SYMBOLS = [chr(ord("A") + i) for i in range(26)] + [f"A{chr(ord('A') + i)}" for i in range(26)] # A..Z, AA..AZ | |
| NONE_SYMBOL = "NONE" | |
| def candidate_symbol(j: int) -> str: | |
| return SYMBOLS[j] | |
| def pair_text(query: str, candidate: str, sep: str = " [SEP] ") -> str: | |
| return f"{query}{sep}{candidate}" | |