DenozordecandClaude Opus 5.5 e8035e1e9d
docker / build (push) Successful in 43s
Переобучение на нескольких авторах в строке: метки PARSE_VERSION 9, новая models/best (base)
Метки пересобраны новыми парсерами (collect.py build --relabel): 69 511 строк из 30 451 релиза;
после prepare_data 52 658 строк, 3 529 с несколькими авторами, 5 ручных решений применены.

Новая models/best (ruBert-base) на общем тесте 4 984 строк: joint exact 0.903 против 0.800 у
прежней, span exact 0.919 против 0.813, type macro-F1 0.976 против 0.909; строки с 2+ авторами —
span 0.815 против 0.011. Прежняя модель — models/best_backup_20261109_164800. ONNX пересобран,
паритет 100 %.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-09 16:56:12 +07:00

grabber-ai — нейро-модель «тип озвучки + автор + 18+»

По тексту дорожки озвучки (или HTML-странице релиза с трекеров rutracker / kinozal / nnm-club) модель определяет:

  • тип озвучки (translation_type, 15 классов: проф. дубляж, проф. многоголосый, авт. одноголосый, …) — классификация;
  • автора (studio: студия или переводчик) — извлечение имени прямо из текста (работает и для авторов, которых не было в обучении) + нормализация по словарю алиасов («HDRezka Studio» → HDrezka, «Ю. Сербин» → «Юрий Сербин»);
  • 18+ дорожка или нет — бинарная голова.

Обучено на датасете из 52 658 строк (69 511 размеченных строк из 30 451 релиза data/raw + морфологическая аугментация; у строки может быть несколько авторов — «Многоголосый (HDRezka Studio, LostFilm)» даёт обоих). Как страницы превращаются в строки и что было исправлено в сборщике — docs/dataset-coverage.md. Multi-task RuBERT: сравниваются rubert-tiny2 и ruBert-base, лучшая кладётся в models/best.

Квикстарт (5 минут)

# 1. окружение (Windows, Python 3.13; GPU требует колёс cu128 — см. docs/training-windows.md)
python -m venv .venv
.venv\Scripts\python -m pip install torch --index-url https://download.pytorch.org/whl/cu128
.venv\Scripts\python -m pip install -r requirements.txt

# 2. данные -> подготовка (data/labels.csv уже в репозитории)
.venv\Scripts\python -m src.prepare_data

# 3. обучение (обе модели, 5-fold CV; ~15-20 мин на RTX 5070 Ti)
.venv\Scripts\python -m src.train
#    результат: models/best, reports/summary.md, reports/*.png

# 4. инференс
.venv\Scripts\python -m src.predict --text "Перевод: Профессиональный (многоголосый закадровый) | HDRezka Studio 18+"
.venv\Scripts\python -m src.predict --html data/samples/rt-topic.html
.venv\Scripts\python -m src.predict --file data/pages/6907007.txt --out result.json

Python API:

from src.predict import DubPredictor

model = DubPredictor()                      # models/best по умолчанию
model.predict_text("Авторский (одноголосый закадровый) - Ю. Сербин")
# {'translation_type': 'авт. одноголосый', 'studio': 'Юрий Сербин', 'is_18plus': False, ...}

model.predict_html(open("data/samples/rt-topic.html", encoding="utf-8").read())
# [ {...дорожка 1...}, {...дорожка 2...}, ... ]

HTTP-сервис и интеграция из Rust/TypeScript (ONNX без Python) — см. docs/integration.md.

Структура

data/            датасет (labels.csv — снимок) и HTML-дампы страниц
data/processed/  подготовленные данные (dataset.json, label_maps.json)
src/             код: подготовка, модель, обучение, инференс, сервис, ONNX-экспорт
models/          чекпоинты (best — итоговая модель)
reports/         метрики, аудит датасета, confusion matrix, ONNX-parity
tests/           юнит-тесты (tests/run_tests.py)
examples/        клиенты: rust (HTTP, ONNX), typescript (HTTP, ONNX)
docs/            документация

