From f91f6cb48e215b5b768d05f8857aeedeb369a91a Mon Sep 17 00:00:00 2001 From: Denozordec Date: Mon, 2 Nov 2026 14:10:32 +0700 Subject: [PATCH] =?UTF-8?q?=D0=A1=D0=B5=D0=B3=D0=BC=D0=B5=D0=BD=D1=82?= =?UTF-8?q?=D0=B0=D1=82=D0=BE=D1=80:=20-1=20=D1=82=D0=BE=D0=BB=D1=8C=D0=BA?= =?UTF-8?q?=D0=BE=20=D0=B4=D0=BB=D1=8F=20=D0=BA=D0=BE=D0=B4=D0=B5=D0=BA-?= =?UTF-8?q?=D1=81=D1=82=D1=80=D0=BE=D0=BA=20=D1=81=20=D1=82=D0=B8=D0=BF?= =?UTF-8?q?=D0=BE=D0=BC=20=D0=B8=D0=BB=D0=B8=20=D1=81=D1=82=D1=83=D0=B4?= =?UTF-8?q?=D0=B8=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Пустая кодек-строка («Аудио 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 --- src/segmenter.py | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/segmenter.py b/src/segmenter.py index e57f0b9..e1cef25 100644 --- a/src/segmenter.py +++ b/src/segmenter.py @@ -115,9 +115,33 @@ RE_AUDIO_TRACK = re.compile( r".*(?:русск|russian|\brus\b|украин|ukrain|\bukr\b))") +RE_TYPE_WORD = re.compile( + r"(?i)\b(?:MVO|DVO|AVO|DUB|VO)\b|дубл|многоголос|двухголос|одноголос|закадр|авторск") +# технические слова кодек-строки: всё, что после их удаления осталось, — имя студии/автора +RE_TECH_WORD = re.compile( + r"(?i)^(?:аудио\w*|audio|e?-?ac-?3|eac3|ac|dts|hd|ma|mpeg|mp3|aac|lc|opus|flac|pcm|lpcm|truehd" + r"|atmos|joc|dolby|digital|surround|stereo|mono|cbr|vbr|avg|constant|core|bit|ch|сh|channels?" + r"|каналов|канала|kbps|kb|кбит|бит|сек|khz|кгц|hz|lfe|dn|db|rus|ukr|eng|russian|русск\w*" + r"|украин\w*|english|англ\w*|l|c|r|sl|sr|ls|rs|lr|cbr|a)$") + + +def _informative(line: str) -> bool: + """Кодек-строка называет тип озвучки или студию/автора, а не только параметры. + + «Аудио 1: AC3, 6 ch, 384 kbps - Русский» — нет; «… | LostFilm», + «… - Русский, Юрий Живов», «… (MVO)» — да. + """ + if RE_TYPE_WORD.search(line): + return True + body = re.sub(r"(?i)^\s*(?:Аудио\w*|Audio)\s*(?:№|#)?\s*(?:\d+|rus|ukr)?\s*[:.]", "", line) + words = [w for w in re.findall(r"[^\W\d_]+", body) if not RE_TECH_WORD.match(w)] + return any(len(w) >= 3 for w in words) + + def label_page(lines: list[str], raws: list[str]) -> list[int]: """1 — строка содержит raw (или raw содержит строку ≥ 15 символов); - -1 — неразмеченная кодек-строка русской дорожки: в обучение не идёт. + -1 — неразмеченная кодек-строка русской дорожки с типом или студией: в + обучение не идёт; пустая кодек-строка («AC3, 6 ch, 384 kbps - Русский») — 0. Кодек-строка «Аудио N: … (MVO, LostFilm)» — дорожка, но у rutracker `raw` — строка «Перевод N:», а кодек-строка в разметку не попадает. Как @@ -127,7 +151,8 @@ def label_page(lines: list[str], raws: list[str]) -> list[int]: out = [] for line in lines: hit = any(r and (r in line or (len(line) >= 15 and line in r)) for r in raws) - out.append(1 if hit else (-1 if RE_AUDIO_TRACK.match(line) else 0)) + skip = RE_AUDIO_TRACK.match(line) and _informative(line) + out.append(1 if hit else (-1 if skip else 0)) return out