nrl-ai/vn-register-phobert-base

Model

vn-register-phobert-base

0

9 commits

1 repos using this model

1 linked in READMEs

updated May 3, 2026

See the code

README

vn-register-phobert-base

4-class Vietnamese text register classifier — labels each input as one of formal (administrative / legal) / business (news / encyclopaedic) / conversational (chat / forum) / literary (classical narrative). Use the predicted register to route a text through the right downstream checkpoint — VN diacritic / summarization / OCR-rerank checkpoints all spread 5-10 pp accuracy across registers, so a cheap router lifts every other tool automatically.

PhoBERT-base backbone (135 M params, MIT, VinAI lab) fine-tuned with a 4-way sequence-classification head. Word-segmented input via nom.text.word_tokenize per the BKai gotcha (raw text drops accuracy ≥ 15 pp on PhoBERT-style models).

Measured on test split

In-house bench, 2026-05-03, n=1234 stratified test split (CUDA, BF16):

ClassPrecisionRecallF1Support
formal0.8890.9410.91434
business0.8850.9280.906400
conversational0.8870.9450.915400
literary0.9240.8150.866400
macro avg0.8960.9070.9001234

Both adoption gates clear: macro F1 ≥ 0.85, every per-class F1 ≥ 0.75.

Source benchmarks/accuracy/register_phobert_base_baseline.json re-runnable from a clean clone via training/register/train.py.

Corpus

Source-provenance labelling — no human annotators needed. Every sentence inherits its register label from the source corpus it came from:

LabelSource(s)License
formalUDHR-vi (PD) + UDHR diacritic-eval slice (PD)Public Domain
businesswiki_vi (Wikipedia VN extracts)CC-BY-SA-4.0
conversationaltatoeba_vi 3k + tatoeba diacritic-eval-300CC-BY 2.0 FR
literarywikisource_vi (PD) + UD-VTB train/dev/testPD + CC-BY-SA-4.0

