BiLSTM — Armenian Participle-Clause Punctuation
A word-level bidirectional LSTM tagger (frozen Armenian GloVe embeddings, 300-dim; 1 layer; hidden size 128) for punctuation of Eastern Armenian participle clauses, as 4-class token labeling. From the CODASSCA 2026 paper Sequence Labeling for Low-Resource Syntax.
Labels
0 O · 1 COMMA_AFTER · 2 BUTH_AFTER · 3 REMOVE_COMMA
Results (macro-F1)
| Benchmark | macro-F1 |
|---|---|
| Gold 2K (noisy web text) | 0.4116 |
| Shtemaran 292 (clean textbook) | 0.3661 |
This is a custom PyTorch model (not a transformers architecture). Files:
bilstm_best.pt (checkpoint dict), armenian_embeddings.pt (GloVe matrix),
armenian_vocab.json (token to id), modeling_bilstm.py (the model class),
bilstm_results.json (metrics). Tokenization is word-level using the provided vocab.
Usage
import json, torch
from huggingface_hub import hf_hub_download
repo = "AlbertHakobyan/bilstm-armenian-participle-punct"
model_py = hf_hub_download(repo, "modeling_bilstm.py")
ckpt_pt = hf_hub_download(repo, "bilstm_best.pt")
vocab = json.load(open(hf_hub_download(repo, "armenian_vocab.json"), encoding="utf-8"))
exec(open(model_py, encoding="utf-8").read()) # defines BiLSTMPunctuator
ck = torch.load(ckpt_pt, map_location="cpu", weights_only=False)
hp = ck["hyperparameters"]
model = BiLSTMPunctuator(ck["vocab_size"], ck["embedding_dim"], hp["hidden_size"],
hp["num_layers"], hp["dropout"], ck["num_classes"])
model.load_state_dict(ck["model_state_dict"]); model.eval()
def tag(words):
ids = torch.tensor([[vocab.get(w, vocab.get("<UNK>", 1)) for w in words]])
with torch.no_grad():
pred = model(ids).argmax(-1)[0].tolist()
id2label = {0:"O",1:"COMMA_AFTER",2:"BUTH_AFTER",3:"REMOVE_COMMA"}
return list(zip(words, [id2label[p] for p in pred]))
Ensemble
Soft-vote with mBERT at alpha=0.45 gives the paper's best macro-F1 (0.6745, Shtemaran).