spacy-fa-pipeline/configs
Mohamad Fazeli 41d5a46d96 Split the pipeline into fa_dep_news_sm + fa_ent_news_sm, drop core
spaCy's naming scheme encodes contents: dep = tagger+parser+lemmatizer,
ent = NER only, core = both. Shipping a single fa_core_news_sm implied the NER
was held to the same standard as the rest of the pipeline. It is not, and the
numbers are not close:

  UD components (PerDT, edited prose):  TAG 95.96  LEMMA 97.91  LAS 85.15
  ner           (ParsTwiNER, tweets):   ENTS_F 67.22

One package name and one version number would paper over that. So the treebank
components ship as fa_dep_news_sm (CC BY-SA 4.0, 7.5 MB) and NER ships as an
opt-in fa_ent_news_sm (MIT, 5.6 MB). Users now choose the weak component
deliberately instead of inheriting it.

Counting ParsTwiNER settles what "weak" means. It is not a small corpus --
232,917 tokens and 16,250 entities, the same order as the restricted ARMAN and
PEYMA. But the labels are skewed: PER 6258, LOC 5478, ORG 2694, NAT 939,
EVE 482, POG 399. The two starved labels are exactly the two scoring worst
(EVE 30.0, POG 41.2). Head labels suffer genre mismatch, tail labels suffer data
starvation -- two problems needing two different fixes. Recorded in README and
docs/MODELS.md.

fa_core_news_sm is reserved, not abandoned. ../ner_dataset/PLAN.md targets
prose-genre NER data that must beat ParsTwiNER on a human-annotated test set
before the name gets used. Nothing technical blocks the merge: the ner component
already embeds its own tok2vec instead of a Tok2VecListener, so

    dep.add_pipe("ner", source=spacy.load("fa_ent_news_sm"))

reassembles a core-equivalent pipeline at runtime -- verified, not assumed.

Mechanics:
- scripts/assemble_core.py -> scripts/finalize_pipeline.py, now variant-aware
  (dep|ent) and refusing to publish a dep pipeline containing an ner component,
  so the split cannot silently regress.
- published meta.json["performance"] now comes from a strict whitelist. It was
  inheriting raw *_loss values and a bogus tag_micro_f: 0.0 from training meta.
- project.yml split into two independent workflows, `all` and `ner`; all 16
  commands dry-run clean.
- configs/fa_core_news_sm.cfg -> configs/fa_dep_news_sm.cfg.
- smoke_test.py degrades gracefully on pipelines lacking DEP/MORPH/ner.

Also folded into ../ner_dataset/PLAN.md: PerDT's XPOS encodes animacy on proper
nouns (N_ANM 6752, N_IANM 12682). Animate PROPN is a strong free prior for PER,
shrinking the annotation task to splitting inanimate PROPN into LOC/ORG, and
giving a gold-grounded cross-check that beats the model's self-reported
confidence for routing items to human review.

Committed unsigned: the OpenPGP smartcard holding 05E227BF4D6736DE is not
present (gpg: selecting card failed: No such device).
2026-07-31 11:08:49 +03:30
..
fa_dep_news_sm.cfg Split the pipeline into fa_dep_news_sm + fa_ent_news_sm, drop core 2026-07-31 11:08:49 +03:30
fa_ner_sm.cfg Split the pipeline into fa_dep_news_sm + fa_ent_news_sm, drop core 2026-07-31 11:08:49 +03:30