Commit Graph
21 Commits
Author SHA1 Message Date
ddadmin a3d0213cb3 feat(onnx-asr): добавить скелет бэкенда с разрешением алиасов моделей
- Зачем:
  - 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
2026-04-25 21:19:33 +03:00
ddadminandClaude Opus 4.6 857267763c feat(cli): --threads для управления CPU-потоками + бенчмарк CUDA compute_type
- Зачем:
  - 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>
2026-03-24 22:49:16 +03:00
Dmitry DementievandClaude Opus 4.6 617181f2dc feat(openvino): добавлена поддержка Intel GPU через OpenVINO
- Зачем:
  - OpenVINO backend хардкодил "CPU", хотя Intel Arc GPU доступен и даёт ~2x ускорение.
- Что:
  - новые device modes: --device openvino-gpu, openvino-cpu; openvino — авто-детект GPU/CPU.
  - detect_device() проверяет Intel GPU через OpenVINO Core API (с fail-safe).
  - OpenVINOBackend передаёт "GPU"/"CPU" в WhisperPipeline вместо хардкода "CPU".
  - подсказка "Совет: --model large-v3" при наличии GPU и модели не large-v3.
  - .gitattributes для нормализации line endings (eol=lf).
  - 150 тестов, включая GPU detection, routing, fallback, CLI device info.
  - README, docs/gpu.md, docs/PRD.md обновлены для Intel GPU.
- Проверка:
  - uv run pytest (150 passed).
  - uv run transcribe --device openvino-gpu file.mp4 на Intel Arc 140T GPU.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 15:45:27 +03:00
ddadminandClaude Opus 4.6 f42d3ae842 fix(openvino): корректный compute_type в CLI + индикатор прогресса
- Зачем:
  - 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>
2026-03-22 11:58:29 +03:00
ddadminandClaude Opus 4.6 262bfd91d1 fix(openvino): исправлены баги compute_type, fallback и help text
- Зачем:
  - compute_type из конфига терялся как implicit, ломая выбор модели OpenVINO.
  - узкий матчинг ошибок пропускал реальные OpenVINO runtime failures.
  - ensure_model_available(device="openvino") падал из-за дефолта float32.
  - ensure_model_available не передавал compute_type_explicit, ломая large-v3 → fp16 override.
  - help по --compute-type не отражал дефолт для OpenVINO.
- Что:
  - ct_explicit учитывает и CLI-флаг, и конфиг-файл.
  - публичный API transcribe() передаёт compute_type_explicit=True.
  - _is_openvino_error() ловит любой RuntimeError.
  - ensure_model_available: дефолт compute_type из DEVICE_DEFAULTS, explicit прокинут в get_backend.
  - --compute-type help обновлён: float16 (CUDA) / int8 (OpenVINO) / float32 (CPU).
- Проверка:
  - uv run pytest -v — 124 passed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 23:45:27 +03:00
ddadminandClaude Opus 4.6 ee9e017083 feat(transcriber): cross-backend fallback openvino → cpu
- Зачем:
  - если 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>
2026-03-21 23:30:50 +03:00
ddadminandClaude Opus 4.6 42bfbe5280 feat(openvino): реализован OpenVINO бэкенд транскрипции
- Зачем:
  - ускорение транскрипции на 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>
2026-03-21 23:28:22 +03:00
ddadminandClaude Opus 4.6 fae25a7fb3 feat(config): добавлена поддержка устройства openvino в конфиге и auto-detect
- Зачем:
  - подготовка к 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>
2026-03-21 23:22:13 +03:00
ddadminandClaude Opus 4.6 4c5399c2fc refactor(transcriber): введена pluggable-архитектура бэкендов транскрипции
- Зачем:
  - подготовка к добавлению 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>
2026-03-21 23:18:39 +03:00
ddadminandClaude Opus 4.6 87f7dc1723 docs(readme): редизайн README и удаление зависимости от ffmpeg
- Зачем:
  - 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>
