SyFox / inference.py
Mr-DS-ML-85's picture
Upload folder using huggingface_hub
c97bd71 verified
Raw History Blame Contribute Delete
3.84 kB
#!/usr/bin/env python3
"""Thin inference wrapper for the SyFox giant model (HuggingFace layout).
from inference import SyFox
m = SyFox() # loads model/giant-<script>
m.decide("I was charged twice on my invoice") # router only
m.decide("...") # router + domain question
The Python layer only speaks JSON; every decision is made by the C++ SI
substrate (energy injection -> settle -> resonance readout -> honest
silence). Requires build/libsyfox_core.so (see Dockerfile or `make`).
"""
import json
import sys
from pathlib import Path
_HERE = Path(__file__).resolve().parent
sys.path.insert(0, str(_HERE / "server"))
from syfox_bridge import SyFoxEngine, detect_script # noqa: E402
_SCHEMAS = json.load(open(_HERE / "datasets" / "schemas.json"))
_DOMAINS = _SCHEMAS["domains"]
_ROUTER_CRITERIA = _DOMAINS["_router"]["criteria"]
class SyFox:
"""Auto-routing handle over the per-script giant substrates."""
def __init__(self, base: str = str(_HERE / "model" / "giant")):
self.base = base
self._engines: dict[str, SyFoxEngine] = {}
def _engine(self, text: str) -> tuple[SyFoxEngine, str]:
slug = detect_script(text)
if slug in ("unknown", ""):
slug = "latin"
cand = Path(f"{self.base}-{slug}")
if not cand.exists():
slug = "latin"
cand = Path(f"{self.base}-latin")
if slug not in self._engines:
eng = SyFoxEngine(str(cand))
eng.set_energy_norm(True) # M1 gain: mandatory at corpus scale
self._engines[slug] = eng
return self._engines[slug], slug
@staticmethod
def router_question() -> dict:
return {"type": "choice", "instructions": "",
"criteria": _ROUTER_CRITERIA}
@staticmethod
def domain_question(domain: str) -> dict:
d = _DOMAINS[domain]
return {"type": "choice", "instructions": "",
"criteria": d["criteria"]}
def domains(self) -> list:
return [d for d in _DOMAINS
if not d.startswith("_")
and _DOMAINS[d].get("type") != "noul_multi"]
def decide(self, state: str, domain: str | None = None) -> dict:
"""Ask the router always; ask the domain's class question when
`domain` is given. NOTE (measured): the router-only estimate is
the blind condition (0.400 hidden accuracy) — naming the domain
anchors the field and gives the class numbers."""
eng, slug = self._engine(state)
questions = {"domain": self.router_question()}
if domain:
questions[_DOMAINS[domain]["qkey"]] = self.domain_question(domain)
answers, usage, _ = eng.decide(state, questions, {"energy_norm": True})
out = {"script": slug, "answers": answers,
"settled_energy": usage.get("settled_energy")}
if domain is None and not answers["domain"].get("deferred"):
chosen = answers["domain"]["choice"]
for d, meta in _DOMAINS.items():
if meta.get("router_anchor") == chosen:
out["suggested_domain"] = d
break
return out
if __name__ == "__main__":
m = SyFox()
for s in ["I was charged twice on my last invoice, please refund.",
"বাংলা সাপোর্ট প্রশ্ন: কার্ড থেকে দুইবার টাকা কেটেছে।",
"The quarterback threw five touchdowns in the opener."]:
r = m.decide(s)
a = r["answers"]["domain"]
print(f"[{r['script']:9s}] {a.get('choice')} "
f"(conf {a.get('confidence', 0):.3f}"
f"{', deferred' if a.get('deferred') else ''}) {s[:60]}")