Skip to content

🚀 Production-ready API for detecting toxic comments in Russian text, powered by a lightweight PyTorch CNN model (~5MB).

License

Notifications You must be signed in to change notification settings

Runoi/lightweight-toxic-classifier

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Легковесный классификатор токсичных комментариев

Этот проект представляет собой полный цикл разработки production-ready ML-сервиса: от обучения и отладки легковесной модели для классификации токсичности в русскоязычных комментариях до ее упаковки в API с использованием FastAPI.

🚀 Ключевые особенности

  • Сверхлегковесная модель: Квантованная CNN-модель весит ~5 МБ, что идеально для быстрого развертывания.
  • Высокая производительность: Время инференса на CPU составляет единицы миллисекунд.
  • Production-Ready API: Готовый к развертыванию API-сервис на FastAPI с документацией Swagger.
  • Чистая архитектура: Проект структурирован по принципам SOLID, DRY, KISS и ООП для легкой поддержки и масштабирования.
  • Воспроизводимость: Проект включает Jupyter-блокнот для полного воспроизведения процесса обучения и оптимизации модели.

🛠️ Технологический стек

  • Машинное обучение: Python, PyTorch, Natasha, scikit-learn
  • API: FastAPI, Pydantic, Uvicorn
  • Развертывание: Docker
  • Среда разработки: Jupyter Notebook (Kaggle), VS Code

📂 Структура проекта

Проект имеет логическую структуру, разделяющую данные, код обучения, обученные модели и код приложения.

AI_Toxic/
│
├── .gitignore             # Исключение ненужных файлов из Git
├── README.md              # Этот файл
│
├── data/                  # Данные для обучения
│   └── raw/
│       └── dataset.csv
│
├── models/                # Обученные модели и артефакты
│   └── v1.0/
│       ├── solo_cnn_fp32.pth  (мастер-модель)
│       ├── solo_cnn_int8.pth  (модель для API)
│       └── vocab.json         (словарь)
│
├── notebooks/             # Jupyter-блокнот с процессом обучения
│   └── cnn_training.ipynb
│
└── api/                   # Код API-сервиса
    ├── main.py
    ├── classifier.py
    ├── preprocessor.py
    ├── schemas.py
    ├── config.py
    ├── requirements.txt
    └── Dockerfile

⚙️ Установка и настройка

Все команды выполняются из корневой папки проекта (AI_Toxic/).

  1. Клонируйте репозиторий:

    git clone [URL вашего репозитория]
    cd AI_Toxic
  2. Создайте и активируйте виртуальное окружение:

    python -m venv venv
    # Для Windows:
    # venv\Scripts\activate
    # Для macOS/Linux:
    # source venv/bin/activate
  3. Установите зависимости: Проект имеет два набора зависимостей: для обучения и для API.

    # Зависимости для запуска API
    pip install -r api/requirements.txt
    
    # Зависимости для запуска Jupyter-блокнота
    # Рекомендуется создать отдельный requirements.txt для блокнота
    pip install pandas jupyter scikit-learn

🚀 Порядок работы

1. Обучение модели (для воспроизведения)

  • Откройте и запустите ячейки в блокноте notebooks/cnn_training.ipynb.
  • Этот блокнот выполнит все шаги: от предобработки данных до обучения, оценки и квантизации модели.
  • В результате в папке models/v1.0/ будут созданы все необходимые артефакты (.pth файлы и vocab.json).

2. Запуск API (для использования)

Вы можете запустить API локально для разработки или через Docker для продакшена.

Локальный запуск:

# Убедитесь, что вы находитесь в корне проекта AI_Toxic/ и venv активировано
uvicorn api.main:app --reload

Откройте в браузере http://127.0.0.1:8000/docs для доступа к интерактивной документации.

Запуск через Docker:

1. Сборка образа

docker build -t toxic-classifier-api . -f api/Dockerfile

2. Запуск контейнера

docker run -d -p 8000:8000 --name my-toxic-api toxic-classifier-api```

📊 Результаты и производительность

Финальная модель версии v1.0 была оценена на валидационной выборке и показала следующие результаты:

  • Размер квантованной модели: ~5 МБ
  • F1-score (токсичный класс): 0.58

Метрики для лучшей модели:

Класс Precision Recall F1-score
Нетоксичный (0) 0.78 0.88 0.83
Токсичный (1) 0.68 0.51 0.58

Матрица ошибок:

Предсказано: Нетоксичный Предсказано: Токсичный
Реальный: Нетоксичный 1685 (TN) 233 (FP)
Реальный: Токсичный 473 (FN) 492 (TP)

Интерпретация: Модель работает в "осторожном" режиме. Когда она помечает комментарий как токсичный, она права в 68% случаев (Precision), но при этом находит только 51% всех токсичных комментариев (Recall). Баланс можно настроить с помощью параметра threshold в API.

💡 Ключевые технические решения в ходе разработки

  • Токенизация: Из-за проблем с лемматизацией natasha в облачной среде был выбран более надежный подход с использованием Segmenter для токенизации и последующей ручной очистки.
  • Стабилизация обучения: Модель была склонна к коллапсу (предсказание одного класса). Проблема была решена комбинацией BatchNorm1d, ReLU как модуля, gradient clipping и CosineAnnealingLR.
  • Квантизация: Для успешной квантизации потребовалось явно указать "мосты" (QuantStub, DeQuantStub), использовать специальный qconfig для nn.Embedding и, что самое важное, явно сливать (fuse) модули Conv-BN-ReLU перед подготовкой модели.