IvanFed/russian-toxic-comments-multilabel
Viewer • Updated • 248k • 24
Эта модель является Multi-Task классификатором токсичности на основе легковесного энкодера cointegrated/rubert-tiny2. Она обучена одновременно предсказывать три класса токсичности:
Модель имеет три независимые головы (линейные слоя), каждая из которых выдает логит для своего класса. Вероятности получаются применением сигмоиды.
Модель обучена на датасете Russian Toxic Comments Multi-label, содержащем 248,288 размеченных комментариев из социальной сети ok.ru.
| Class | Threshold | Precision | Recall | F1-Score |
|---|---|---|---|---|
| Profanity | 0.45 | 0.8921 | 0.8969 | 0.8945 |
| Threat | 0.35 | 0.7654 | 0.7998 | 0.7823 |
| Illegal | 0.50 | 0.0000 | 0.0000 | 0.0000 |
Примечание: Класс illegal отсутствует в датасете, поэтому метрики равны нулю.
pip install torch transformers huggingface-hub
import torch
from transformers import AutoTokenizer
import json
tokenizer = AutoTokenizer.from_pretrained("IvanFed/rubert-toxicity-multitask")
with open("thresholds.json", "r") as f:
thresholds = json.load(f)
class MultiTaskToxicityEncoder(torch.nn.Module):
def __init__(self, model_name="cointegrated/rubert-tiny2"):
super().__init__()
from transformers import AutoModel
self.encoder = AutoModel.from_pretrained(model_name)
self.hidden_size = self.encoder.config.hidden_size
self.dropout = torch.nn.Dropout(0.1)
self.profanity_head = torch.nn.Linear(self.hidden_size, 1)
self.threat_head = torch.nn.Linear(self.hidden_size, 1)
self.illegal_head = torch.nn.Linear(self.hidden_size, 1)
def forward(self, input_ids, attention_mask):
outputs = self.encoder(input_ids=input_ids, attention_mask=attention_mask)
cls_embedding = outputs.last_hidden_state[:, 0, :]
cls_embedding = self.dropout(cls_embedding)
return (
self.profanity_head(cls_embedding),
self.threat_head(cls_embedding),
self.illegal_head(cls_embedding)
)
model = MultiTaskToxicityEncoder()
model.load_state_dict(torch.load("pytorch_model.bin", map_location="cpu"))
model.eval()
def predict_toxicity(text, threshold_dict=thresholds):
encoded = tokenizer(text, truncation=True, padding='max_length', max_length=128, return_tensors='pt')
with torch.no_grad():
profanity_logits, threat_logits, illegal_logits = model(encoded['input_ids'], encoded['attention_mask'])
profanity_prob = torch.sigmoid(profanity_logits).item()
threat_prob = torch.sigmoid(threat_logits).item()
illegal_prob = torch.sigmoid(illegal_logits).item()
return {
'profanity': {'probability': profanity_prob, 'prediction': profanity_prob >= threshold_dict.get('Profanity', 0.5)},
'threat': {'probability': threat_prob, 'prediction': threat_prob >= threshold_dict.get('Threat', 0.5)},
'illegal': {'probability': illegal_prob, 'prediction': illegal_prob >= threshold_dict.get('Illegal', 0.5)}
}
text = "Ты дурак!"
print(predict_toxicity(text))
cointegrated/rubert-tiny2illegal отсутствует в обучающем датасете, поэтому модель не может его обнаружить.threat рекомендуется собрать дополнительные данные.Благодарность авторам оригинального датасета Toxic Russian Comments за предоставленные данные.
Если вы используете эту модель в своей работе, пожалуйста, ссылайтесь на:
@misc{rubert_toxicity_multitask,
author = {IvanFed},
title = {RuBERT Multi-Task Toxicity Classifier},
year = {2026},
publisher = {Hugging Face},
howpublished = {\url{https://huggingface.co/IvanFed/rubert-toxicity-multitask}}
}