Files
grabber-ai/docs/retrain-segmenter.md
T
DenozordecandClaude Sonnet 5.5 b3ceefda4f
docker / build (push) Successful in 2m1s
Сегментация: список дорожек под «Перевод:» на реальной вёрстке, достройка блока, segmenter_warning
- 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]>
2026-11-07 16:14:50 +07:00

94 lines
6.0 KiB
Markdown

# Дообучение сегментатора страниц
Сегментатор решает, какие строки страницы описывают дорожки озвучки
(`src/segmenter.py`, rubert-tiny2). Дообучать его нужно, когда `/predict` теряет
дорожки или в ответе появилось `segmenter_warning` (модель и правила
разошлись). Делается на машине, где лежат `data/raw`, `data/pages` и `models/segmenter`
(в git их нет; в репозитории на машине разработки их не оказалось, пути ниже — относительно каталога проекта, где они есть): без них обучение выдаст более слабые веса, чем рабочие.
## 0. Понять причину (по желанию, 1 минута)
Какие оценки модель ставит строкам страницы (`docker compose exec` — на
сервере, либо то же в `.venv` локально):
```bash
docker compose exec grabber-ai python -c "from src.fetch import fetch_html; from src.html_extract import html_to_text; from src.segmenter import LineSegmenter, page_lines; h,_=fetch_html('https://rutracker.org/forum/viewtopic.php?t=6919056', timeout=60); L=page_lines(html_to_text(h)); s=LineSegmenter('/app/models/segmenter'); [print(round(float(p),3), l[:90]) for l,p in zip(L, s.score(L)) if p>0.01]"
```
* оценки 0.3–0.49 у строк-дорожек — упёрлись в порог (`THRESHOLD = 0.5`);
* оценки около 0 — модель не знает такую вёрстку, нужны примеры (шаги ниже).
## 1. Добавить проблемные раздачи
```powershell
cd <каталог проекта, где лежат data\raw и models>
.venv\Scripts\python tools\collect.py
```
Главное меню → **6** («Обучение по ссылкам»): вставьте ссылки на раздачи, у
которых дорожки определились неверно (например,
`https://rutracker.org/forum/viewtopic.php?t=6919056`). Страницы скачиваются
вашим Chrome (вход на трекер делаете сами), парсер строит метки. Проверьте
таблицу: строк-дорожек должно быть столько же, сколько на странице (для
6919056 — четыре, у двух HDRezka разные типы). Правки: «2 18» — переключить
18+, «3 d» — удалить строку, «1 t <тип>» — тип, «1 s <студия>» — студия.
Сохраните: id попадёт в `data/manual_ids.txt`, такие релизы всегда в train и
повторяются при обучении ×5.
Чем больше похожих раздач (3–10 штук с разными студиями и той же вёрсткой),
тем надёжнее; одна страница редко меняет поведение модели.
## 2. Переобучить
Главное меню → **2** («Переобучить и протестировать»). Шаги идут сами:
`prepare_data`, обучение сегментатора в `models/segmenter_v2`
(≈ минуты на RTX 5070 Ti), `tests/run_tests.py`, таблица «правила / старые веса /
новые веса» по трекерам.
Без меню:
```powershell
.venv\Scripts\python -m src.prepare_data
.venv\Scripts\python -m src.segmenter --train --out models/segmenter_v2
.venv\Scripts\python tests\run_tests.py
.venv\Scripts\python tests\e2e_segmenter.py models/segmenter_v2
```
## 3. Принять новые веса
Меню покажет, лучше ли новые веса. На «y» они заменят `models/segmenter`, старые
уйдут в `models/segmenter_old_<время>`. Если хуже — не принимайте: добавьте
больше примеров вёрстки и повторите шаг 2.
Исправленная раздача проверяется на сервере после пересборки образа (шаг 5).
## 4. Упаковать модели и пересобрать образ
```powershell
.venv\Scripts\python tools\pack_models.py --stage docker-models
docker compose up -d --build
```
(в CI — workflow `.gitea/workflows/docker.yml`, см. `docs/docker.md`).
## 5. Проверить на сервере
```powershell
irm http://192.168.100.67:7654/health # "segmenter": "model"
irm http://192.168.100.67:7654/predict -Method Post -ContentType "application/json; charset=utf-8" -Headers @{Authorization="Bearer <токен>"} -Body ([Text.Encoding]::UTF8.GetBytes('{"url":"https://rutracker.org/forum/viewtopic.php?t=6919056"}')) | ConvertTo-Json -Depth 10
```
Должно быть `"segmenter": "model"`, четыре дорожки, без `segmenter_warning`.
## Что делает сервис, пока модель не дообучена
* **Достройка блока** (`release.complete_block`): модель выбрала часть строк
списка под «Перевод:» — соседние строки с типом озвучки (Проф…, Любит…, …голос…)
добавляются в тот же список.
* **Запасные правила**: модель не нашла ни одной строки — дорожки берут правила
`html_extract.extract_segments`; в ответе `"segmenter": "rules"`.
* **`segmenter_warning`** в ответе и строка `segmenter: …` в логе сервиса — модель
и правила разошлись. На глоссариях типов озвучки правила дают ложные
срабатывания, поэтому предупреждение — повод посмотреть страницу, а не
всегда ошибка.