CoolFace
Apppublic

build-small-hackathon/hackathon-advisor

sourceHugging Facemitupdated 3mo agoView on Hugging Face
16likes
aliases.py81 linesDownload Raw Back to hackathon_advisor
1from __future__ import annotations2 3from dataclasses import dataclass4from difflib import SequenceMatcher5import re6 7 8@dataclass(frozen=True)9class Correction:10    original: str11    canonical: str12    confidence: float13 14    def to_dict(self) -> dict:15        return {16            "original": self.original,17            "canonical": self.canonical,18            "confidence": round(self.confidence, 3),19        }20 21 22ALIASES: dict[str, tuple[str, ...]] = {23    "Nemotron": ("nemotron", "nemo tron", "neutron", "nemotran", "nemo-tron"),24    "MiniCPM5": ("minicpm5", "mini cpm5", "mini cpm", "open cpm", "opencpm5", "cpm five"),25    "EmbeddingGemma": ("embedding gemma", "embeddinggemma", "gemma embedding", "embedded gemma"),26    "ZeroGPU": ("zero gpu", "zerogpu", "zero-gpu", "zero g p u"),27    "Gradio Server": ("gradio server", "gradio.server", "server mode"),28    "Build Small Hackathon": ("build small", "build-small", "small hackathon"),29    "Off the Grid": ("off the grid", "off-grid", "offline badge"),30    "Well-Tuned": ("well tuned", "well-tuned", "fine tune", "finetune", "lora"),31    "Tiny Titan": ("tiny titan", "tiny tight end", "tiny-titan"),32    "Llama Champion": ("llama champion", "llama.cpp", "llama cpp", "llama badge"),33}34 35_TOKEN_RE = re.compile(r"[a-z0-9]+(?:[.-][a-z0-9]+)?", re.IGNORECASE)36 37 38def normalize_text(text: str) -> tuple[str, list[Correction]]:39    normalized = text40    corrections: list[Correction] = []41    spans = _candidate_spans(text)42    used: set[str] = set()43 44    for canonical, aliases in ALIASES.items():45        best: tuple[str, float] | None = None46        for alias in aliases:47            for span in spans:48                confidence = _similarity(alias, span)49                if confidence >= 0.88 and (best is None or confidence > best[1]):50                    best = (span, confidence)51        if not best:52            continue53 54        original, confidence = best55        if original.lower() in used or original == canonical:56            continue57        used.add(original.lower())58        normalized = re.sub(re.escape(original), canonical, normalized, count=1, flags=re.IGNORECASE)59        corrections.append(Correction(original=original, canonical=canonical, confidence=confidence))60 61    return normalized, corrections62 63 64def _candidate_spans(text: str) -> list[str]:65    tokens = _TOKEN_RE.findall(text.lower())66    spans = set(tokens)67    for size in (2, 3):68        for index in range(max(0, len(tokens) - size + 1)):69            spans.add(" ".join(tokens[index : index + size]))70    return sorted(spans, key=len, reverse=True)71 72 73def _similarity(left: str, right: str) -> float:74    compact_left = re.sub(r"[^a-z0-9]", "", left.lower())75    compact_right = re.sub(r"[^a-z0-9]", "", right.lower())76    if not compact_left or not compact_right:77        return 0.078    if compact_left == compact_right:79        return 1.080    return SequenceMatcher(None, compact_left, compact_right).ratio()81