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 и ограничение `onnx-asr<0.12.0`, проверить VAD и квантованные модели; OpenVINO и
OpenVINO GenAI обновлять согласованно. Не фиксировать ONNX Runtime 1.28 для OpenVINO GenAI обновлять согласованно. Не фиксировать ONNX Runtime 1.28 для
Python 3.10. Python 3.10.
Шаг 1 в части onnx-пути вынесен в отдельную работу —
[спека «Onnx-каталог, Python 3.13 и границы версий»](specs/2026-08-11-onnx-model-catalog.md): движок
обновляется, три модели становятся поддерживаемыми, дефолт и OpenVINO не
трогаются намеренно, чтобы сохранить точку отсчёта для будущего сравнения.
2. После интеграционных тестов провести сравнительный бенчмарк моделей. Не 2. После интеграционных тестов провести сравнительный бенчмарк моделей. Не
менять CPU-дефолт только по model card или результату на одном файле. менять CPU-дефолт только по model card или результату на одном файле.
3. Решение зафиксировать в ADR-007, обновить рекомендации README и только затем 3. Решение зафиксировать в ADR-007, обновить рекомендации README и только затем
@@ -226,6 +230,23 @@ SQL`), словарь пользовательский в `.transcriber.toml`.
## Авто-детект и UX ## Авто-детект и 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` ### Включение `onnx` в `--device auto`
**Что:** После периода стабилизации `--device onnx` (несколько недель production-использования без жалоб) — рассмотреть включение в auto-detect chain. **Что:** После периода стабилизации `--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 не упоминаются.