Документация

  • docs/architecture.md — устройство модели и пайплайна
  • docs/dataset.md — схема датасета, семантика классов, аудит
  • docs/dataset-coverage.md — покрытие всех страниц data/raw, найденные дыры сборщика и что исправлено
  • docs/training-windows.md — обучение на Windows+GPU, troubleshooting
  • docs/api-reference.md — все значения ответа сервиса (15 классов translation_type и др.) и принцип работы; labels.csv для этого открывать не нужно
  • docs/inference.md — CLI/API, JSON-контракт
  • docs/integration.md — Rust/TypeScript: HTTP-сервис и ONNX

Качество

Held-out test (4 984 строки, группировка по релизам и текстам; метки пересобраны парсерами PARSE_VERSION 9, строки со списком студий склеены в одну с несколькими авторами). Все модели оценены на одном и том же тесте:

модель type acc type macro-F1 span exact 18+ acc lang acc joint exact [95 %] строки с 2+ авторами (438), span
прежняя models/best (09.11, один автор на строку) 0.981 0.909 0.813 1.000 0.998 0.800 [0.788–0.810] 0.011
rubert-tiny2, несколько авторов 0.978 0.904 0.869 0.999 0.999 0.854 [0.843–0.863] 0.637
ruBert-base, несколько авторов (models/best) 0.979 0.976 0.919 1.000 0.999 0.903 [0.895–0.911] 0.815
  • joint exact — строка распознана полностью (тип + все авторы + 18+); span exact сравнивает набор авторов строки целиком.
  • Новая models/best против прежней на тех же строках: исправлено 647, сломано 131 (знаковый критерий p ≈ 1e-83). Прежняя модель часть тестовых строк видела при обучении, так что сравнение в её пользу.
  • Противоречивых строк (один текст — разные метки) в датасете 1.2 % вместо 20 %: исправлены парсеры студий (пол голоса, техпараметры, «т/к», «N-й канал»), а списки студий размечаются целиком. Оставшиеся расхождения между релизами разбираются вручную: tools/collect.py → «Разбор противоречий» (data/text_fixes.csv).
  • E2E по релизам (замер для модели от 09.11 с одним автором на строку) (tests/e2e_segmenter.py, по 400 тестовых страниц на трекер, пары тип + студия, precision / recall) — новая модель на тех же страницах: kinozal 0.805 / 0.867, rutracker 0.771 / 0.740, nnm 0.752 / 0.693; прежняя модель там же: 0.752 / 0.830, 0.729 / 0.700, 0.669 / 0.604. Справочно, правила: 0.792 / 0.859, 0.697 / 0.721, 0.670 / 0.646.
  • Сегментатор (models/segmenter) переобучен на расширенном наборе страниц (models/segmenter_v2, line precision 0.933 / recall 0.977), но e2e новых весов хуже по nnm (0.610 / 0.560) — в models/segmenter оставлены прежние веса.
  • models/best-onnx пересобран под новую модель: паритет с PyTorch 100 % по типу, авторам и 18+ — reports/onnx_parity.md.

Ограничения

  • Метки датасета сгенерированы регулярками (пайплайн deepseek-harness) — метрики измеряют согласование с этой разметкой; ценность модели — обобщение на новые формулировки без сопровождения регулярок.
  • Датасет: 69 511 строк из 30 451 релиза (kinozal 23 749 / nnm 26 478 / rutracker 19 284); после подготовки 52 658 строк (3 529 — с несколькими авторами). Покрытие страниц data/raw — 85.5 % (30 260 из 35 385); оставшиеся — почти все без озвучки (русский оригинал, «не требуется», музыка/сканы), см. docs/dataset-coverage.md.
  • Извлечение автора уверенно работает на форматах записи, представленных в датасете (имя после типа через разделитель, в скобках у AVO/MVO/DVO-дорожек, после тире); на непривычных форматах («Одноголосый закадровый (Фамилия)») модель может не выделить имя — span остаётся пустым, тип при этом верный.
  • kinozal-страницы: авторы озвучки лежат во вкладках, которые сайт подгружает JavaScript-ом. По url сервис скачивает их сам (fetch_html, showtab); в присланном html/text без этих вкладок студий может не быть.
  • Классы с 1–8 примерами почти не выучиваются (видно в macro-F1 и confusion matrix); морфологическая аугментация (458 вариантов: «многоголосое» и т.п.) частично закрывает этот пробел.
S
Description
No description provided
Readme
3.4 GiB
0 Stars 1 Watchers 0 Forks
Languages
Python 58.7%
HTML 41%
JavaScript 0.2%
Dockerfile 0.1%