Russian Toxicity Multilabel Model
Multi-label классификатор русскоязычных текстов для трёх независимых классов:
profanity— ненормативная и оскорбительная лексика;threat— угрозы;illegal— запросы, связанные с незаконными или запрещёнными действиями.
Базовый энкодер: cointegrated/rubert-tiny2
Датасет: petaevd/russian-toxicity-multilabel
Архитектура
Один общий Transformer-энкодер и три независимые линейные головы.
Порядок выходных логитов:
[profanity, threat, illegal]
Для получения вероятностей применяется sigmoid.
Пороги
Пороги подобраны на validation по максимальному F1:
| Класс | Threshold |
|---|---|
| profanity | 0.5 |
| threat | 0.7 |
| illegal | 0.9 |
Метрики на test
| Класс | Precision | Recall | F1 |
|---|---|---|---|
| profanity | 0.771 | 0.962 | 0.856 |
| threat | 0.429 | 0.600 | 0.500 |
| illegal | 0.500 | 0.600 | 0.545 |
Macro F1: 0.634
Micro F1: 0.826
Использование
import json
import torch
import torch.nn as nn
from huggingface_hub import hf_hub_download
from safetensors.torch import load_file
from transformers import AutoModel, AutoTokenizer
REPO_ID = "petaevd/russian-toxicity-multilabel-model"
class MultiTaskToxicityEncoder(nn.Module):
def __init__(self, model_name, dropout=None):
super().__init__()
self.encoder = AutoModel.from_pretrained(model_name)
hidden_size = self.encoder.config.hidden_size
if dropout is None:
dropout = getattr(
self.encoder.config,
"hidden_dropout_prob",
0.1,
)
self.dropout = nn.Dropout(dropout)
self.profanity_head = nn.Linear(hidden_size, 1)
self.threat_head = nn.Linear(hidden_size, 1)
self.illegal_head = nn.Linear(hidden_size, 1)
def forward(self, input_ids, attention_mask):
outputs = self.encoder(
input_ids=input_ids,
attention_mask=attention_mask,
return_dict=True,
)
cls_embedding = self.dropout(
outputs.last_hidden_state[:, 0, :]
)
return torch.cat(
[
self.profanity_head(cls_embedding),
self.threat_head(cls_embedding),
self.illegal_head(cls_embedding),
],
dim=1,
)
config_path = hf_hub_download(
repo_id=REPO_ID,
filename="config.json",
)
weights_path = hf_hub_download(
repo_id=REPO_ID,
filename="model.safetensors",
)
with open(config_path, encoding="utf-8") as file:
config = json.load(file)
tokenizer = AutoTokenizer.from_pretrained(REPO_ID)
model = MultiTaskToxicityEncoder(
config["base_model"]
)
model.load_state_dict(
load_file(weights_path)
)
model.eval()
Для бинарного решения необходимо применить sigmoid и thresholds из config.json.
Ограничения
- Классы
threatиillegalпредставлены небольшим числом положительных примеров. - На ручных примерах вне test-распределения модель показала слабое обобщение для части очевидных угроз и незаконных запросов.
- Модель может путать агрессивную или насильственную лексику с прямой угрозой.
- Разметка датасета в основном автоматическая.
- Выходы
sigmoidне являются откалиброванными вероятностями.
Модель предназначена для учебных и экспериментальных задач и не должна использоваться как единственный механизм production-модерации.
- Downloads last month
- 13
Model tree for petaevd/russian-toxicity-multilabel-model
Base model
cointegrated/rubert-tiny2