Переразбор всех страниц data/raw: legacy-страницы импорта, форматы префиксов ([*]Перевод (1):, Озвучка:, №2, диапазоны), дорожки только в строках «Аудио» (в т.ч. «(Русский, X)», «| Rus | Звук: …»), «Язык озвучки», несколько студий в одной строке, студия без типа. Кодек-строки: «Аудио #N Русский:», «Аудио pic RUS:», «Звук N:», «Аудиодорожка 01:», кириллические АVO/МVO. «Авторский» без числа голосов -> авт. одноголосый, «двугоголосый». Чистка студий: языки, кодеки, «по заказу», «в составе контейнера», отказы от озвучки.
Итог: страниц с метками 30 260 (85.5 %), страниц с дорожкой без меток 1 259 -> 223; data/pages 30 444; после prepare_data 60 944 строки (train 54 686 / test 6 258).
Новый tools/coverage_audit.py + reports/coverage_audit.md, docs/dataset-coverage.md. Переобучен models/best (base): на общем тесте type acc 0.976 против 0.949 у прежней, span 0.674 против 0.643; e2e kinozal 0.805/0.867, rt 0.771/0.740, nnm 0.752/0.693.
Kinozal 2160145: после переобучения модель выбирала первую строку вкладки «Релиз»
(«Memoirs.of.a.Geisha.2005.2160p.UHD.Blu-ray.Remux…-CiNEPHiLES», оценка 0.96), и
имя релиза попадало в ответ как «студия». Прежние веса строку не выбирали.
- html_extract.RE_SCENE: без пробелов и ≥ 4 точек — дорожкой не бывает;
LineSegmenter.select_lines отбрасывает такие строки при любой оценке модели.
- build_examples: scene-имена — трудные негативы, берутся все (раньше прореживались
до 15 %); эффект — при следующем переобучении.
- На реальных данных страницы (вкладки Техданные/Интересно/Награды/Релиз):
1 дорожка «проф. дубляж», без студии. Тесты: 288 ok.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Парсер меток (rt_parse) требовал текст после «Перевод:» на той же строке, поэтому
раздачи с пустым «Перевод:» и списком «Профессиональный (…) | Студия» по строке на
дорожку (t=6919056, 6927571) не получали меток, релиз не сохранялся, а сегментатор
учился на их дорожках как на негативах. Теперь rt_bare_list берёт подряд идущие
строки со словом типа (через пустые строки; строки «тип: определение» —
глоссарий — не берутся). То же правило в html_extract.extract_segments.
На data/raw: +252 раздачи получают метки, в 12 добавляются недостающие дорожки.
PARSE_VERSION 3 -> 4 (переразбор при «Переиндексировать data/raw»). Тест rt_parse
на 6919056; 276 ok.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
- html_extract: строки дорожек под пустым «Перевод:» берутся и через пустые
строки (в HTML после <br> стоит \n исходника — прежняя правка на реальной
странице rutracker t=6919056 отдавала 1 дорожку из 4); шаблон начала строки
требует полные слова типа озвучки.
- release: complete_block достраивает список, из которого модель выбрала не все
строки; segmenter_warning (+ лог) — модель и правила (без кодек-строк)
разошлись; поле segmenter_warning в ответе.
- docs: retrain-segmenter.md — как дообучить сегментатор, поле в api-reference.
- tests: 275 ok.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
На rutracker дорожки бывают перечислены по одной на строку под
«Перевод:» без значения; правила брали только первую строку и теряли
остальные (t=6919056: 1 из 4, t=6927571: 1 из 7). Теперь берутся
подряд идущие строки, начинающиеся со слова типа озвучки.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
На nnm строка «Видео» не называет битность и HDR — они только в заголовке («[4K, HDR10, DV 8.1, 10-bit]»).
- bit_depth: если в строке «Видео» нет, ищется в заголовке
- «DV» считается Dolby Vision (\b не цепляет DVD/DVDRip)
- профиль из «DV 8.1», «DV P7», «DoVi P5»; только реальные профили, «DV 10-bit» — не профиль
- тесты: раздача nnm «В поисках Дори», DVDRip / DV 10-bit, DV P7
Co-Authored-By: Claude Opus 5.5 <[email protected]>
src/techinfo.py — правила по строкам «Видео:», «Тип релиза:»/«Качество»,
«Контейнер:», «Продолжительность:», «Субтитры:» и заголовку: поля video
(кодек, размер кадра, класс разрешения, fps, битрейт, битность, HDR,
профиль DV), release (тип, нормализованный источник, контейнер,
продолжительность), subtitles (языки с forced/full/SDH, формат, вшитые).
audio дорожек и original: khz и atmos (вход модели не меняется).
title_from_html больше не рвёт заголовок rutracker пробелами
(<span>/<wbr> на каждом слове). Покрытие на 600 страницах каждого
трекера: видео 90/93/100%, e2e озвучки без изменений. Тесты 275 ok.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Пустая кодек-строка («Аудио 1: AC3, 6 ch, 384 kbps - Русский») снова
негатив: с -1 модель разучилась её отбрасывать и на nnm подменяла ею
строку «Перевод: …».
Пробное обучение (2 эпохи, ~34 мин на 27.9k страниц) e2e по 400 тестовых
страниц, P/R пар (тип, студия), текущие веса -> новые: nnm 0.872/0.879 ->
0.836/0.860, rutracker 0.891/0.917 -> 0.883/0.910, kinozal 0.720/0.844 ->
0.724/0.845. Новые веса не лучше текущих, models/segmenter не заменён.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Обучение:
* page_text/kinozal_text: текст kinozal = h1 + «Техданные» + «Релиз» из
data/raw/kinozal/*.json (в pages/kz-*.txt нет заголовка и «Техданных»,
откуда половина меток kinozal; сервис видит обе вкладки).
* label_page: позитив — raw или audio_raw; неразмеченная кодек-строка
русской дорожки («Аудио 3: … Русский (MVO, X)», «Аудио Rus: … | X»)
получает -1 и в обучение не идёт: как негатив она учила отбрасывать
кодек-строки. Сводка «Аудио: Русский, английский (…)» остаётся негативом.
Инференс (release):
* model_segments -> (основные, кодек); выбранные моделью кодек-строки идут
второстепенным источником вместе с правилом codec_segments; иноязычные
(«Казахский (Dub, …)», «English Dubbing», «Original») отбрасываются.
* merge_extra_tracks(adopt_type): кодек-дорожка с типом «неизвестно»
получает тип единственной дорожки страницы без студии.
e2e_segmenter: тот же текст kinozal, не больше E2E_MAX (400) страниц на
трекер, train-страницы только с --train-pages (меню парсит только тест).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Конфликт в src/release.py: взяты original_info, lostfilm_release,
series_info и серии дорожек из advisor; сохранены same_studio,
merge_extra_tracks и codec_segments. Кодек-дорожкам тоже проставляются
серии.
Кодек-строки теперь подключаются, только если у какой-то дорожки страницы
нет студии: с новыми моделями безусловное подключение роняло precision
студий на rutracker (0.908 -> 0.793). С условием, test-сплит, по 300
релизов, студии P/R: rutracker 0.908/0.882 -> 0.840/0.900, nnm
0.875/0.915 -> 0.875/0.940, kinozal 0.816/0.845 -> 0.800/0.863. Тесты:
240 ok.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
С only_second токенизатор бросал исключение, если сама строка (до 220
символов) не помещалась в MAX_LEN и обрезать было нечего, кроме контекста.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
На kinozal во встроенном #tabs только «Техданные» («Перевод:» без студий),
а строки «Аудио N: … (MVO, LostFilm)» лежат во вкладке «Релиз», которую
страница грузит JS. Поэтому по URL определялись только типы без студий.
* fetch: для kinozal скачиваются вкладки showtab(id,N)
(get_srv_details.php?id=…&pagesd=N, кроме «Техданных» и «Скриншотов»)
и дописываются в #tabs; недоступная вкладка пропускается.
* release: кодек-строки с типом озвучки берутся правилом codec_segments
(сегментатор их отбрасывает — в разметке rutracker это не raw) и идут
второстепенным источником (source=codec / page+codec): только дорожки
со студией, дубли студии (same_studio) пропускаются, студия вписывается
в дорожку того же типа без студии. «English Dubbing» и т.п. не берутся.
* merge_title_tracks переведён на общий merge_extra_tracks.
e2e test rutracker без изменений (P 0.988 / R 0.982); train-страницы
P 0.975 -> 0.951. Тесты: 77 ok.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- Docker: Dockerfile (CPU), compose с FlareSolverr, настройка через DUB_* переменные,
токен доступа к /predict, tools/pack_models.py, workflow Gitea Actions, docs/docker.md
- Модель грузится офлайн (config.json рядом с весами); общий код вынесен в src/spans.py,
сервису не нужны sklearn/matplotlib/pandas
- Обучение: профили tiny2/base/large/modern, запуски в models/runs, реестр и честное
сравнение на одной тестовой выборке (src/runs.py), пункт меню «Модели»
- Датасет: язык и аудио-параметры дорожек, 18+ по строкам «Аудио», ручные метки по ссылкам,
переиндексация сохранённого HTML, параллельная сборка, сбалансированная выборка
- Тексты страниц (data/pages) больше не хранятся в git
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>