Downloads · 30 days
0
AtesiT/ru-multitask-toxicity-encoder
ru-multitask-toxicity-encoder is a text classification model from AtesiT. Use it when you need a label for a piece of text. The card lists the license as mit.
Лёгкая multi-task модель для классификации токсичности русскоязычных текстов по трём независимым категориям одновременно.
Downloads · 30 days
0
Access
Public
Updated Jul 15, 2026
Repo size
117 MB
Likes
1
Public
Click a slice to open those files.
.pt117 MB · 98%
From the Hugging Face model README
Лёгкая multi-task модель для классификации токсичности русскоязычных текстов по трём независимым категориям одновременно.
Модель построена на базе cointegrated/rubert-tiny2
с тремя независимыми классификационными головами поверх эмбеддинга [CLS] токена.
Каждая голова предсказывает один бинарный класс:
Encoder (rubert-tiny2)
└── [CLS] embedding (312-dim)
├── Dropout (p=0.2)
├── Linear(312 → 1) → profanity_logit
├── Linear(312 → 1) → threat_logit
└── Linear(312 → 1) → illegal_logit
| Класс | Порог | Precision | Recall | F1 |
|---|---|---|---|---|
| profanity | 0.60 | 0.9454 | 0.9256 | 0.9354 |
| threat | 0.75 | 1.0000 | 0.9286 | 0.9630 |
| illegal | 0.16 | 1.0000 | 1.0000 | 1.0000 |
Пороги подобраны индивидуально для каждого класса по максимуму F1-score на валидационной выборке. Классы сильно несбалансированы — это учтено через
pos_weightвBCEWithLogitsLossпри обучении.
import json
import torch
import torch.nn as nn
from transformers import AutoModel, AutoTokenizer
# 1. Загрузка токенизатора и конфига
tokenizer = AutoTokenizer.from_pretrained("AtesiT/ru-multitask-toxicity-encoder")
with open("toxicity_config.json") as f:
config = json.load(f)
# 2. Определение архитектуры
class MultiTaskToxicityEncoder(nn.Module):
def __init__(self, model_name, hidden_size, dropout=0.2):
super().__init__()
self.encoder = AutoModel.from_pretrained(model_name)
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):
out = self.encoder(input_ids=input_ids, attention_mask=attention_mask)
cls = self.dropout(out.last_hidden_state[:, 0, :])
return (
self.profanity_head(cls),
self.threat_head(cls),
self.illegal_head(cls),
)
# 3. Загрузка весов
model = MultiTaskToxicityEncoder(
model_name=config["base_model"],
hidden_size=config["hidden_size"],
)
state_dict = torch.load("model_weights.pt", map_location="cpu")
model.load_state_dict(state_dict)
model.eval()
# 4. Инференс
thresholds = config["thresholds"]
def predict(text):
enc = tokenizer(
text, return_tensors="pt",
padding="max_length", truncation=True,
max_length=config["max_length"],
)
with torch.no_grad():
p_logit, t_logit, i_logit = model(
enc["input_ids"], enc["attention_mask"]
)
probs = {
"profanity": torch.sigmoid(p_logit).item(),
"threat": torch.sigmoid(t_logit).item(),
"illegal": torch.sigmoid(i_logit).item(),
}
labels = {k: int(v >= thresholds[k]) for k, v in probs.items()}
return {"probs": probs, "labels": labels}
print(predict("Ты полный идиот, заткнись!"))
BCEWithLogitsLoss с pos_weight для каждого классаthreat, illegal) — качество на реальных данных может отличаться.MIT. Создано в учебных целях для курса по трансформерным энкодерам.