2026-03-18 23:07:39 +03:00
ddadminandClaude Opus 4.6 b7e6ab634a feat(config): добавлены device-aware дефолты и результаты тестов
- Зачем:
  - тестирование на реальных записях показало, что 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>
2026-03-18 21:43:06 +03:00
ddadminandClaude Opus 4.6 e28232ef50 feat(cli): добавлен батч-режим и конфигурационный файл (шаги 8–12)
- Зачем:
  - обработка нескольких файлов за один вызов с загрузкой модели один раз.
  - хранение дефолтов (модель, язык, устройство) в .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>
2026-03-18 20:57:19 +03:00
ddadminandClaude Opus 4.6 a72ac1187c feat(cli): реализована обработка ошибок и graceful Ctrl+C (шаг 6)
- Зачем:
  - пользователь видел 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>
2026-03-18 19:48:27 +03:00
ddadminandClaude Opus 4.6 c1eed7690d feat(formatter): объединение сегментов в абзацы по паузам
- Зачем:
  - мелкая нарезка (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>
2026-03-18 19:33:52 +03:00
ddadminandClaude Opus 4.6 a9a44b8d3a feat(transcriber): добавлен прогресс транскрипции, исправлена формулировка статуса
- Зачем:
  - при длительной транскрипции пользователь видел только спиннер без информации
    о ходе обработки; формулировка "Загружаю модель" путала с загрузкой из сети.
- Что:
  - спиннер показывает позицию и длительность: "Транскрибирую... 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>
2026-03-18 19:14:08 +03:00
ddadminandClaude Opus 4.6 bdb9b06855 feat(cuda): добавлен прозрачный GPU runtime для Linux/WSL2
- Зачем:
  - 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>
2026-03-18 18:37:14 +03:00
ddadmin 3d14ed7b86 feat(cli): реализован шаг 5 — CLI-связка всех модулей с исправлениями из ревью
- Зачем:
  - шаг 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 показывает все опции.
2026-03-17 23:38:32 +03:00
ddadminandClaude Opus 4.6 0d1a734479 feat(formatter): реализовано форматирование транскрипта (шаг 4)
- Зачем:
  - необходим модуль формирования markdown-файла с таймкодами и метаданными.
- Что:
  - реализованы format_timestamp (MM:SS.ss / HH:MM:SS.ss), format_transcript (шапка по PRD 3.3, авто-часы при >1ч, пустая речь), write_transcript (UTF-8).
  - добавлено 6 тестов в test_formatter.py (22 теста зелёные).
- Проверка:
  - uv run pytest tests/test_formatter.py -v (6 passed).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 22:35:30 +03:00
ddadminandClaude Opus 4.6 dfc5f46bf3 feat(transcriber): реализована обёртка над faster-whisper (шаг 3)
- Зачем:
  - необходим модуль транскрипции с 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>
2026-03-17 22:30:40 +03:00
ddadmin 510d6ccfc9 feat(utils): реализованы проверки окружения (шаг 2)
- Зачем:
  - необходимы утилиты для проверки 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())"
2026-03-17 21:51:22 +03:00
ddadmin ade3b23301 feat(scaffold): добавлена начальная структура проекта local-transcriber
- Зачем:
  - необходима базовая структура пакета для последовательной реализации шагов по плану.
- Что:
  - создан pyproject.toml с зависимостями typer, rich и dev-зависимостью pytest.
  - добавлены модули-заглушки cli.py, transcriber.py, formatter.py, utils.py с сигнатурами и raise NotImplementedError.
  - созданы пустые тестовые файлы test_formatter.py, test_transcriber.py, test_utils.py.
  - добавлены .gitignore и uv.lock; отмечены чекбоксы шага 1 в docs/plan.md.
- Проверка:
  - uv run transcribe --help — показывает аргументы.
  - uv run pytest — тесты обнаруживаются без ошибок.
  - python -c "from local_transcriber import cli, transcriber, formatter, utils" — импорт без ошибок.
2026-03-17 21:46:10 +03:00