Download tests/test_data.py from Ericu950/Stoicheia-code: direct link, hf CLI and curl.
- Browser
- Download file 3.53 kB
-
https://huggingface.co/Ericu950/Stoicheia-code/resolve/main/tests/test_data.py
- Command line
-
hf download hf://Ericu950/Stoicheia-code/tests/test_data.py
-
curl -L -o test_data.py https://huggingface.co/Ericu950/Stoicheia-code/resolve/main/tests/test_data.py
3.53 kB
| import os | |
| from pathlib import Path | |
| import numpy as np | |
| import pytest | |
| from tagger.backbone import restore_polytonic | |
| from tagger.conllu import read_conllu, write_conllu | |
| from tagger.dataset import TaggerDataset, batch_rows, encode_sentence, encode_word, pack_rows | |
| from tagger.edits import LabelVocab, form_key | |
| KFOLD = Path(os.path.expandvars(os.environ.get("TAGGER_KFOLD", | |
| "$STOICHEIA_DATA/treebanks/oga_repo/kfold"))) | |
| pytestmark = pytest.mark.skipif( | |
| not (KFOLD / "dev0.conllu").is_file(), | |
| reason="TAGGER_KFOLD not set to a checkout of the OGA treebank k-fold split") | |
| def sents(): | |
| out = [] | |
| for i, s in enumerate(read_conllu(KFOLD / "dev0.conllu")): | |
| if i >= 200: | |
| break | |
| out.append(s) | |
| return out | |
| def vocab(sents): | |
| return LabelVocab.build(sents, lambda f: encode_word(f) is not None) | |
| def test_conllu_roundtrip(tmp_path, sents): | |
| preds = [[(t.lemma, t.upos, t.xpos) for t in s.tokens] for s in sents] | |
| write_conllu(sents, preds, tmp_path / "rt.conllu") | |
| back = list(read_conllu(tmp_path / "rt.conllu")) | |
| assert len(back) == len(sents) | |
| for a, b in zip(sents, back): | |
| assert [t.form for t in a.tokens] == [t.form for t in b.tokens] | |
| assert [t.xpos for t in a.tokens] == [t.xpos for t in b.tokens] | |
| def test_span_alignment(sents, vocab): | |
| """restore_polytonic over each word span must reproduce the FORM (mod key-folding).""" | |
| checked = 0 | |
| for s in sents: | |
| e = encode_sentence(s, vocab) | |
| if e is None: | |
| continue | |
| # per-word cap plane is discarded in SentEnc; re-encode per word for the check | |
| for t, span in zip(s.tokens, e.spans): | |
| if span is None: | |
| continue | |
| enc = encode_word(t.form) | |
| chars, dia, cap = enc | |
| s0, s1 = span | |
| assert np.array_equal(e.chars[s0:s1], chars) | |
| words = restore_polytonic(chars, dia, cap, np.array([0] * (len(chars) - 1) + [1])) | |
| assert len(words) == 1 | |
| # restored span == FORM restricted to Greek letters+marks (the char stream | |
| # drops apostrophes/brackets/digits; macron/breve/underdot are stripped marks) | |
| import unicodedata | |
| target = "".join( | |
| c for c in unicodedata.normalize("NFD", t.form) | |
| if unicodedata.category(c) in ("Ll", "Lu", "Lo") or c in "́̀͂̓̔̈ͅ") | |
| target = unicodedata.normalize("NFC", target) | |
| assert form_key(words[0]).replace("ς", "σ") == form_key(target).replace("ς", "σ"), (t.form, words[0]) | |
| checked += 1 | |
| assert checked > 500 | |
| def test_packing_invariants(sents, vocab): | |
| ds = TaggerDataset(sents, vocab, T=1024, W=256) | |
| rows, trunc = pack_rows(ds.encs, 1024, 256) | |
| batch = batch_rows(rows[:4], 1024, 256) | |
| ids, seg, wid = batch["input_ids"], batch["seg_id"], batch["word_id"] | |
| assert ids.shape == seg.shape == wid.shape | |
| # pads are exactly where seg==0, and pads carry pad_id | |
| assert bool(((ids == 26) == (seg == 0)).all()) | |
| # every labeled word slot has at least one char pointing at it | |
| for b in range(ids.shape[0]): | |
| labeled = (batch["y_script"][b] != -100).nonzero().flatten().tolist() | |
| pointed = set(wid[b][wid[b] >= 0].tolist()) | |
| assert set(labeled) <= pointed | |
| # slots align with labels | |
| for b, rs in enumerate(batch["slots"]): | |
| assert len(rs) == len(set(wid[b][wid[b] >= 0].tolist())) | |