Эксперимент с DeepSeek V4 Pro: добавление onnx-asr бэкенда (Parakeet/GigaAM/
FastConformer) с независимой валидацией качества через agent-judge.
Реализация:
- backends/onnx_asr.py — третий pluggable backend через onnxruntime + Silero VAD.
- --device onnx с моделями gigaam-v3 (рекомендуется для русского) и parakeet-v3.
- _normalize_quantization() — маппинг compute_type → onnx-asr quantization
(int8/fp16 pass-through, float16→fp16, float32/fp32→None, остальные→ValueError).
- DEVICE_DEFAULTS для onnx, _VALID_DEVICES расширен.
Документация:
- ADR-006 — итоги: GigaAM v3 как best-CPU choice для русских встреч, Parakeet
непригоден для русского (воспроизведены три класса проблем из ADR-005), новый
класс ошибок Whisper medium на длинных файлах с тихими фрагментами.
- backlog.md — устойчивый список будущих экспериментов (GigaAM v3 RNN-T и др.).
Контекст эксперимента:
- ADR-005 (Opus, master) отклонил Parakeet на двух 15-мин файлах с тихим
микрофоном. ADR-006 повторяет на 22-81-мин файлах + добавляет GigaAM.
- Реализация прошла три фазы валидации: smoke-test (4 mock-API расхождения
→ fix), agent-judge на 9 транскриптах (подтверждение проблем Parakeet,
обнаружение Whisper-галлюцинаций), adversarial-review через GPT-5.5
(compute_type=float32 ломал onnx-загрузку → fix + 4 теста).
Не включено в merge: docs/superpowers/specs/ и plans/ от DeepSeek (stale
assumptions, итоговый канон в ADR-006; полные документы — в истории ветки).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
При adversarial review (gpt-5.5) обнаружено: пользователь с config
compute_type = "float32" и --device onnx падал на старте.
HARDCODED_DEFAULTS["compute_type"] = "float32", apply_device_defaults не
заменяет значение если оно есть в config — старая проверка
(compute_type in ("int8", "fp16", "float32")) пропускала "float32"
дальше как onnx_asr quantization, что заставляло искать несуществующий
файл с суффиксом _float32.
- _normalize_quantization() — explicit маппинг в onnx-asr quantization.
- float32/fp32 → None (unquantized loading в onnx-asr — это None, не строка).
- float16 → fp16 (CUDA-naming → onnx-asr-naming).
- int8/fp16 → pass-through.
- Неизвестные compute_type (например, int8_float32 от CTranslate2) → ValueError
вместо silent fallback на int8 — пользователь раньше получал не ту
модель без предупреждения.
4 новых теста: float32→None, fp32→None, float16→fp16, unknown→raises.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
В проекте не было общего файла для будущих идей: docs/plan.md — историческая
летопись (всё [x]), docs/gpu.md — потенциальные направления привязаны к GPU/CPU
производительности, открытые вопросы из ADR легко теряются среди следующих ADR.
Создан docs/backlog.md как канонический хаб для будущих экспериментов
с обоснованием, цифрами и ссылками на источники. Первые записи:
- GigaAM v3 RNN-T — потенциальная замена CTC-дефолта (WER 2.6% vs 13.2%
на сложных текстах, e2e_rnnt c пунктуацией, 70:30 vs Whisper-large-v3 LLM-judge)
- Canary 1B — multilingual + пунктуация на CPU
- Whisper medium галлюцинации на длинных файлах (chunk_length / pipeline-фильтры)
- Качественный pipeline для OpenVINO (давно зафиксировано в gpu.md)
- Включение onnx в --device auto после стабилизации
Все направления связаны ссылками на источники (ADR-006, gpu.md, публикации
SberDevices), чтобы при возврате к работе не пришлось воспроизводить контекст.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Переименовано из 005 в 006: на master уже есть ADR-005-parakeet-evaluation
от прошлого эксперимента (Opus, отклонение Parakeet), нумерация бы конфликтовала.
Качество замерено независимым agent-judge'ем по методологии ADR-005
на 9 транскриптах (3 файла × 3 backend), а не субъективными пометками
"Отлично/Хорошо" на одном файле, как в первой версии. Артефакты транскриптов
лежат в /mnt/c/ddmitry/Videos/OBS/ для верификации.
Подтверждены три класса проблем Parakeet из ADR-005 (Mm-hmm-редукция,
иноязычные вставки, искажение IT-терминов) на новом наборе файлов
с конкретными цитатами и таймкодами.
Обнаружен новый класс ошибок Whisper medium: галлюцинации на длинных
файлах с тихими фрагментами (до 17 минут потеряно на одном файле,
многоминутные повторы, приписывание несуществующих имён). Не описано
в ADR-005, потому что там были 15-минутные отрывки.
GigaAM v3 подтверждён как лучший backend для русских встреч на CPU
(summary utility 4/5 на всех файлах, единственный без потерь содержания).
Рекомендация в README уточнена: parakeet-v3 для русского не подходит,
openvino-cpu medium — только для встреч ≤30 мин с равномерной громкостью.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Зачем:
- в README не было рекомендаций по выбору между gigaam-v3 и parakeet-v3.
- Что:
- добавлена таблица ONNX-моделей с RTFx, языками и пунктуацией.
- пример parakeet-v3 изменён на --language ru.
- рекомендации: gigaam-v3 для скорости, parakeet-v3 для пунктуации.
- Проверка:
- uv run pytest -q (172 passed).
- Зачем:
- задокументировать результаты сравнения gigaam-v3 vs OpenVINO на CPU.
- Что:
- таблица скорости по 3 файлам (3-5x ускорение).
- сравнение качества русской речи с GPU faster-whisper.
- решение: оставить бэкенд как экспериментальный (--device onnx).
- Проверка:
- просмотр docs/adr/005-onnx-asr-backend.md.
- Зачем:
- при smoke-тесте выявлены расхождения между onnx-asr API и мок-тестами.
- Что:
- убран deprecated cpu_preprocessing из load_model.
- sample_rate передан как keyword-аргумент в recognize().
- исправлены имена полей SegmentResult: start_ts→start, end_ts→end.
- добавлен device "onnx" в DEVICE_DEFAULTS и _VALID_DEVICES.
- Проверка:
- uv run pytest -q (172 passed).
- uv run transcribe file.mp4 --device onnx --model gigaam-v3.
- Зачем:
- Экспериментальное сравнение скорости и качества транскрипции на реальных аудиофайлах.
- Что:
- скрипт compare_backends.py запускает транскрипцию одного файла через gigaam-v3, parakeet-v3 и OpenVINO medium.
- выводит время, количество сегментов и превью текста для каждого.
- Проверка:
- python scripts/compare_backends.py /path/to/audio.mp3
- Зачем:
- Основной метод бэкенда — транскрипция аудиофайла в сегменты с временными метками.
- Что:
- метод transcribe декодирует аудио через faster_whisper.decode_audio, затем вызывает model.recognize() с VAD-сегментацией.
- каждый VAD-сегмент преобразуется в проектную структуру Segment.
- поддержка колбэков on_segment, on_status.
- написаны 4 теста: сбор сегментов, вызов on_segment, передача языка, обработка пустого аудио.
- Проверка:
- uv run pytest tests/test_onnx_asr.py -v (14 passed)
- Зачем:
- onnx-asr модель должна создаваться с квантизацией и VAD для разбивки аудио на сегменты.
- Что:
- метод create_model вызывает onnx_asr.load_model с квантизацией и cpu_preprocessing=True.
- подгружается Silero VAD, прикрепляется к модели через with_vad.
- написаны 3 теста: проверка аргументов load_model, загрузка VAD, передача fp16.
- Проверка:
- uv run pytest tests/test_onnx_asr.py -v
- Зачем:
- Бэкенд должен резолвить алиасы моделей и сохранять compute_type для дальнейшего использования.
- Что:
- добавлен конструктор __init__ с полями actual_compute_type, _resolved_model_id, _vad.
- метод ensure_model_available валидирует алиас и возвращает идентификатор модели onnx-asr.
- написаны 3 теста на резолвинг и сохранение compute_type.
- Проверка:
- uv run pytest tests/test_onnx_asr.py -v
- Зачем:
- onnx-asr бэкенд должен распознавать короткие алиасы (gigaam-v3, parakeet-v3) и raw-имена (nemo-canary-1b-v2).
- Что:
- создан файл backends/onnx_asr.py с MODEL_ALIASES и классом OnnxAsrBackend.
- метод _resolve_model: преобразует алиасы, пропускает raw-имена, выдаёт ValueError для неизвестных.
- написаны 4 теста на разрешение алиасов.
- Проверка:
- uv run pytest tests/test_onnx_asr.py::TestModelAliases -v
- Зачем:
- зафиксировать в master результат эксперимента с Parakeet-бэкендом:
что проверяли, какие цифры получили, почему оставили Whisper как дефолт.
Знания доступны, код — в экспериментальной ветке feature/parakeet-backend.
- Что:
- docs/adr/005-parakeet-evaluation.md — полный контекст решения: гипотеза,
методология, метрики скорости (Parakeet 2.7x быстрее, -35% RAM),
качество (Summary utility 2-3/5 vs 4/5 у Whisper), систематические
проблемы модели на тихой русской речи, VAD-тюнинг не помог, условия
пересмотра решения в будущем (английский / live-captioning / русские
specialized-модели через onnx-asr).
- docs/gpu.md — короткая заметка под «Потенциальные направления развития»
со ссылкой на ADR-005.
- Проверка:
- cat docs/adr/005-parakeet-evaluation.md.
- grep -A5 "Parakeet TDT — проверено" docs/gpu.md.
- ветка feature/parakeet-backend сохранена и не удаляется.
- Зачем:
- зафиксировать дизайн экспериментального бэкенда до имплементации; гипотеза — Parakeet TDT v3 быстрее/качественнее Whisper на Intel/AMD встройках.
- Что:
- добавлен docs/superpowers/specs/2026-04-18-parakeet-backend-design.md после 3 раундов adversarial-review.
- зафиксированы: onnx-asr+Silero VAD как runtime, CPU EP в MVP, --device parakeet, int8/fp32 compute_type, no-fallback политика, long-audio gate с blocker-thresholds (peak RSS ≤4GB, первый status ≤10с, interval ≤30с, offline после первого запуска).
- Проверка:
- cat docs/superpowers/specs/2026-04-18-parakeet-backend-design.md.
float16 требует CC ≥ 7.0, float32 падает с ошибкой — пребилды
CTranslate2 4.x не включают sm_50/sm_60. Рекомендация: --device cpu
или --device openvino.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Зачем:
- CTranslate2 по умолчанию использует 4 потока; на многоядерных CPU (8+ ядер)
это неоптимально — --threads 8 даёт +13% ускорения.
- Не было данных по int8_float32/int8_float16 на NVIDIA GPU.
- Что:
- --threads / -t: новый CLI-флаг, пробрасывается через load_model →
backend.create_model(cpu_threads=...) → WhisperModel(cpu_threads=...).
- Валидация min=0 на входе (typer), Backend протокол синхронизирован.
- docs/gpu.md: результаты бенчмарка 6 комбинаций CUDA compute_type
(medium/large-v3 × float16/int8_float32/int8_float16) на двух файлах
(16 мин и 46 мин). Ключевой вывод: float16 — оптимальный дефолт;
large-v3 ненадёжен на длинных записях.
- README: --threads добавлен в таблицу опций.
- Фикс теста: test_resolve_repo_explicit_unsupported_pair_raises обновлён
под добавление medium fp16 модели.
- Проверка:
- uv run pytest: 157 passed.
- transcribe file.mp4 --device cpu --threads 8: 277с vs 320с (дефолт).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Добавлена pluggable-архитектура бэкендов транскрипции и OpenVINO
как второй движок для ускорения на Intel/AMD CPU в 3-6 раз.
- Backend Protocol (structural typing) + реестр с lazy imports
- FasterWhisperBackend (CUDA/CPU) — рефакторинг без изменения поведения
- OpenVINOBackend — openvino-genai WhisperPipeline, предквантизированные модели
- Auto-detect: CUDA → OpenVINO → CPU
- Cross-backend fallback с сохранением состояния в батч-режиме
- Тесты на 3 CPU: Intel Ultra 7, AMD Ryzen 7, Intel i7 (WSL2)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Зачем:
- индикатор "00:32 / 16:02" был неочевиден — два одинаковых формата.
- путь в "Транскрипт сохранён" отображался разным цветом из-за Rich bold-разметки.
- Что:
- формат прогресса: "Транскрибирую 16 мин аудио (OpenVINO)... прошло 00:32".
- путь выводится в кавычках без bold-разметки, единым цветом.
- Проверка:
- uv run pytest -q — 124 passed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Зачем:
- CLI показывал int8, хотя реально использовался fp16 для large-v3.
- при транскрипции OpenVINO не было индикации прогресса.
- Что:
- _resolve_repo возвращает (repo_id, actual_compute_type).
- бэкенды сохраняют actual_compute_type после ensure_model_available.
- CLI выводит фактический compute_type после load_model, а не дефолтный.
- generate() запускается в потоке, статус обновляется каждую секунду с elapsed time.
- Проверка:
- uv run pytest -q — 124 passed.
- uv run transcribe file.mp4 --device openvino --model large-v3 показывает fp16.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Зачем:
- OpenVINO GenAI может вернуть отрицательный end_ts, ломая формат транскрипта.
- зафиксировать бенчмарки на Intel и AMD CPU для документации.
- Что:
- backends/openvino.py: start/end клампятся через max(0, ...).
- docs/gpu.md: полная таблица скорости Intel i7 vs AMD Ryzen 7 8845H.
- сравнение качества medium int8 vs large-v3 fp16 vs CPU float32 на одном файле.
- вывод: large-v3 OpenVINO (416с) быстрее medium CPU (734с) при лучшем качестве.
- Проверка:
- uv run pytest -q — 124 passed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Зачем:
- зафиксировать реальные бенчмарки OpenVINO перед мержем в main.
- Что:
- скорость: OpenVINO medium int8 в 3-4x быстрее CPU float32 (205с vs 658с на 16 мин файле).
- качество: сопоставимо с CPU float32 и CUDA float16, галлюцинаций нет.
- таблица ожидаемой скорости обновлена с OpenVINO строкой.
- отмечено, что тестирование на AMD CPU пока не проводилось.
- Проверка:
- uv run transcribe file.mp4 --device openvino.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Зачем:
- если OpenVINO не справляется (ошибка init или mid-stream), нужен автоматический переход на CPU через faster-whisper.
- Что:
- _is_openvino_error() распознаёт ошибки OpenVINO runtime по паттернам в сообщении.
- _is_backend_error() теперь маршрутизирует на правильную проверку по device.
- при fallback: скачивается модель для CPU бэкенда, создаётся новая модель, обновляются backend/model_path.
- 3 интеграционных теста: openvino→cpu init fallback, midstream fallback, strict_device без fallback.
- Проверка:
- uv run pytest -v — 122 passed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Зачем:
- ускорение транскрипции на x86 CPU (Intel/AMD) в 2-4 раза через OpenVINO GenAI.
- Что:
- создан backends/openvino.py: OpenVINOBackend с ensure_model_available, create_model, transcribe.
- модели скачиваются из HuggingFace (OpenVINO/whisper-*-ov), формат OpenVINO IR.
- аудио декодируется через faster_whisper.decode_audio (PyAV) → .tolist() → pipe.generate(return_timestamps=True).
- контракт compute_type: явный --compute-type уважается; из дефолтов large-v3 получает fp16 автоматически.
- openvino-genai добавлен в pyproject.toml с platform markers (x86_64/AMD64, не macOS).
- compute_type_explicit прокинут через get_backend → load_model → CLI.
- 16 тестов для OpenVINO бэкенда: resolve_repo, ensure, create, transcribe, validate.
- Проверка:
- uv run pytest -v — 119 passed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Зачем:
- подготовка к OpenVINO бэкенду: config и utils должны знать о новом устройстве.
- Что:
- config.py: openvino добавлен в _VALID_DEVICES и DEVICE_DEFAULTS (model=medium, compute_type=int8).
- utils.py: detect_device() расширен цепочкой CUDA → OpenVINO → CPU; _is_openvino_available() проверяет архитектуру (x86_64/AMD64) и наличие openvino_genai.
- cli.py: --device help text обновлён (auto|cpu|cuda|openvino).
- добавлены тесты: config с openvino device, device defaults, auto-detect приоритет.
- Проверка:
- uv run pytest -v — 103 passed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Зачем:
- подготовка к добавлению OpenVINO бэкенда для ускорения на x86 CPU без CUDA.
- архитектура должна позволять добавлять новые бэкенды (CoreML, AMD XDNA) без переписывания кода.
- Что:
- создан types.py с общими типами (Segment, TranscribeResult, TranscribeFileResult).
- создан backends/base.py с Backend Protocol (3 метода: ensure_model_available, create_model, transcribe).
- создан backends/faster_whisper.py — текущий код вынесен из transcriber.py в FasterWhisperBackend.
- transcriber.py переделан в оркестратор: load_model() владеет полным пайплайном (ensure + create), CLI больше не вызывает ensure_model_available() отдельно.
- TranscribeFileResult расширен полями backend и model_path для корректного cross-backend fallback в батч-режиме.
- device_used проставляется оркестратором, а не бэкендом.
- cli.py: вынесен _format_device_info(), подготовлен к openvino.
- тесты обновлены: mock-точки перенесены с WhisperModel на get_backend/бэкенд-объекты.
- Проверка:
- uv run pytest -v — 98 passed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Зачем:
- формальное указание условий использования проекта.
- Что:
- создан файл LICENSE с текстом MIT License.
- добавлено поле license = "MIT" в pyproject.toml.
- Проверка:
- cat LICENSE && grep license pyproject.toml.
- Зачем:
- cublas64_12.dll not found не распознавалась как CUDA-ошибка, fallback на CPU не срабатывал
- Что:
- _is_cuda_error теперь матчит cublas и cudnn в дополнение к cuda и out of memory
- README: добавлен шаг GPU-ускорения в установку, зафиксирована CUDA 12 (ctranslate2 4.7)
- Проверка:
- uv run pytest (97 passed)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Зачем:
- README перегружен деталями GPU/бенчмарков, нет Quick Start, macOS/Windows — второй класс.
- системный ffmpeg не нужен — PyAV (зависимость faster-whisper) включает FFmpeg в wheels.
- Что:
- переписан README: Quick Start в первых строках, установка без клонирования через uv tool install, паритет платформ, progressive disclosure через <details>.
- удалена функция check_ffmpeg() из utils.py, убраны импорт и вызовы из cli.py.
- убраны моки check_ffmpeg и тест ffmpeg-ошибки из test_cli.py.
- GPU-контент вынесен в docs/gpu.md, добавлен CONTRIBUTING.md.
- Проверка:
- uv run pytest — 97 passed, 1 skipped.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Зачем:
- тестирование на реальных записях показало, что int8 даёт галлюцинации на длинных файлах, auto-detect языка ошибается — нужны оптимальные дефолты по устройству.
- Что:
- дефолты: medium float16 (GPU), medium float32 (CPU), language=ru.
- добавлены DEVICE_DEFAULTS и apply_device_defaults() в config.py.
- убран preprocessor_config.json из обязательных файлов модели (отсутствует у medium).
- README обновлён: таблицы скоростей, качества, результаты тестирования compute_type.
- Проверка:
- uv run pytest — 98 passed, 1 skipped.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Зачем:
- обработка нескольких файлов за один вызов с загрузкой модели один раз.
- хранение дефолтов (модель, язык, устройство) в .transcriber.toml.
- Что:
- добавлен config.py: поиск .transcriber.toml (CWD → ~/.config), парсинг, валидация, приоритет CLI > конфиг > хардкод.
- рефакторинг transcriber.py: выделены load_model() и _transcribe_file() с TranscribeFileResult для переиспользования модели в батче.
- добавлены expand_globs() с дедупликацией и has_existing_transcript() в utils.py.
- CLI: files: list[Path], --force/-f, prescan-first батч с итоговой статистикой и временем, Status-спиннер для прогресса.
- README: секции батч-режим, конфигурационный файл, --force в таблице опций.
- ADR-002: зафиксированы архитектурные решения (prescan-first, TranscribeFileResult, конфиг без мержа).
- Проверка:
- uv run pytest -q — 94 passed, 1 skipped.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Зачем:
- чтобы коллега мог установить и запустить проект на Windows/WSL2/Linux без вопросов (шаг 7 plan.md).
- Что:
- создан README.md: требования, установка через uv tool, примеры CLI, таблицы моделей и квантизаций.
- описаны настройка GPU/CUDA по платформам, совместимость GPU, ожидаемая скорость.
- добавлен пример выходного файла, соответствующий реальному формату formatter (HH:MM:SS.ss, группировка абзацев).
- отмечен шаг 7 как выполненный в plan.md.
- Проверка:
- uv tool install . && transcribe --help — CLI доступен глобально.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Зачем:
- пользователь видел raw traceback при ошибках, не было корректной обработки Ctrl+C
- Что:
- graceful Ctrl+C: перехват KeyboardInterrupt → «Прервано пользователем» + exit 130
- пользовательские ошибки (файл не найден, пустой) — чистое сообщение без traceback
- неожиданные ошибки — traceback только с --verbose, иначе подсказка
- Windows CUDA диагностика интегрирована в общий обработчик ошибок
- логика вынесена в _run(), обработка ошибок — в main()
- Проверка:
- uv run pytest -v — 60 passed, 1 skipped
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Зачем:
- мелкая нарезка (235 строк на 16 мин) засоряет контекст при передаче
транскрипта в ИИ для дальнейшей обработки.
- Что:
- соседние сегменты объединяются в абзацы: новый абзац при паузе > 2с
или длительности > 60с.
- 235 строк -> 58 строк на том же файле (4x компактнее).
- Проверка:
- uv run pytest tests/test_formatter.py -v (11 passed).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Зачем:
- при длительной транскрипции пользователь видел только спиннер без информации
о ходе обработки; формулировка "Загружаю модель" путала с загрузкой из сети.
- Что:
- спиннер показывает позицию и длительность: "Транскрибирую... 05:32 / 15:52 [87 сегм.]".
- статус инициализации изменён на "Инициализирую модель на cuda/cpu...".
- VAD-фильтр протестирован и отклонён: ухудшает сегментацию для совещаний
(315-321 сегмент вместо 235 без VAD).
- Проверка:
- uv run pytest -v (52 passed, 1 skipped).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Зачем:
- зафиксировать архитектурное решение по GPU runtime и rejected alternatives,
чтобы не переизобретать отклонённые подходы в будущем.
- Что:
- создан docs/adr/001-cuda-bootstrap.md (контекст, решение, tradeoffs, альтернативы).
- PRD 4.2: исправлено описание CUDA-зависимостей (cuDNN не нужен, cuBLAS из pip).
- plan.md: добавлен выполненный шаг 5.1 со ссылкой на ADR.
- удалены docs/plan-gpu-runtime.md и отчёты ревью (review-stages-*).
- Проверка:
- cat docs/adr/001-cuda-bootstrap.md.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Зачем:
- ctranslate2 требует libcublas.so.12 для CUDA, но не бандлит её в wheel —
без системного CUDA toolkit GPU не работает из коробки.
- Что:
- добавлена зависимость nvidia-cublas-cu12 (Linux x86_64).
- создан _cuda_bootstrap.py: preload libcublas через ctypes.CDLL(RTLD_GLOBAL)
до импорта ctranslate2 (LD_LIBRARY_PATH не работает — glibc кеширует пути).
- добавлен strict_device в transcriber: --device cuda/cpu не делает silent fallback.
- CLI: диагностика requested vs resolved device, Windows CUDA-подсказка.
- Проверка:
- uv run pytest -v (52 passed, 1 skipped).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Зачем:
- шаг 5 плана: нужен рабочий CLI-happy path, связывающий utils / transcriber / formatter.
- ревью этапов 4–5 выявило два medium-бага в formatter и отсутствие тестов для CLI.
- Что:
- cli.py: все опции по PRD 3.2 (--model, --language, --output, --device, --compute-type, --verbose),
rich Status + stderr-консоль, предупреждение на пустую речь, статистика времени.
- transcriber.py: добавлена ensure_model_available() с проверкой кэша HF и валидацией
локальной директории; on_status callback для передачи прогресса в CLI; обработка
ImportError при отсутствии socksio через SOCKS proxy.
- formatter.py: исправлен overflow в format_timestamp (0.995 → 00:01.00 вместо 00:00.100);
сегменты теперь пишутся с явным пробелом и strip() независимо от whisper-формата текста.
- deps: добавлен socksio>=1.0.0 для поддержки SOCKS proxy при загрузке модели.
- tests: test_cli.py (8 тестов на CLI-контракт), расширены test_formatter.py и test_transcriber.py.
- Проверка:
- uv run pytest — 42 passed.
- uv run transcribe --help показывает все опции.
- Зачем:
- фиксация результатов code review для трассируемости.
- Что:
- добавлен docs/review-stages-1-3.md с findings и статусом исправлений.
- Проверка:
- cat docs/review-stages-1-3.md.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Зачем:
- необходим модуль транскрипции с CUDA fallback для основного flow приложения.
- Что:
- добавлена зависимость faster-whisper>=1.2.1 в pyproject.toml.
- реализована функция transcribe() с fallback CUDA→CPU на всех этапах (загрузка модели, вызов transcribe, итерация сегментов).
- исправлен IndexError в get_gpu_name() при пустом stdout nvidia-smi.
- добавлено 6 тестов в test_transcriber.py и 1 тест в test_utils.py (16 тестов зелёные).
- Проверка:
- uv run pytest -v (16 passed).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Зачем:
- необходимы утилиты для проверки ffmpeg, определения устройства и
валидации входного файла перед запуском транскрипции.
- Что:
- check_ffmpeg() завершает процесс с понятным сообщением, если ffmpeg не в PATH.
- detect_device() возвращает "cuda" при наличии nvidia-smi, иначе "cpu".
- get_gpu_name() получает имя GPU через nvidia-smi или возвращает None.
- validate_input_file() проверяет существование, тип и размер файла;
неизвестное расширение — warning, не ошибка.
- build_output_path() формирует путь <stem>-transcript.md рядом с исходником.
- Проверка:
- uv run pytest tests/test_utils.py -v — 9 passed.
- uv run python -c "from local_transcriber.utils import check_ffmpeg, detect_device; check_ffmpeg(); print(detect_device())"
- Зачем:
- устранены пробелы в плане: недостающие тесты, неописанные параметры, архитектурные расхождения.
- Что:
- detect_device() возвращает только str (device), compute-type независим от него.
- добавлен get_gpu_name() для человекочитаемой строки устройства в шапке markdown.
- добавлен on_segment callback в transcribe() для --verbose без переделки API.
- добавлено поле device_used в TranscribeResult (фактическое устройство после fallback).
- добавлены тесты: test_utils.py (9 тестов), test_transcriber.py (4 mock-теста).
- выровнено поведение пустой речи: файл с шапкой + *Речь не обнаружена.* в теле (PRD и plan).
- добавлены импорты Callable, datetime, Path в заглушки шага 1.
- убраны строки с git add -A / git commit из всех шагов.
- Проверка:
- открыть docs/plan.md и docs/PRD.md и убедиться в согласованности.
- Зачем:
- зафиксированы требования к проекту и план разработки для выравнивания команды.
- Что:
- добавлен docs/PRD.md с требованиями к продукту.
- добавлен docs/plan.md с планом реализации.
- Проверка:
- открыть docs/PRD.md и docs/plan.md и убедиться в корректности содержимого.