Token Classification
Transformers
Safetensors
ONNX
Transformers.js
modernbert
punctuation
punctuation-restoration
asr
speech-recognition
transcription
mmbert
Instructions to use seamon67/Punctuation-Restoration with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use seamon67/Punctuation-Restoration with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("token-classification", model="seamon67/Punctuation-Restoration")# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModelForTokenClassification tokenizer = AutoTokenizer.from_pretrained("seamon67/Punctuation-Restoration") model = AutoModelForTokenClassification.from_pretrained("seamon67/Punctuation-Restoration", device_map="auto") - Transformers.js
How to use seamon67/Punctuation-Restoration with Transformers.js:
// npm i @huggingface/transformers import { pipeline } from '@huggingface/transformers'; // Allocate pipeline const pipe = await pipeline('token-classification', 'seamon67/Punctuation-Restoration'); - Notebooks
- Google Colab
- Kaggle
Download code/punct/eval_punct.py from seamon67/Punctuation-Restoration: direct link, hf CLI and curl.
- Browser
- Download file 4.41 kB
-
https://huggingface.co/seamon67/Punctuation-Restoration/resolve/main/code/punct/eval_punct.py
- Command line
-
hf download hf://seamon67/Punctuation-Restoration/code/punct/eval_punct.py
-
curl -L -o eval_punct.py https://huggingface.co/seamon67/Punctuation-Restoration/resolve/main/code/punct/eval_punct.py
4.41 kB
| """Evaluate punctuation-restoration token classifiers on punct/build_evals.py sets. | |
| python punct/eval_punct.py OUT.json EVAL_DIR MODEL [MODEL ...] (MODEL = local dir or Hub id; labels "0 . , ? - :") | |
| Every model gets the same input: the paragraph with target marks removed (punct/common.py units), cased and lowercased, | |
| in chunks of 150 words (250 CJK characters). A word's prediction is the label of its last token (as in | |
| deepmultilingualpunctuation). Metrics per set and language: punctuation F1 (micro over the 5 marks: a predicted mark is | |
| correct only if it is the gold mark) and per-mark F1. | |
| """ | |
| import json, os, sys, time | |
| import numpy as np, pandas as pd, torch | |
| from transformers import AutoModelForTokenClassification, AutoTokenizer | |
| sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) | |
| from common import LABELS, NOSPACE, units, lower_keep_len, unit_preds | |
| out_f, ev = sys.argv[1:3]; models = sys.argv[3:] | |
| KREDOR = {"eng_Latn", "deu_Latn", "fra_Latn", "spa_Latn", "bul_Cyrl", "ita_Latn", "pol_Latn", "nld_Latn", "ces_Latn", "por_Latn", | |
| "slk_Latn", "slv_Latn"} | |
| sets = {os.path.basename(p)[:-8]: pd.read_parquet(f"{ev}/{os.path.basename(p)}") for p in sorted(os.listdir(ev)) if p.endswith(".parquet")} | |
| items = [] # (set, lang, clean chunk, ends, gold labels) | |
| for name, df in sets.items(): | |
| for text, lang in zip(df.text, df.lang): | |
| nos = lang.startswith(("zho", "jpn", "yue")) or lang in NOSPACE | |
| c, e, l = units(text, "cmn_Hani" if lang.startswith(("zho", "yue")) else lang) | |
| cap = 250 if nos else 150 | |
| for a in range(0, len(e), cap): | |
| off = e[a - 1] + (0 if nos else 1) if a else 0 | |
| ee = e[a:a + cap] | |
| items.append((name, lang, c[off:ee[-1]], [x - off for x in ee], l[a:a + cap])) | |
| print("chunks", len(items), flush=True) | |
| res = json.load(open(out_f)) if os.path.exists(out_f) else {} | |
| for mname in models: | |
| tok = AutoTokenizer.from_pretrained(mname) | |
| model = AutoModelForTokenClassification.from_pretrained(mname, torch_dtype=torch.bfloat16).cuda().eval() | |
| id2 = {int(k): v for k, v in model.config.id2label.items()} | |
| remap = np.array([LABELS.index(id2[i]) if id2[i] in LABELS else 0 for i in range(len(id2))]) | |
| r = {}; t0 = time.time() | |
| for mode in ["cased", "lower"]: | |
| texts = [lower_keep_len(it[2]) if mode == "lower" else it[2] for it in items] | |
| order = np.argsort([len(t) for t in texts]); preds = [None] * len(items) | |
| for s in range(0, len(order), 64): | |
| idx = order[s:s + 64] | |
| enc = tok([texts[i] for i in idx], truncation=True, max_length=512, padding=True, return_offsets_mapping=True, return_tensors="pt") | |
| offs = enc.pop("offset_mapping").tolist() | |
| with torch.no_grad(): | |
| pr = model(**{k: v.cuda() for k, v in enc.items()}).logits.argmax(-1).cpu().numpy() | |
| for j, i in enumerate(idx): | |
| preds[i] = unit_preds(offs[j], remap[pr[j]].tolist(), items[i][3]) | |
| cnt = {} | |
| for it, p in zip(items, preds): | |
| k = (it[0], it[1]); c = cnt.setdefault(k, np.zeros((6, 6), np.int64)) | |
| for g, q in zip(it[4], p): | |
| c[LABELS.index(g), LABELS.index(q)] += 1 | |
| for (sname, lang), c in cnt.items(): | |
| tp = sum(c[i, i] for i in range(1, 6)); fp = c[:, 1:].sum() - tp; fn = c[1:, :].sum() - tp | |
| d = r.setdefault(sname, {}).setdefault(lang, {}) | |
| d[mode] = dict(f1=2 * tp / max(1, 2 * tp + fp + fn), conf=c.tolist(), | |
| **{LABELS[i]: 2 * c[i, i] / max(1, c[i, :].sum() + c[:, i].sum()) for i in range(1, 6)}) | |
| summ = {} | |
| for sname, langs in r.items(): | |
| for mode in ["cased", "lower"]: | |
| for sub, ls in [("all", list(langs)), ("kredor12", [l for l in langs if l in KREDOR])]: | |
| if ls: | |
| summ[f"{sname}/{mode}/{sub}"] = float(np.mean([langs[l][mode]["f1"] for l in ls])) | |
| pooled = sum(np.array(langs[l][mode]["conf"]) for l in langs) | |
| for i in (1, 2, 3): | |
| summ[f"{sname}/{mode}/pooled_{LABELS[i]}"] = float(2 * pooled[i, i] / max(1, pooled[i, :].sum() + pooled[:, i].sum())) | |
| r["_summary"] = summ; res[mname] = r | |
| print(mname, f"{time.time() - t0:.0f}s", json.dumps({k: round(v, 4) for k, v in summ.items()}), flush=True) | |
| json.dump(res, open(out_f, "w")) | |
| del model; torch.cuda.empty_cache() | |