Views
No views yet
vinai/phobert-large. Khác với các mô hình phân loại văn bản thông thường (Sentence Classification) chỉ đưa ra kết quả nhị phân (Có/Không), mô hình này được thiết kế để giải quyết bài toán Sequence Labeling (Gán nhãn chuỗi) bằng định dạng BIO, nhằm định vị chính xác vị trí của từ lóng, teencode, và ngôn từ xúc phạm trong câu.Linear Classifier được tùy chỉnh bằng PyTorch để xuất ra 3 nhãn riêng biệt cho từng token.vi).O (0): Outside - Từ bình thường, an toàn.B-T (1): Begin Toxic - Token đầu tiên của một cụm từ độc hại.I-T (2): Inside Toxic - Các token tiếp theo nằm bên trong cụm từ độc hại.B-T).B-T (đạt F1 0.64) là đã đủ cơ sở để kích hoạt cờ cảnh báo (flag) và ngăn chặn bình luận độc hại.I-T thấp hơn B-T).I-T không được đứng trước B-T), kỳ vọng sẽ kéo điểm Span F1 lên mức ≥0.60.PhoBERTForBIOTagging) thay vì lớp AutoModelForTokenClassification mặc định. Do đó, bạn cần tải file trọng số .pt và thiết lập kiến trúc thủ công như sau:1import torch
2import torch.nn as nn
3from transformers import AutoTokenizer, XLMRobertaModel
4from huggingface_hub import hf_hub_download
5
6# 1. Định nghĩa lại kiến trúc Model tùy chỉnh
7class PhoBERTForBIOTagging(nn.Module):
8 def __init__(self, backbone: XLMRobertaModel, num_labels: int = 3, dropout: float = 0.1):
9 super().__init__()
10 self.bert = backbone
11 self.dropout = nn.Dropout(dropout)
12 self.classifier = nn.Linear(backbone.config.hidden_size, num_labels)
13
14 def forward(self, input_ids, attention_mask):
15 outputs = self.bert(input_ids=input_ids, attention_mask=attention_mask)
16 sequence_output = self.dropout(outputs.last_hidden_state)
17 return self.classifier(sequence_output)
18
19device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
20
21# 2. Tải Tokenizer và Base Backbone
22backbone_name = "vinai/phobert-large"
23tokenizer = AutoTokenizer.from_pretrained(backbone_name)
24backbone = XLMRobertaModel.from_pretrained(backbone_name)
25backbone.resize_token_embeddings(len(tokenizer))
26
27# 3. Tải file Weights (.pt) từ Hugging Face Hub
28REPO_ID = "Minhtan210905/PhoBERT-BIO-Sequence-Labeling"
29weights_path = hf_hub_download(repo_id=REPO_ID, filename="phobert_bio_best.pt")
30
31# 4. Khởi tạo mô hình và nạp trọng số
32model = PhoBERTForBIOTagging(backbone=backbone, num_labels=3)
33model.load_state_dict(torch.load(weights_path, map_location=device))
34model.eval().to(device)
35
36def extract_toxic_spans(text):
37 inputs = tokenizer(text, return_tensors="pt", truncation=True, max_length=128).to(device)
38
39 with torch.no_grad():
40 logits = model(inputs["input_ids"], inputs["attention_mask"])
41
42 preds = logits.argmax(dim=-1)[0].cpu().numpy()
43 tokens = tokenizer.convert_ids_to_tokens(inputs["input_ids"][0])
44
45 real_len = int(inputs["attention_mask"][0].sum())
46 body_preds = preds[1 : real_len - 1]
47 body_tokens = tokens[1 : real_len - 1]
48
49 toxic_words = []
50 current_word = ""
51
52 for token, label in zip(body_tokens, body_preds):
53 clean_token = token.replace("@@", "").replace("_", " ")
54 if label == 1: # B-T
55 if current_word: toxic_words.append(current_word.strip())
56 current_word = clean_token
57 elif label == 2: # I-T
58 current_word += clean_token
59 else: # O
60 if current_word:
61 toxic_words.append(current_word.strip())
62 current_word = ""
63
64 if current_word: toxic_words.append(current_word.strip())
65 return toxic_words
66
67# --- Chạy thử nghiệm ---
68test_text = "thằng này là đồ ngu đần học dốt vl"
69violation_words = extract_toxic_spans(test_text)
70
71print(f"Câu gốc: {test_text}")
72print(f"Các từ lóng vi phạm bị bắt: {violation_words}")
73# Kì vọng Output: ['ngu đần', 'vl']