Downloads · 30 days
42
14% of all-time downloads
NTA1802/NER-Completing-With-Legal-Dataset
NER-Completing-With-Legal-Dataset is a token classification model from NTA1802. Use it when you need labels on individual words, such as names. It is set up for transformers. The card lists the license as mit.
Mô hình Named Entity Recognition (NER) cho văn bản pháp lý tiếng Việt, fine-tune từ NlpHUST/ner-vietnamese-electra-base trên bộ dữ liệu pháp lý tự xây dựng với BIO tagging scheme, 63 loại thực thể và 125 nhãn (1 O + c…
Downloads · 30 days
42
14% of all-time downloads
All-time downloads
290
Public
Parameters
133M
533 MB on disk
Likes
2
Public
Click a slice to open those files.
.safetensors533 MB · 100%
From the Hugging Face model README
Mô hình Named Entity Recognition (NER) cho văn bản pháp lý tiếng Việt, fine-tune từ NlpHUST/ner-vietnamese-electra-base trên bộ dữ liệu pháp lý tự xây dựng với BIO tagging scheme, 63 loại thực thể và 125 nhãn (1 O + các tag B-/I-; riêng ARTICLE và LOCATION chỉ xuất hiện dạng B-).
Phạm vi: 3 luật — Luật Viễn thông, Luật An ninh mạng, Luật Công nghệ thông tin (cùng các văn bản hướng dẫn liên quan).
125 nhãn BIO (1 O + 62 loại × 2 prefix B/I) thuộc 7 nhóm: văn bản pháp lý, chủ thể, khái niệm pháp lý, an ninh mạng, hạ tầng & kỹ thuật, tiêu chuẩn & quy định, và các thực thể khác (địa điểm, thời gian, mức độ...).
-1000.9 — backbone LR 3e-5, classifier head LR 1e-4warmup_ratio=0.1), weight decay 0.01, gradient clipping 1.00.1eval_f1 (seqeval entity-level), patience 5DataCollatorForTokenClassification42| Split | Số câu |
|---|---|
| Train | 6 403 |
| Validation | 1 279 |
| Test | 1 288 |
Dataset: JSONL format, mỗi dòng gồm tokens (list) và labels (list BIO labels) — ngoài ra có thêm id và sentence. Lưu ý tokens đã được word-tokenize sẵn (token dạng Bộ_Công_an, an_ninh_mạng).
Train 30 epoch (early stopping theo eval_f1), GPU NVIDIA RTX PRO 6000 Blackwell, ~262 s — train_loss ≈ 1.09 (đã gồm label smoothing 0.1). Metric seqeval entity-level:
| Split | Precision | Recall | F1 |
|---|---|---|---|
| Validation | 0.9965 | 0.9970 | 0.9968 |
| Test | 0.9960 | 0.9976 | 0.9968 |
Trên tập test (7 804 thực thể), theo classification_report:
| Precision | Recall | F1 | |
|---|---|---|---|
| micro avg | 0.9960 | 0.9976 | 0.9968 |
| macro avg | 0.9896 | 0.9963 | 0.9926 |
| weighted avg | 0.9961 | 0.9976 | 0.9968 |
Phần lớn entity type đạt F1 = 1.0. Các type có support lớn: OBLIGATION (1079, F1 1.00), LEGAL_ACTOR (1025, F1 0.996), LEGAL_ACTION (940, F1 0.997), LAW (690, F1 1.00), TIME (556, F1 0.998), SANCTION (485, F1 0.998), SYSTEM (327, F1 0.989). Các type F1 thấp nhất đều thuộc nhóm support rất nhỏ: AUTHORIZATION (0.857, support 3), AUDIT (0.933, 7), LICENSE (0.947, 19), LEGAL_CONCEPT (0.952, 31), PERMISSION (0.964, 28).
⚠️ F1 ≈ 0.997 phản ánh dữ liệu được sinh khá theo khuôn mẫu (template) — số liệu trên domain văn bản pháp lý thực tế, đa dạng hơn, sẽ thấp hơn đáng kể.
⚠️ Quan trọng: model được train trên dữ liệu đã word-tokenize (token dạng
Bộ_Công_an,an_ninh_mạng, ...). Khi inference bắt buộc phải word-tokenize trước rồi truyền vớiis_split_into_words=True— nếu truyền raw text thẳng vào tokenizer/pipeline, entity sẽ lệch hoàn toàn.
import torch
from pyvi import ViTokenizer
from transformers import AutoTokenizer, AutoModelForTokenClassification
MODEL_DIR = "NTA1802/NER-Completing-With-Legal-Dataset"
tok = AutoTokenizer.from_pretrained(MODEL_DIR, use_fast=True)
mdl = AutoModelForTokenClassification.from_pretrained(MODEL_DIR).eval()
id2label = mdl.config.id2label
@torch.no_grad()
def extract_entities(text: str):
words = ViTokenizer.tokenize(text).split()
enc = tok(words, is_split_into_words=True, return_tensors="pt", truncation=True)
pred_ids = mdl(**enc).logits[0].argmax(-1).tolist()
word_ids = enc.word_ids(0)
word_label = [None] * len(words)
seen = set()
for j, wid in enumerate(word_ids):
if wid is None or wid in seen:
continue
seen.add(wid)
word_label[wid] = id2label[pred_ids[j]]
entities, cur = [], None
for w, lab in zip(words, word_label):
if lab in (None, "O"):
if cur: entities.append(cur); cur = None
continue
prefix, _, etype = lab.partition("-")
if prefix == "B" or cur is None or cur["type"] != etype:
if cur: entities.append(cur)
cur = {"type": etype, "text": w.replace("_", " ")}
else:
cur["text"] += " " + w.replace("_", " ")
if cur: entities.append(cur)
return entities
print(extract_entities("Khoản 1 Điều 46 Luật An ninh mạng quy định về bảo vệ dữ liệu cá nhân."))
NlpHUST/ner-vietnamese-electra-base (ELECTRA-base, 12 layers, hidden 768)