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>
This commit is contained in:
2026-03-18 21:43:06 +03:00
co-authored by Claude Opus 4.6
parent e28232ef50
commit b7e6ab634a
6 changed files with 163 additions and 70 deletions
+10 -8
View File
@@ -6,7 +6,7 @@ import typer
from rich.console import Console
from rich.status import Status
from .config import load_config, resolve_defaults
from .config import apply_device_defaults, load_config, resolve_defaults
from .formatter import format_transcript, write_transcript
from .transcriber import (
Segment,
@@ -34,27 +34,29 @@ console = Console(stderr=True)
def main(
files: list[Path] = typer.Argument(..., help="Пути к аудио/видеофайлам"),
model: str | None = typer.Option(
None, "--model", "-m", show_default=False, help="Модель Whisper [по умолч.: large-v3]"
None, "--model", "-m", show_default=False, help="Модель Whisper [по умолч.: medium]"
),
language: str | None = typer.Option(
None, "--language", "-l", show_default=False, help="Язык (ru|en|auto) [по умолч.: auto]"
None, "--language", "-l", show_default=False, help="Язык [по умолч.: ru]"
),
output: Path | None = typer.Option(None, "--output", "-o", help="Путь к выходному файлу"),
device: str | None = typer.Option(
None, "--device", "-d", show_default=False, help="Устройство (auto|cpu|cuda) [по умолч.: auto]"
),
compute_type: str | None = typer.Option(
None, "--compute-type", show_default=False, help="Тип вычислений [по умолч.: int8]"
None, "--compute-type", show_default=False,
help="Тип вычислений [по умолч.: float16 (GPU) / float32 (CPU)]"
),
verbose: bool = typer.Option(False, "--verbose", "-v", help="Подробный вывод"),
force: bool = typer.Option(False, "--force", "-f", help="Перезаписать существующие транскрипты"),
) -> None:
try:
config = load_config()
defaults = resolve_defaults(
{"model": model, "language": language, "device": device, "compute_type": compute_type},
config,
)
cli_values = {"model": model, "language": language, "device": device, "compute_type": compute_type}
defaults = resolve_defaults(cli_values, config)
resolved_device = detect_device(defaults["device"])
defaults = apply_device_defaults(defaults, resolved_device, cli_values, config)
expanded = expand_globs(files)
if not expanded:
+28 -3
View File
@@ -8,10 +8,15 @@ else:
import tomli as tomllib
HARDCODED_DEFAULTS: dict[str, str] = {
"model": "large-v3",
"language": "auto",
"model": "medium",
"language": "ru",
"device": "auto",
"compute_type": "int8",
"compute_type": "float32",
}
DEVICE_DEFAULTS: dict[str, dict[str, str]] = {
"cuda": {"model": "medium", "compute_type": "float16"},
"cpu": {"model": "medium", "compute_type": "float32"},
}
_VALID_KEYS = set(HARDCODED_DEFAULTS)
@@ -83,3 +88,23 @@ def resolve_defaults(
else:
result[key] = HARDCODED_DEFAULTS[key]
return result
def apply_device_defaults(
defaults: dict[str, str],
resolved_device: str,
cli_values: dict[str, str | None],
config: dict[str, str],
) -> dict[str, str]:
"""Применяет device-aware дефолты для model и compute_type,
если они не были явно заданы через CLI или конфиг."""
device_defs = DEVICE_DEFAULTS.get(resolved_device, {})
if not device_defs:
return defaults
result = dict(defaults)
for key in ("model", "compute_type"):
if cli_values.get(key) is None and key not in config:
if key in device_defs:
result[key] = device_defs[key]
return result
-1
View File
@@ -30,7 +30,6 @@ MODEL_ALLOW_PATTERNS = [
MODEL_REQUIRED_FILES = [
"config.json",
"preprocessor_config.json",
"model.bin",
"tokenizer.json",
]