Class imbalance — formal only has 169 unique sentences (UDHR is naturally short), the others cap at 2 000 each. The 134 / 169 / 169 / 169 split per register survives the imbalance (model still hits 0.91 F1 on formal — class weighting wasn't needed). Future v2: add a permissive VN legal corpus to grow formal.

Use

from transformers import AutoTokenizer, AutoModelForSequenceClassification

tok = AutoTokenizer.from_pretrained("nrl-ai/vn-register-phobert-base")
model = AutoModelForSequenceClassification.from_pretrained("nrl-ai/vn-register-phobert-base")

# IMPORTANT: PhoBERT requires word-segmented input (multi-syllable words
# joined with underscores). Use VnCoreNLP's RDRSegmenter or nom.text:
from nom.text import normalize, word_tokenize
text = "Doanh thu công ty quý 2 năm 2026 tăng 18 %."
segmented = " ".join(t.replace(" ", "_") for t in word_tokenize(normalize(text)))

import torch
ids = tok(segmented, return_tensors="pt", truncation=True, max_length=256)
with torch.no_grad():
    logits = model(**ids).logits
probs = torch.softmax(logits, dim=-1).squeeze().tolist()
labels = ["formal", "business", "conversational", "literary"]
for label, p in sorted(zip(labels, probs), key=lambda x: -x[1]):
    print(f"  {label:<15} {p:.3f}")
# →   business        0.952
#     formal          0.029
#     conversational  0.012
#     literary        0.007

Or via the nom-vn wrapper:

from nom.classify import PhoBertRegisterClassifier
clf = PhoBertRegisterClassifier()  # default model_id = this repo
result = clf.predict("Doanh thu công ty quý 2 năm 2026 tăng 18 %.")
print(result.label, result.score, result.distribution)

Honesty notes

  • Tested only on held-out 20 % of source-provenance corpus. A sentence labelled "formal" because it came from UDHR is a single data-distribution slice — real-world legal prose may shift. A genre classifier this scale needs cross-corpus eval (e.g. legal_vi from th1nhng0) before adoption claims beyond routing.
  • literary recall 0.815 < precision 0.924. When the model says "literary," it's usually right; when something IS literary, the model misses ~18 % to other classes (mostly to formal because of shared archaic vocab). Acceptable for routing — false negatives fall back to a sensible default.
  • Word-segmentation matters. Skip word_tokenize and accuracy drops 10-15 pp. The wrapper handles this; if you call the model directly, you must segment.

Citation

@misc{nguyen_vn_register_phobert_base_2026,
  author = {Nguyen, Viet-Anh and {Neural Research Lab}},
  title  = {{vn-register-phobert-base: A 4-class Vietnamese text-register
             classifier (formal / business / conversational / literary)}},
  year   = {2026},
  url    = {https://huggingface.co/nrl-ai/vn-register-phobert-base}
}

License: MIT (matches PhoBERT-base backbone).

Maintained as part of the nom-vn project by Viet-Anh Nguyen ([email protected]) and Neural Research Lab.

endpoints_compatible
nrl-ai
phobert
register-classification
roberta
safetensors
text-classification
transformers
vietnamese

nrl-ai/vn-register-phobert-base

Model

vn-register-phobert-base

0

9 commits

1 repos using this model

1 linked in READMEs

updated May 3, 2026

See the code

README

vn-register-phobert-base

4-class Vietnamese text register classifier — labels each input as one of formal (administrative / legal) / business (news / encyclopaedic) / conversational (chat / forum) / literary (classical narrative). Use the predicted register to route a text through the right downstream checkpoint — VN diacritic / summarization / OCR-rerank checkpoints all spread 5-10 pp accuracy across registers, so a cheap router lifts every other tool automatically.

PhoBERT-base backbone (135 M params, MIT, VinAI lab) fine-tuned with a 4-way sequence-classification head. Word-segmented input via nom.text.word_tokenize per the BKai gotcha (raw text drops accuracy ≥ 15 pp on PhoBERT-style models).

Measured on test split

In-house bench, 2026-05-03, n=1234 stratified test split (CUDA, BF16):

ClassPrecisionRecallF1Support
formal0.8890.9410.91434
business0.8850.9280.906400
conversational0.8870.9450.915400
literary0.9240.8150.866400
macro avg0.8960.9070.9001234

Both adoption gates clear: macro F1 ≥ 0.85, every per-class F1 ≥ 0.75.

Source benchmarks/accuracy/register_phobert_base_baseline.json re-runnable from a clean clone via training/register/train.py.

Corpus

Source-provenance labelling — no human annotators needed. Every sentence inherits its register label from the source corpus it came from:

LabelSource(s)License
formalUDHR-vi (PD) + UDHR diacritic-eval slice (PD)Public Domain
businesswiki_vi (Wikipedia VN extracts)CC-BY-SA-4.0
conversationaltatoeba_vi 3k + tatoeba diacritic-eval-300CC-BY 2.0 FR
literarywikisource_vi (PD) + UD-VTB train/dev/testPD + CC-BY-SA-4.0

Class imbalance — formal only has 169 unique sentences (UDHR is naturally short), the others cap at 2 000 each. The 134 / 169 / 169 / 169 split per register survives the imbalance (model still hits 0.91 F1 on formal — class weighting wasn't needed). Future v2: add a permissive VN legal corpus to grow formal.

Use

from transformers import AutoTokenizer, AutoModelForSequenceClassification

tok = AutoTokenizer.from_pretrained("nrl-ai/vn-register-phobert-base")
model = AutoModelForSequenceClassification.from_pretrained("nrl-ai/vn-register-phobert-base")

# IMPORTANT: PhoBERT requires word-segmented input (multi-syllable words
# joined with underscores). Use VnCoreNLP's RDRSegmenter or nom.text:
from nom.text import normalize, word_tokenize
text = "Doanh thu công ty quý 2 năm 2026 tăng 18 %."
segmented = " ".join(t.replace(" ", "_") for t in word_tokenize(normalize(text)))

import torch
ids = tok(segmented, return_tensors="pt", truncation=True, max_length=256)
with torch.no_grad():
    logits = model(**ids).logits
probs = torch.softmax(logits, dim=-1).squeeze().tolist()
labels = ["formal", "business", "conversational", "literary"]
for label, p in sorted(zip(labels, probs), key=lambda x: -x[1]):
    print(f"  {label:<15} {p:.3f}")
# →   business        0.952
#     formal          0.029
#     conversational  0.012
#     literary        0.007

Or via the nom-vn wrapper:

from nom.classify import PhoBertRegisterClassifier
clf = PhoBertRegisterClassifier()  # default model_id = this repo
result = clf.predict("Doanh thu công ty quý 2 năm 2026 tăng 18 %.")
print(result.label, result.score, result.distribution)

Honesty notes

  • Tested only on held-out 20 % of source-provenance corpus. A sentence labelled "formal" because it came from UDHR is a single data-distribution slice — real-world legal prose may shift. A genre classifier this scale needs cross-corpus eval (e.g. legal_vi from th1nhng0) before adoption claims beyond routing.
  • literary recall 0.815 < precision 0.924. When the model says "literary," it's usually right; when something IS literary, the model misses ~18 % to other classes (mostly to formal because of shared archaic vocab). Acceptable for routing — false negatives fall back to a sensible default.
  • Word-segmentation matters. Skip word_tokenize and accuracy drops 10-15 pp. The wrapper handles this; if you call the model directly, you must segment.

Citation

@misc{nguyen_vn_register_phobert_base_2026,
  author = {Nguyen, Viet-Anh and {Neural Research Lab}},
  title  = {{vn-register-phobert-base: A 4-class Vietnamese text-register
             classifier (formal / business / conversational / literary)}},
  year   = {2026},
  url    = {https://huggingface.co/nrl-ai/vn-register-phobert-base}
}

License: MIT (matches PhoBERT-base backbone).

Maintained as part of the nom-vn project by Viet-Anh Nguyen ([email protected]) and Neural Research Lab.

endpoints_compatible
nrl-ai
phobert
register-classification
roberta
safetensors
text-classification
transformers
vietnamese