docs(specs): спека onnx-каталога, Python 3.13 и границ версий

- Зачем:
  - смешанная русско-английская речь и отсутствие пунктуации у gigaam-v3-ctc
    закрываются моделями из onnx-asr 0.12, но обновление заблокировано пином.
- Что:
  - добавлена спека: три модели в каталог, Python 3.13 и ORT 1.28, верхние
    границы мажорных версий, ловушки и границы ручной приёмки.
  - в backlog добавлены ссылка на спеку из пункта про CPU-дефолт и новое
    направление «профили намерения вместо выбора модели».
- Проверка:
  - задача трекера #1 с порядком работ и критериями приёмки.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dmitriy Dementiev
2026-08-11 11:39:28 +03:00
co-authored by Claude Opus 5
parent 579cb87bc0
commit 80b864077a
2 changed files with 181 additions and 0 deletions
+21
View File
@@ -26,6 +26,10 @@
ограничение `onnx-asr<0.12.0`, проверить VAD и квантованные модели; OpenVINO и
OpenVINO GenAI обновлять согласованно. Не фиксировать ONNX Runtime 1.28 для
Python 3.10.
Шаг 1 в части onnx-пути вынесен в отдельную работу —
[спека «Onnx-каталог, Python 3.13 и границы версий»](specs/2026-08-11-onnx-model-catalog.md): движок
обновляется, три модели становятся поддерживаемыми, дефолт и OpenVINO не
трогаются намеренно, чтобы сохранить точку отсчёта для будущего сравнения.
2. После интеграционных тестов провести сравнительный бенчмарк моделей. Не
менять CPU-дефолт только по model card или результату на одном файле.
3. Решение зафиксировать в ADR-007, обновить рекомендации README и только затем
@@ -226,6 +230,23 @@ SQL`), словарь пользовательский в `.transcriber.toml`.
## Авто-детект и UX
### Профили намерения вместо выбора модели
**Что:** Вместо `--model gigaam-v3-e2e-rnnt` пользователь выбирает намерение —
условные `ru-fast`, `ru-readable`, `mixed`, — а проект разворачивает его в пару
модель + квантизация с учётом устройства.
**Почему:** Имена onnx-моделей ничего не говорят о том, что получит
пользователь, и различие «поддерживаемая модель ≠ рекомендуемая» через них не
выражается.
**Почему откладывается:** профиль осмыслен, когда известно, какой профиль чем
закрывается — то есть после сравнительной оценки. Введение понятия раньше
данных закрепит догадку в интерфейсе. Источник:
[спека «Onnx-каталог, Python 3.13 и границы версий»](specs/2026-08-11-onnx-model-catalog.md).
---
### Включение `onnx` в `--device auto`
**Что:** После периода стабилизации `--device onnx` (несколько недель production-использования без жалоб) — рассмотреть включение в auto-detect chain.
+160
View File
@@ -0,0 +1,160 @@
# 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-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-дефолте этого недостаточно;
- **качество моделей друг относительно друга не измерялось.** Ручная проверка
отвечает на вопрос «работает ли», а не «лучше ли»; сравнение — отдельная
работа, см. [backlog](../backlog.md).
Пошаговый чеклист и практика прогона нужны только на время работ и живут в
задаче трекера
([#1](https://git.dementev.space/ddmitry/local-transcriber/issues/1)), а не в
этом документе.
## Документация
README: три модели в таблицу ONNX-моделей. Рекомендация остаётся прежней —
`gigaam-v3` для русского — пока нет данных, чтобы её менять; у новых моделей
стоит оговорка, что скорость на слабых CPU не измерялась. Требование Python
правится в [`docs/PRD.md`](../PRD.md) — раздел «Требования» и таблица
технологий; в README версии Python не упоминаются.