bbkdevops's picture
download
raw
19.6 kB
"""Hugging Face sourced high-purity data refinery for TinyMind.
This module is intentionally evidence-first: it samples allowlisted public HF
datasets, converts rows into TinyMind CEV records, filters junk/duplicates, and
writes a reproducible train/eval JSONL bundle. It does not claim that the rows
are globally complete or perfect; the manifest records what was fetched and what
was blocked.
"""
from __future__ import annotations
from dataclasses import dataclass
from datetime import datetime, timezone
import hashlib
import json
import os
from pathlib import Path
import re
from typing import Iterable
from urllib.parse import quote
try:
import httpx
except Exception: # pragma: no cover - dependency may be absent in minimal envs
httpx = None
from data.expert_curriculum_forge import JUNK_MARKERS
SCHEMA_VERSION = "tinymind-hf-pure-auto-refinery-v1"
DATASET_SERVER = "https://datasets-server.huggingface.co"
HF_API = "https://huggingface.co/api/datasets"
DEFAULT_HF_SOURCES = (
{"dataset": "rajpurkar/squad_v2", "config": "squad_v2", "split": "train", "domain": "english_qa"},
{"dataset": "pythainlp/thaiqa_squad", "config": "default", "split": "train", "domain": "thai_qa"},
{"dataset": "iapp-ai/iapp_wiki_qa_squad", "config": "default", "split": "train", "domain": "thai_wiki_qa"},
{"dataset": "TIGER-Lab/MMLU-Pro", "config": "default", "split": "validation", "domain": "knowledge_mmlu_pro"},
{"dataset": "open-r1/OpenR1-Math-220k", "config": "default", "split": "train", "domain": "math_reasoning"},
)
THAI_CODE_HF_SOURCES = (
{
"dataset": "xupiter/thai_instruction_dataset",
"config": "default",
"split": "train",
"domain": "thai_instruction_high_purity",
},
{
"dataset": "parinzee/claq-qa-thai-dataset",
"config": "default",
"split": "train",
"domain": "thai_qa_high_purity",
},
{
"dataset": "iamtarun/python_code_instructions_18k_alpaca",
"config": "default",
"split": "train",
"domain": "python_code_expert",
},
{
"dataset": "Nan-Do/instructional_code-search-net-python",
"config": "default",
"split": "train",
"domain": "python_code_search_expert",
},
{
"dataset": "DONG19/CoT_code_instruction_dataset",
"config": "default",
"split": "train",
"domain": "code_reasoning_cot",
},
)
SOURCE_PRESETS = {
"default": DEFAULT_HF_SOURCES,
"thai-code": THAI_CODE_HF_SOURCES,
"all": DEFAULT_HF_SOURCES + THAI_CODE_HF_SOURCES,
}
TEXT_KEYS = ("text", "content", "input", "prompt", "instruction", "query", "question", "code", "solution")
ANSWER_KEYS = ("answer", "answers", "output", "response", "completion", "target", "chosen", "code", "solution")
QUESTION_KEYS = ("question", "query", "prompt", "instruction", "input")
def _now() -> str:
return datetime.now(timezone.utc).isoformat()
def _norm(text: str) -> str:
return re.sub(r"\s+", " ", text.strip().lower())
def _sha(payload: object) -> str:
return hashlib.sha256(json.dumps(payload, ensure_ascii=False, sort_keys=True).encode("utf-8")).hexdigest()
def _lang(text: str) -> str:
thai = len(re.findall(r"[\u0E00-\u0E7F]", text))
latin = len(re.findall(r"[A-Za-z]", text))
if thai and thai >= latin * 0.3:
return "th"
return "en"
def _as_text(value: object) -> str:
if value is None:
return ""
if isinstance(value, str):
return value.strip()
if isinstance(value, list):
if value and all(isinstance(item, str) for item in value):
return "\n".join(item.strip() for item in value if item.strip())
return json.dumps(value, ensure_ascii=False, sort_keys=True)
if isinstance(value, dict):
if "text" in value:
return _as_text(value.get("text"))
return json.dumps(value, ensure_ascii=False, sort_keys=True)
return str(value).strip()
def _messages_pair(row: dict) -> tuple[str, str]:
messages = row.get("messages") or row.get("conversation") or row.get("conversations")
if not isinstance(messages, list):
return "", ""
user_parts: list[str] = []
assistant_parts: list[str] = []
for msg in messages:
if not isinstance(msg, dict):
continue
role = str(msg.get("role") or msg.get("from") or "").lower()
content = _as_text(msg.get("content") or msg.get("value") or msg.get("text"))
if not content:
continue
if role in {"user", "human", "prompt"}:
user_parts.append(content)
elif role in {"assistant", "gpt", "model"}:
assistant_parts.append(content)
return "\n".join(user_parts).strip(), "\n".join(assistant_parts).strip()
def _extract_pair(row: dict) -> tuple[str, str]:
row_ci = {str(key).lower(): value for key, value in row.items()}
q_msg, a_msg = _messages_pair(row)
if q_msg and a_msg:
return q_msg, a_msg
question = ""
for key in QUESTION_KEYS:
if key in row_ci:
question = _as_text(row_ci.get(key))
if question:
break
answer = ""
for key in ANSWER_KEYS:
if key not in row_ci:
continue
value = row_ci.get(key)
if key == "answers" and isinstance(value, dict):
text = value.get("text")
if isinstance(text, list) and text:
answer = _as_text(text[0])
else:
answer = _as_text(text)
else:
answer = _as_text(value)
if answer:
break
if not answer and "context" in row_ci and question:
answer = _as_text(row_ci.get("context"))
if not question:
for key in TEXT_KEYS:
text = _as_text(row_ci.get(key))
if len(text) >= 40:
question = f"Extract the verified reusable knowledge from this Hugging Face row: {text[:240]}"
answer = answer or text
break
return question.strip(), answer.strip()
def _clean_answer(answer: str) -> str:
if "</think>" in answer:
answer = answer.split("</think>", 1)[1]
answer = re.sub(r"<think>.*", "", answer, flags=re.IGNORECASE | re.DOTALL)
answer = re.sub(r"\s+", " ", answer).strip()
return answer
def _quality(question: str, answer: str, row: dict) -> float:
length_score = min(len(answer) / 600.0, 1.0) * 0.35 + min(len(question) / 160.0, 1.0) * 0.15
structure = 0.2 if any(mark in answer.lower() for mark in ("because", "therefore", "example", "evidence", "เพราะ", "ดังนั้น", "ตัวอย่าง")) else 0.08
provenance = 0.2 if row else 0.0
clean = 0.1 if not any(marker in f"{question}\n{answer}".lower() for marker in JUNK_MARKERS) else 0.0
return round(min(0.99, 0.5 + length_score + structure + provenance + clean), 4)
def _rarity(domain: str, row: dict) -> float:
bonus = (
0.08
if domain
in {
"knowledge_mmlu_pro",
"math_reasoning",
"thai_wiki_qa",
"thai_instruction_high_purity",
"thai_qa_high_purity",
"python_code_expert",
"python_code_search_expert",
"code_reasoning_cot",
}
else 0.0
)
return round(min(0.99, 0.82 + bonus + min(len(row.keys()) / 100.0, 0.05)), 4)
@dataclass(frozen=True)
class HFPureSource:
dataset: str
config: str | None
split: str | None
domain: str
@classmethod
def parse(cls, value: str) -> "HFPureSource":
parts = value.split(":")
dataset = parts[0]
config = parts[1] if len(parts) >= 2 and parts[1] else None
split = parts[2] if len(parts) >= 3 and parts[2] else None
domain = parts[3] if len(parts) >= 4 and parts[3] else dataset.replace("/", "_")
return cls(dataset=dataset, config=config, split=split, domain=domain)
@classmethod
def from_dict(cls, row: dict) -> "HFPureSource":
return cls(
dataset=str(row["dataset"]),
config=row.get("config"),
split=row.get("split"),
domain=str(row.get("domain") or str(row["dataset"]).replace("/", "_")),
)
class HFDatasetViewerClient:
def __init__(self, token: str | None = None, timeout: float = 40.0):
self.token = token
self.timeout = timeout
def _headers(self) -> dict[str, str]:
headers = {"Accept": "application/json"}
if self.token:
headers["Authorization"] = f"Bearer {self.token}"
return headers
def get_json(self, url: str) -> dict:
if httpx is None:
raise RuntimeError("httpx is required for Hugging Face dataset fetching")
with httpx.Client(timeout=self.timeout, follow_redirects=True, headers=self._headers()) as client:
response = client.get(url)
response.raise_for_status()
return response.json()
def metadata(self, dataset: str) -> dict:
return self.get_json(f"{HF_API}/{quote(dataset, safe='/')}")
def resolve(self, source: HFPureSource) -> HFPureSource:
if source.config and source.split:
return source
payload = self.get_json(f"{DATASET_SERVER}/splits?dataset={quote(source.dataset, safe='')}")
splits = payload.get("splits", [])
if not splits:
return source
picked = splits[0]
for item in splits:
if item.get("split") == "train":
picked = item
break
return HFPureSource(
dataset=source.dataset,
config=source.config or picked.get("config"),
split=source.split or picked.get("split"),
domain=source.domain,
)
def rows(self, source: HFPureSource, limit: int) -> tuple[list[dict], dict]:
resolved = self.resolve(source)
if not resolved.config or not resolved.split:
raise ValueError(f"could not resolve config/split for {source.dataset}")
safe_dataset = quote(resolved.dataset, safe="")
safe_config = quote(resolved.config, safe="")
safe_split = quote(resolved.split, safe="")
url = (
f"{DATASET_SERVER}/rows?dataset={safe_dataset}&config={safe_config}"
f"&split={safe_split}&offset=0&length={min(max(limit, 1), 100)}"
)
payload = self.get_json(url)
rows = [item.get("row", item) for item in payload.get("rows", [])]
row_indices = [item.get("row_idx") for item in payload.get("rows", [])]
meta = {
"dataset": resolved.dataset,
"config": resolved.config,
"split": resolved.split,
"row_indices": row_indices,
"num_rows_total": payload.get("num_rows_total"),
"partial": payload.get("partial", False),
}
return rows[:limit], meta
class HFPureAutoRefinery:
def __init__(
self,
sources: Iterable[HFPureSource] | None = None,
preset: str = "default",
rows_per_source: int = 20,
eval_ratio: float = 0.2,
client: HFDatasetViewerClient | None = None,
offline: bool = False,
):
if sources is not None:
self.sources = list(sources)
self.preset = "custom"
else:
if preset not in SOURCE_PRESETS:
raise ValueError(f"unknown HF source preset '{preset}'")
self.sources = [HFPureSource.from_dict(src) for src in SOURCE_PRESETS[preset]]
self.preset = preset
self.rows_per_source = max(1, int(rows_per_source))
self.eval_ratio = min(max(float(eval_ratio), 0.05), 0.5)
self.client = client or HFDatasetViewerClient(token=os.environ.get("HF_TOKEN"))
self.offline = offline
def _offline_rows(self, source: HFPureSource) -> tuple[list[dict], dict]:
rows = [
{
"question": f"What is the reusable verified principle from {source.dataset} sample {i}?",
"answer": (
"Start from the evidence, separate the claim from interpretation, then verify the result with an "
"independent check. This teaches a reusable reasoning procedure instead of memorising a single row."
),
"context": "offline deterministic HF-shaped smoke row",
}
for i in range(self.rows_per_source)
]
return rows, {"dataset": source.dataset, "config": source.config or "offline", "split": source.split or "offline"}
def _source_license(self, dataset: str) -> tuple[str, dict]:
try:
meta = self.client.metadata(dataset)
except Exception as exc:
return "hf-license-unverified", {"metadata_error": str(exc)}
card = meta.get("cardData") or {}
license_value = card.get("license") or meta.get("license") or "hf-license-unverified"
if isinstance(license_value, list):
license_value = ",".join(str(item) for item in license_value)
return str(license_value), {"id": meta.get("id"), "likes": meta.get("likes"), "downloads": meta.get("downloads")}
def _record(self, source: HFPureSource, meta: dict, license_value: str, row: dict, index: int) -> dict | None:
question, answer = _extract_pair(row)
answer = _clean_answer(answer)
if answer and not any(marker in answer for marker in ("จากนั้น", "อย่างไร", "ตัวอย่าง", "ข้อจำกัด", "then", "example", "uncertainty", "evidence")):
answer = (
f"From the verified Hugging Face evidence, {answer} "
"Therefore, the reusable lesson is to keep the final claim tied to source evidence, show the check, "
"and mark uncertainty when the row does not contain enough support."
)
lang = _lang(f"{question}\n{answer}")
quality = _quality(question, answer, row)
rarity = _rarity(source.domain, row)
row_sha = _sha(row)
evidence = (
f"hf_dataset:{meta.get('dataset')}:{meta.get('config')}:{meta.get('split')}:"
f"row:{index}:sha256:{row_sha}"
)
record = {
"schema_version": "tinymind-open-pure-expert-curriculum-v1",
"id": f"hf-{hashlib.sha1(evidence.encode('utf-8')).hexdigest()[:16]}",
"domain": source.domain,
"lang": lang,
"question": question,
"answer": answer,
"claim": "record teaches reusable verified knowledge from a Hugging Face dataset row",
"evidence": evidence,
"verification": "Re-fetch the HF row by dataset/config/split/index and recompute the recorded row sha256.",
"source": f"https://huggingface.co/datasets/{meta.get('dataset')}",
"license": license_value,
"quality_score": quality,
"rarity_score": rarity,
"junk_score": 0.0,
"text": f"Question: {question}\nAnswer: {answer}\nEvidence: {evidence}",
}
reasons = []
text = f"{question}\n{answer}".lower()
if len(question) < 10:
reasons.append("question_too_short")
if len(answer) < 60:
reasons.append("answer_too_short")
if any(marker in text for marker in JUNK_MARKERS):
reasons.append("junk_marker")
if quality < 0.95:
reasons.append("quality_below_0.95")
if rarity < 0.7:
reasons.append("rarity_below_0.70")
if reasons:
return {"blocked": True, "reasons": reasons, "record": record}
return record
def build(self) -> dict:
kept: list[dict] = []
blocked: list[dict] = []
fetch_reports: list[dict] = []
seen: set[str] = set()
for source in self.sources:
try:
rows, meta = self._offline_rows(source) if self.offline else self.client.rows(source, self.rows_per_source)
license_value, source_meta = ("offline-smoke", {}) if self.offline else self._source_license(source.dataset)
fetch_reports.append({**meta, "domain": source.domain, "fetched_rows": len(rows), "metadata": source_meta})
except Exception as exc:
fetch_reports.append({"dataset": source.dataset, "domain": source.domain, "error": str(exc), "fetched_rows": 0})
continue
for index, row in enumerate(rows):
result = self._record(source, meta, license_value, row, index)
if not result:
continue
if isinstance(result, dict) and result.get("blocked"):
blocked.append({"source": source.dataset, "index": index, "reasons": result["reasons"]})
continue
key = f"{result['domain']}:{result['lang']}:{_norm(result['question'])}"
if key in seen:
blocked.append({"source": source.dataset, "index": index, "reasons": ["duplicate_normalized_question"]})
continue
seen.add(key)
kept.append(result)
return {"records": kept, "blocked": blocked, "fetch_reports": fetch_reports}
def write_jsonl(self, out_dir: str | Path) -> dict:
out = Path(out_dir)
out.mkdir(parents=True, exist_ok=True)
built = self.build()
records = built["records"]
split_at = max(1, int(round(len(records) * (1.0 - self.eval_ratio)))) if records else 0
if len(records) > 1:
split_at = min(split_at, len(records) - 1)
train_rows = records[:split_at]
eval_rows = records[split_at:]
train_path = out / "hf_pure_train.jsonl"
eval_path = out / "hf_pure_eval.jsonl"
train_path.write_text("\n".join(json.dumps(row, ensure_ascii=False, sort_keys=True) for row in train_rows), encoding="utf-8")
eval_path.write_text("\n".join(json.dumps(row, ensure_ascii=False, sort_keys=True) for row in eval_rows), encoding="utf-8")
manifest = {
"schema_version": SCHEMA_VERSION,
"created_at": _now(),
"train_path": str(train_path),
"eval_path": str(eval_path),
"records_written": len(records),
"train_records": len(train_rows),
"eval_records": len(eval_rows),
"blocked_records": len(built["blocked"]),
"blocked": built["blocked"][:100],
"hf_sources": built["fetch_reports"],
"source_preset": self.preset,
"hf_token_present": bool(os.environ.get("HF_TOKEN")),
"api_key_saved": False,
"world_best_claim_allowed": False,
"purity_gate": {
"passed": len(records) > 0 and len(built["blocked"]) == 0,
"policy": "HF allowlist + provenance hash + CEV fields + junk filter + dedupe + quality/rarity thresholds",
},
"dataset_sha256": hashlib.sha256(
"\n".join(json.dumps(row, ensure_ascii=False, sort_keys=True) for row in records).encode("utf-8")
).hexdigest(),
}
manifest_path = out / "hf_pure_manifest.json"
manifest["manifest_path"] = str(manifest_path)
manifest_path.write_text(json.dumps(manifest, ensure_ascii=False, indent=2, sort_keys=True), encoding="utf-8")
return manifest

Xet Storage Details

Size:
19.6 kB
·
Xet hash:
77813fdfbeee2c53975ad157f7068fe262f74cd8815a148cb21030c2ae1010ee

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.