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:
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -30,7 +30,6 @@ MODEL_ALLOW_PATTERNS = [
|
||||
|
||||
MODEL_REQUIRED_FILES = [
|
||||
"config.json",
|
||||
"preprocessor_config.json",
|
||||
"model.bin",
|
||||
"tokenizer.json",
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user