- Зачем: - расширенный benchmark показал устойчивое улучшение multilingual large на трёх реальных записях. - Что: - добавлен alias gigaam-multilingual-large-ctc с квантизациями int8 и float32. - обновлены README, спецификация, backlog и сравнительный benchmark. - Проверка: - uv run pytest -q: 225 passed, 1 skipped. - uvx ruff check src/local_transcriber/backends/onnx_asr.py tests/test_onnx_asr.py.
165 lines
14 KiB
Markdown
165 lines
14 KiB
Markdown
# Onnx-каталог, Python 3.13 и границы версий
|
||
|
||
## Проблема
|
||
|
||
Смешанная русско-английская речь и отсутствие пунктуации у `gigaam-v3-ctc` —
|
||
известные ограничения onnx-пути ([ADR-006](../adr/006-onnx-asr-backend.md)). В
|
||
`onnx-asr` 0.12 появились модели, которые их адресуют, но обновление
|
||
заблокировано ограничением `onnx-asr[cpu,hub]>=0.11.0,<0.12.0` в
|
||
`pyproject.toml`.
|
||
|
||
Состояние движков и первичные источники —
|
||
[исследование обновлений](../research/2026-08-10-engine-model-updates.md).
|
||
|
||
## Что делаем
|
||
|
||
Снимаем ограничение версии, поднимаем `onnx-asr` до 0.12 и делаем
|
||
поддерживаемыми четыре модели:
|
||
|
||
- `gigaam-multilingual-ctc` и `gigaam-multilingual-large-ctc` — смешанная речь
|
||
с англоязычными терминами; large добавлена после сравнительного benchmark по
|
||
явному решению пользователя;
|
||
- `gigaam-v3-e2e-ctc` и `gigaam-v3-e2e-rnnt` — пунктуация и нормализация текста.
|
||
|
||
Каталог моделей в бэкенде хранит, помимо имени, опубликованные для модели
|
||
квантизации — сейчас такого места нет, потому что алиасы отображают имя в имя.
|
||
Расширять существующую таблицу или заводить рядом отдельную структуру —
|
||
решается при реализации. Passthrough сырых имён onnx-asr сохраняется: он не
|
||
мешает и оставляет дверь для экспериментов.
|
||
|
||
Заодно поднимаем минимальную версию Python до 3.13 и ONNX Runtime до последней
|
||
доступной (1.28 на момент написания). Python 3.10 в режиме security-only и
|
||
снимается с поддержки в октябре 2026, а ORT 1.28 требует минимум 3.11 — так что
|
||
подъём floor и обновление рантайма идут вместе. Следствие: зависимость `tomli` и
|
||
условный импорт в `config.py` становятся мёртвым кодом и убираются — начиная с
|
||
3.11 есть `tomllib`.
|
||
|
||
Floor берётся сразу 3.13, а не минимально достаточный 3.11: любой подъём версии
|
||
всё равно требует прогона на всех трёх платформах, и дорого именно тестирование,
|
||
а не строка в `pyproject.toml`. Один переезд вместо двух. Проект ставится там,
|
||
где доступны uv и PyPI, поэтому uv сам поднимет нужный интерпретатор; закрытых
|
||
контуров и оффлайн-зеркал среди пользователей нет.
|
||
|
||
Рабочая версия фиксируется файлом `.python-version` (сейчас его в репозитории
|
||
нет). Floor разрешает любой интерпретатор от 3.13 и выше, а пин делает окружение
|
||
одинаковым на разных машинах — иначе расхождение вылезает именно тогда, когда
|
||
что-то отлаживаешь.
|
||
|
||
Колёса cp313 проверены для всех нативных зависимостей и всех трёх целевых
|
||
платформ — Windows, Linux, macOS: `openvino-genai` 2026.0.0.0, `ctranslate2`
|
||
4.7.1, `onnxruntime` 1.28.0. На macOS `openvino-genai` не ставится по
|
||
существующему маркеру `sys_platform != 'darwin'`, так что там остаются
|
||
faster-whisper на CPU и onnx-путь — это не меняется этой работой, но стоит
|
||
помнить, раз появились пользователи на Mac.
|
||
|
||
GPU-пакеты ORT с их требованием CUDA 13 нас не касаются: CUDA идёт через
|
||
CTranslate2, а onnx-путь ставится в CPU-варианте.
|
||
|
||
## Границы версий
|
||
|
||
Каждая прямая зависимость получает верхнюю границу по мажорной версии. Причина
|
||
не в осторожности вообще, а в канале установки: README предлагает
|
||
`uv tool install git+…`, а этот путь резолвит зависимости заново из метаданных
|
||
пакета — `uv.lock` в колесо не попадает и не участвует. Диапазоны в
|
||
`[project.dependencies]` — единственное, что ограничивает версии на машине
|
||
пользователя. Установки в разные месяцы иначе дают разные наборы библиотек при
|
||
одном и том же коде, и такие расхождения дороже разбирать, чем поднимать
|
||
границы вручную.
|
||
|
||
Три случая, которые сами собой не решаются:
|
||
|
||
- **`onnxruntime` объявляется прямой зависимостью с границей**, хотя проект его
|
||
не импортирует. `[tool.uv] constraint-dependencies` для этого не годится:
|
||
по документации uv он действует только когда uv резолвит сам проект, и
|
||
игнорируется, когда пакет ставят как зависимость.
|
||
- **`nvidia-cublas-cu12` получает границу по мажорной версии.**
|
||
`_cuda_bootstrap.py` преднагружает `libcublas.so.12` по точному soname
|
||
([ADR-001](../adr/001-cuda-bootstrap.md)); мажорный апгрейд даёт другой soname
|
||
и ломает bootstrap при неизменном коде.
|
||
- **`openvino-genai` фиксируется на проверенной линии 2026.0**, а не просто «до
|
||
следующего года». Иначе свежая установка подтянет 2026.3 и незаметно поменяет
|
||
ту самую точку отсчёта, которую мы договорились не трогать. Границу снимает
|
||
отдельная работа по обновлению OpenVINO — осознанно.
|
||
|
||
Конкретные номера берутся из `uv.lock` при реализации.
|
||
|
||
## Чего не делаем
|
||
|
||
- Не меняем модель по умолчанию и auto-detect: `gigaam-v3` остаётся дефолтом
|
||
`--device onnx`. Решение о CPU-дефолте требует замеров на целевом Intel Core
|
||
i5, которого сейчас нет в доступе.
|
||
- Не обновляем OpenVINO, OpenVINO GenAI и CTranslate2. Whisper medium на
|
||
OpenVINO — то, с чем сравниваются новые модели; менять его движок
|
||
одновременно значит потерять точку отсчёта. Верхние границы версий им при
|
||
этом проставляются — см. «Границы версий»; это фиксация текущего состояния, а
|
||
не обновление.
|
||
- Не добавляем алиасы `large-v3-turbo`, диаризацию, чанкование по паузам и
|
||
словарь замен терминов — отдельные пункты [backlog](../backlog.md).
|
||
|
||
## Ловушки
|
||
|
||
- **`compute_type` разрешается по устройству, а не по модели.**
|
||
`DEVICE_DEFAULTS["onnx"]` даёт `int8` независимо от модели, а `int8`
|
||
опубликован не для всех. Для модели без запрошенной квантизации проект должен
|
||
взять доступную и сказать об этом; явно заданное пользователем значение
|
||
остаётся ошибкой, а не тихой подменой. Явным считается и значение из
|
||
`.transcriber.toml`, не только флаг CLI — подстановка допустима лишь там, где
|
||
квантизацию выбрал сам проект. Это единственное изменение в каскаде
|
||
конфигурации.
|
||
- **Язык у multilingual-модели.** Проект по умолчанию форсирует `ru`, а интерес
|
||
— как раз смешанная речь. Надо посмотреть, принимает ли модель подсказку языка
|
||
или определяет сама, и описать правило в README.
|
||
- **E2E меняет форму текста.** Пунктуация и нормализация могут повлиять на
|
||
группировку абзацев в `formatter.py` и на предупреждения `quality.py`,
|
||
написанные под поведение Whisper.
|
||
- **VAD.** В 0.12 исправлены сегменты нулевой длины после VAD — проект
|
||
оборачивает модель в `.with_vad()`, так что изменение касается нас напрямую.
|
||
|
||
## Как проверяем
|
||
|
||
Работа идёт в отдельной ветке (по конвенции репозитория — `feature/…`), в
|
||
`master` вливается только после ручной проверки. Причина не в процессе ради
|
||
процесса: переезд на 3.13 пересобирает окружение целиком, и откатывать это на
|
||
основной ветке неприятно. Ветка позволяет держать рабочий `master` под рукой,
|
||
пока новое окружение не подтвердилось.
|
||
|
||
Внутри ветки смена окружения и смена библиотеки проверяются раздельно: сначала
|
||
Python и зависимости при неизменных моделях — поведение обязано остаться
|
||
прежним, — и только потом `onnx-asr` 0.12 с новыми моделями. Иначе при первой же
|
||
странности подозреваемых окажется десяток и разделить их будет нечем, CI тут не
|
||
поможет.
|
||
|
||
Проект домашний, CI нет, репрезентативные записи приватны и на разных ноутбуках
|
||
разные — автоматическая приёмка невозможна в принципе, уверенность держится на
|
||
ручных прогонах. Что она покрывает и чего не покрывает:
|
||
|
||
- существующие тесты замоканы ([`AGENTS.md`](../../AGENTS.md)) и подтверждают
|
||
CLI, конфиг и форматирование, но не работоспособность движка: поломку ORT или
|
||
onnx-asr видно только на реальной записи;
|
||
- ручные прогоны делаются на Windows и Linux, по всем трём путям — onnx,
|
||
openvino, cuda;
|
||
- **macOS не проверяется вовсе.** Колёса cp313 там опубликованы, но это
|
||
наличие, а не работоспособность; при жалобе с Mac исходить из того, что путь
|
||
не валидировался;
|
||
- **скорость на Intel Core i5 не измерялась.** Замеры делаются на Ryzen 7
|
||
8845H и записываются как наблюдение с указанием CPU — для решения о
|
||
CPU-дефолте этого недостаточно;
|
||
- **качество моделей измерено предварительно на трёх 14–15-минутных записях.**
|
||
Результат фиксирует WER, скорость и ручное чтение, но не заменяет приёмку на
|
||
целевом Intel Core i5 и длинных записях; см.
|
||
[benchmark](../benchmarks/2026-08-11-gigaam-model-comparison.md).
|
||
|
||
Пошаговый чеклист и практика прогона нужны только на время работ и живут в
|
||
задаче трекера
|
||
([#1](https://git.dementev.space/ddmitry/local-transcriber/issues/1)), а не в
|
||
этом документе.
|
||
|
||
## Документация
|
||
|
||
README: четыре модели в таблицу ONNX-моделей. Для русского без пунктуации
|
||
рекомендуется `gigaam-v3`, для готового читаемого текста — E2E RNN-T, для
|
||
смешанной речи с приоритетом качества — multilingual large. Скорость на слабых
|
||
CPU не измерялась. Требование Python
|
||
правится в [`docs/PRD.md`](../PRD.md) — раздел «Требования» и таблица
|
||
технологий; в README версии Python не упоминаются.
|