SyntaxError
Update README.md
b547e14 verified
|
Raw
History Blame Contribute Delete
10.6 kB
---
language:
- ru
tags:
- text-classification
- moderation
- toxicity
- spam-detection
- toxic-detection
- cyberbullying-detection
- russian
- cyberbullying
- bert
- NLP
- rubert
license: mit
base_model: DeepPavlov/rubert-base-cased
---
# AIMS — AI Moderation System
**AIMS** — многоклассовая модель классификации текста для автоматической модерации русскоязычных чатов. Определяет токсичный контент, спам, коммерческие объявления и другие нарушения.
Модель построена на базе [`DeepPavlov/rubert-base-cased`](https://huggingface.co/DeepPavlov/rubert-base-cased) с дополнительной головой классификатора (multi-head pooling: CLS + mean + max).
Модель может использоваться для автоматической модерации русскоязычных онлайн-сообществ.
*Мой TON (Gram) Крипто-кошелек. Если вы хотите поддержать проект: UQDB_yClLEoQMzfxFz1XoTa-bH0mPEiDfGhLhC3igJV4HrSL*
---
## Классы
| Класс | Описание |
|---|---|
| `SAFE` | Безопасное сообщение, нарушений не обнаружено |
| `OSK` | Оскорбления — кибербуллинг, агрессия, унижение |
| `RUDELY_OSK` | Грубые оскорбления — мат в адрес родственников, несколько оскорблений в одном сообщении |
| `SPAM` | Спам — реклама, предложения работы, навязчивые рассылки |
| `SELL` | Коммерция — объявления о покупке/продаже, обмене |
| `ADULT` | Сексуальный контент — текстовые предложения интима, различные грубые выражения |
| `PLS` | Попрошайничество - навязчивые просьбы о денежном вознаграждении *(бета-тест)* |
> ⚠️ Модель работает **исключительно с русскоязычным текстом**.
---
## Характеристики
| Параметр | Значение |
|---|---|
| Базовая модель | `DeepPavlov/rubert-base-cased` |
| Архитектура | BERT + multi-head pooling + Linear classifier |
| Макс. длина токенов | 40 |
| Количество классов | 7 |
| Язык | Русский |
| Источник данных | Активные Telegram-чаты |
---
## Датасет
Модель обучена на собственном датасете из **27 000 примеров**, собранных в русскоязычных Telegram-чатах летом и осенью 2025 года.
- Разметка: частично выполнена вручную человеком, частично с помощью **DeepSeek**
- Источник: живые сообщения из публичных Telegram-чатов
- Баланс классов: компенсируется оверсэмплингом редких классов и взвешенным `CrossEntropyLoss`
---
## Метрики
Тестирование проводилось на внешних датасетах с HuggingFace с бинарной разметкой (плохое/хорошее). Оценивалась способность модели детектировать целевой класс среди немеченых плохих сообщений.
Все метрики приведены для порога уверенности **≥ 90%** (рекомендуемый порог уверенности модели).
### Токсичность (OSK + RUDELY_OSK)
Для оценки эффективности модели использовались открытые наборы данных, охватывающие различные задачи автоматической модерации русскоязычного контента.
Тестирование проводилось на следующих датасетах:
- **AlexSham/Toxic_Russian_Comments** — набор данных, содержащий русскоязычные комментарии с разметкой токсичности. Использовался для оценки качества обнаружения токсичных высказываний.
Тест на датасете с оскорбительными сообщениями (Взятый обьем: 22 000 примеров, ~18 000 SAFE / ~4 000 BAD). **AlexSham/Toxic_Russian_Comments**
| Метрика | Значение |
|---|---|
| **Precision** | 91.3% |
| **Recall** | 95.7% |
| **F1-score** | 93.5% |
### Спам (SPAM)
- **alt-gnome/telegram-spam** — набор сообщений из Telegram с разметкой на спам и легитимные сообщения. Использовался для оценки качества обнаружения спам-контента в условиях, приближенных к реальной эксплуатации.
Тест на датасете спам сообщений (Взятый обьем: 15 000 примеров, ~10 000 SAFE / ~5 000 BAD).
| Метрика | Значение |
|---|---|
| **Precision** | 93.6% |
| **Recall** | 96.8% |
| **F1-score** | 95.2% |
---
## Использование
### Установка зависимостей
```bash
pip install torch transformers
```
### Быстрый старт
```python
import torch
import torch.nn as nn
import pickle
import json
import numpy as np
from transformers import AutoTokenizer, AutoModel
MODEL_DIR = "path/to/aims-model"
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# Загрузка конфига
with open(f"{MODEL_DIR}/config.json") as f:
config = json.load(f)
with open(f"{MODEL_DIR}/label_encoder.pkl", "rb") as f:
label_encoder = pickle.load(f)
# Определение архитектуры
class AIMSModel(nn.Module):
def __init__(self, model_name, num_classes):
super().__init__()
self.encoder = AutoModel.from_pretrained(model_name, low_cpu_mem_usage=True)
hidden = self.encoder.config.hidden_size
self.classifier = nn.Sequential(
nn.Dropout(0.2),
nn.Linear(hidden * 3, 512),
nn.GELU(),
nn.Dropout(0.1),
nn.Linear(512, num_classes)
)
def forward(self, input_ids, attention_mask):
hs = self.encoder(input_ids=input_ids, attention_mask=attention_mask).last_hidden_state
cls_p = hs[:, 0]
mask = attention_mask.unsqueeze(-1).float()
mean_p = (hs * mask).sum(1) / mask.sum(1).clamp(min=1e-9)
max_p = hs.masked_fill(attention_mask.unsqueeze(-1) == 0, float('-inf')).max(dim=1).values
return self.classifier(torch.cat([cls_p, mean_p, max_p], dim=-1))
# Загрузка модели
tokenizer = AutoTokenizer.from_pretrained(MODEL_DIR)
model = AIMSModel(config["model"], config["num_classes"]).to(DEVICE)
model.load_state_dict(torch.load(f"{MODEL_DIR}/pytorch_model.bin", map_location=DEVICE, weights_only=True))
model.eval()
# Инференс
def predict(text: str) -> dict:
enc = tokenizer(text, truncation=True, padding="max_length",
max_length=config["max_length"], return_tensors="pt")
with torch.no_grad():
logits = model(enc["input_ids"].to(DEVICE), enc["attention_mask"].to(DEVICE))
probs = torch.softmax(logits, dim=-1).squeeze().cpu().numpy()
idx = int(np.argmax(probs))
return {
"label": label_encoder.classes_[idx],
"confidence": float(probs[idx]),
"probs": dict(zip(label_encoder.classes_, probs.tolist()))
}
# Пример
result = predict("продам аккаунт за 500 звёзд, пишите в лс")
print(result)
# {'label': 'SELL', 'confidence': 0.99, 'probs': {...}}
```
### Рекомендуемая логика принятия решения
```python
FINAL_THRESHOLD = 0.90 # окончательное решение
WARNING_THRESHOLD = 0.80 # предупреждение, требуется проверка
def moderate(text: str) -> dict:
result = predict(text)
conf = result["confidence"]
label = result["label"]
if label == "SAFE":
verdict = "safe"
elif conf >= FINAL_THRESHOLD:
verdict = "block" # высокая уверенность — блокировать
elif conf >= WARNING_THRESHOLD:
verdict = "review" # средняя уверенность — на проверку модератору
else:
verdict = "safe" # низкая уверенность — пропустить
return {"verdict": verdict, "label": label, "confidence": conf}
```
> **Рекомендация:** используйте порог **90-95%**- как границу для автоматической блокировки. При уверенности 80–90% — передавайте сообщение на ручную проверку. Ниже 80% — считайте сообщение безопасным.
---
## Ограничения
- Модель оптимизирована для **коротких сообщений** (до 40 токенов). Длинные тексты обрезаются.
- Класс `PLS` (попрошайничество) находится в **бета-тестировании** — точность ниже остальных классов из-за малого количества обучающих примеров.
- Модель не адаптирована для официальных текстов или новостных материалов.
- Возможны ложные срабатывания на текстах с нецензурной лексикой в нейтральном контексте (цитаты, художественные тексты).
---
## Лицензия
MIT
---
## Цитирование
```bibtex
@misc{aims2025,
author = {JustDev23},
title = {AIMS: AI Moderation System},
year = {2025},
publisher = {Hugging Face},
note = {Trained on proprietary Telegram dataset collected during summer--autumn 2025}
}
```