kodama-core / runtime /jevlike /data /decontam.py
Cem13's picture
Release Kodama Core with weights, runtime, attribution, and evaluation
c7893fa verified
Raw History Blame Contribute Delete
2.57 kB
"""Keep new training data away from the evaluation sets.
Two rules:
1. Task families used only for zero-shot evaluation (data/heldout.jsonl: trec question types,
formality, spam) must never be trained on. `blocked_task(name)` checks dataset/task names.
2. No training state may overlap an eval state (heldout, test, bench): exact match after
normalization, or any shared 12-word shingle. `is_contaminated(state)` checks this.
from jevlike.data.decontam import Decontaminator
dc = Decontaminator() # loads the eval sets once (~1 s)
if dc.blocked_task(task_name) or dc.is_contaminated(state): skip
CLI: python -m jevlike.data.decontam IN.jsonl OUT.jsonl (filters a Record JSONL)
"""
from __future__ import annotations
import re
import sys
from pathlib import Path
from jevlike.types import read_jsonl, write_jsonl
ROOT = Path(__file__).resolve().parents[2]
EVAL_FILES = ["data/heldout.jsonl", "data/test.jsonl", "data/bench/decisions.jsonl",
"data/eval_newsfin/zeroshot.jsonl", "data/eval_newsfin/zeroshot_long.jsonl"]
BLOCKED_PATTERNS = [r"\btrec\b", r"question[\s_-]*(type|classification)", r"formal", r"spam", r"enron"]
SHINGLE = 12
def _norm(s: str) -> str:
return re.sub(r"\W+", " ", s.lower()).strip()
def _shingles(s: str) -> set[str]:
w = _norm(s).split()
if len(w) < SHINGLE:
return {" ".join(w)}
return {" ".join(w[i:i + SHINGLE]) for i in range(len(w) - SHINGLE + 1)}
class Decontaminator:
def __init__(self, eval_files: list[str] = EVAL_FILES):
self.exact: set[str] = set()
self.shingles: set[str] = set()
for f in eval_files:
p = ROOT / f
if not p.exists():
continue
for r in read_jsonl(str(p)):
self.exact.add(_norm(r.state))
self.shingles |= _shingles(r.state)
@staticmethod
def blocked_task(name: str) -> bool:
"""True for dataset/task names in the held-out task families (match on name or description)."""
return any(re.search(p, name.lower()) for p in BLOCKED_PATTERNS)
def is_contaminated(self, state: str) -> bool:
return _norm(state) in self.exact or not self.shingles.isdisjoint(_shingles(state))
if __name__ == "__main__":
src, dst = sys.argv[1], sys.argv[2]
dc = Decontaminator()
rs = read_jsonl(src)
keep = [r for r in rs if not (dc.blocked_task(r.source) or dc.is_contaminated(r.state))]
write_jsonl(dst, keep)
print(f"kept {len(keep)}/{len(rs)} ({len(rs) - len(keep)} dropped)")