Files
grabber-ai/docs/inference.md
T

114 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Инференс: CLI, Python API, JSON-контракт
## CLI (src/predict.py)
```bash
# одна дорожка текстом (префикс «Перевод:» не обязателен, но допустим)
python -m src.predict --text "Перевод: Профессиональный (многоголосый закадровый) | HDRezka Studio 18+"
# HTML-страница целиком -> все дорожки релиза
python -m src.predict --html data/samples/rt-topic.html
# текстовый дамп страницы
python -m src.predict --file data/pages/6907007.txt
# результат в файл + выбор модели
python -m src.predict --file page.txt --out result.json --model models/base
```
Кодировка входных файлов определяется автоматически (utf-8 → cp1251).
HTML распознаётся по содержимому, так что `--html` и `--file`
взаимозаменяемы.
## Ссылка на раздачу и агрегат релиза
```bash
python -m src.predict --url https://rutracker.org/forum/viewtopic.php?t=123
python -m src.predict --url https://kinozal.tv/details.php?id=1 --cookie "uid=..; pass=.."
```
Поддерживаются только rutracker / kinozal / nnm-club (allowlist доменов,
редиректы за его пределы запрещены). Для `--html`, `--file` и `--url` ответ —
агрегат релиза: к `tracks` добавлены
| Поле | Описание |
|---|---|
| `studios` | уникальные `{studio, translation_type, is_18plus}` |
| `translation_types` | отсортированный список типов релиза |
| `is_18plus` | `true`, если 18+ хотя бы у одной дорожки |
| `title` | заголовок раздачи (если найден в HTML) |
| `tracker` | только для `--url` |
Дорожки дедуплицируются по (тип, студия). Студии из заголовка раздачи вида
`ПМ (LostFilm)`, которых нет в описании, добавляются с `source: "title"`
(у остальных `source: "page"`). `--text` по-прежнему возвращает только `tracks`.
## Python API
```python
from src.predict import DubPredictor
model = DubPredictor() # models/best; параметр device определяется сам
model.predict_text("Авторский (одноголосый закадровый) - Ю. Сербин")
# -> dict (см. контракт ниже)
model.predict_html(open("page.html", encoding="utf-8").read())
# -> list[dict] — по одному на каждую найденную дорожку
model.predict_page("Перевод: Дублированный | MovieDalen\n...") # текст без HTML
model.predict_file("page.txt")
```
## JSON-контракт
Полный справочник значений (14 классов `translation_type`, `lang`, `role`, `audio`, агрегат релиза, принцип работы) — в [api-reference.md](api-reference.md); ниже краткий пример.
```json
{
"tracks": [
{
"segment": "Профессиональный (многоголосый закадровый) | HDRezka Studio 18+",
"translation_type": "проф. многоголосый",
"type_confidence": 0.99,
"studio_span": "HDRezka Studio",
"studio": "HDrezka",
"studio_confidence": 0.97,
"is_18plus": true,
"age_confidence": 0.99
}
]
}
```
| Поле | Тип | Описание |
|---|---|---|
| `segment` | string | текст дорожки, по которому сделано предсказание (префикс снят) |
| `translation_type` | string | один из 14 классов (см. docs/dataset.md) |
| `type_confidence` | float | softmax-вероятность класса |
| `studio_span` | string \| null | фрагмент текста, распознанный как имя автора |
| `studio` | string \| null | каноническое имя автора по словарю алиасов; null — автора в тексте нет |
| `studio_confidence` | float \| null | средняя вероятность токенов спана |
| `is_18plus` | bool | дорожка помечена 18+ |
| `age_confidence` | float | вероятность предсказанного класса 18+ |
## Как обрабатывается страница
1. HTML → текст (BeautifulSoup: `div.post_body` (rutracker) → `#tabs`
(kinozal) → весь документ);
2. строки вида «Перевод/Озвучка/Озвучивание/Озвучено/Звук/Аудио N: …»;
3. разбиение многострочных дорожек: нумерация «1. … 2. …», разделители
«+ ; /» перед словами типов, перечисление типов через запятую;
4. строки без признаков типа озвучки (например, чисто кодек-строки) не
попадают в результат;
5. каждая дорожка — отдельное предсказание модели.
## Ограничения
* `studio` — нормализация по словарю; неизвестные имена возвращаются как
есть (спан), без канонизации;
* если дорожка в тексте написана без какой-либо информации о типе, модель
вернёт наиболее вероятный класс (обычно «неизвестно») — фильтрация таких
строк уже сделана на этапе сегментации;
* классы с единичными примерами в обучении (см. docs/dataset.md)
предсказываются хуже — видно в confusion matrix.