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>
This commit is contained in:
@@ -51,7 +51,7 @@ def main(
|
||||
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]"
|
||||
help="Устройство (auto|cpu|cuda|openvino) [по умолч.: auto]"
|
||||
),
|
||||
compute_type: str | None = typer.Option(
|
||||
None, "--compute-type", show_default=False,
|
||||
|
||||
@@ -19,11 +19,12 @@ HARDCODED_DEFAULTS: dict[str, str] = {
|
||||
DEVICE_DEFAULTS: dict[str, dict[str, str]] = {
|
||||
"cuda": {"model": "medium", "compute_type": "float16"},
|
||||
"cpu": {"model": "medium", "compute_type": "float32"},
|
||||
"openvino": {"model": "medium", "compute_type": "int8"},
|
||||
}
|
||||
|
||||
# Одно место правды для допустимых ключей конфига
|
||||
_VALID_KEYS = set(HARDCODED_DEFAULTS)
|
||||
_VALID_DEVICES = {"auto", "cpu", "cuda"}
|
||||
_VALID_DEVICES = {"auto", "cpu", "cuda", "openvino"}
|
||||
|
||||
|
||||
def find_config_file() -> Path | None:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""Утилиты для валидации входных файлов, определения устройства и работы с путями."""
|
||||
|
||||
import glob
|
||||
import platform
|
||||
import shutil
|
||||
import subprocess
|
||||
import warnings
|
||||
@@ -15,16 +16,30 @@ SUPPORTED_EXTENSIONS = {
|
||||
def detect_device(requested: str = "auto") -> str:
|
||||
"""Определяет устройство для вычислений.
|
||||
|
||||
При ``requested="auto"`` проверяет наличие ``nvidia-smi`` в PATH
|
||||
и возвращает ``"cuda"`` или ``"cpu"``. Явное значение возвращается как есть.
|
||||
При ``requested="auto"`` проверяет: CUDA → OpenVINO → CPU.
|
||||
Явное значение возвращается как есть.
|
||||
"""
|
||||
if requested != "auto":
|
||||
return requested
|
||||
if shutil.which("nvidia-smi") is not None:
|
||||
return "cuda"
|
||||
if _is_openvino_available():
|
||||
return "openvino"
|
||||
return "cpu"
|
||||
|
||||
|
||||
def _is_openvino_available() -> bool:
|
||||
"""Проверяет доступность OpenVINO: x86/AMD64 архитектура + пакет установлен."""
|
||||
if platform.machine().lower() not in {"x86_64", "amd64"}:
|
||||
return False
|
||||
try:
|
||||
import openvino_genai # noqa: F401
|
||||
|
||||
return True
|
||||
except ImportError:
|
||||
return False
|
||||
|
||||
|
||||
def get_gpu_name() -> str | None:
|
||||
"""Возвращает название GPU через ``nvidia-smi`` (для метаданных транскрипта)."""
|
||||
try:
|
||||
|
||||
@@ -128,3 +128,18 @@ def test_apply_device_defaults_config_overrides():
|
||||
result = apply_device_defaults(defaults, "cuda", cli, config)
|
||||
assert result["model"] == "small"
|
||||
assert result["compute_type"] == "int8"
|
||||
|
||||
|
||||
def test_load_config_openvino_device(tmp_path):
|
||||
config = tmp_path / "config.toml"
|
||||
config.write_text('device = "openvino"\n')
|
||||
result = load_config(config)
|
||||
assert result == {"device": "openvino"}
|
||||
|
||||
|
||||
def test_apply_device_defaults_openvino():
|
||||
defaults = {"model": "medium", "language": "ru", "device": "auto", "compute_type": "float32"}
|
||||
cli = {"model": None, "language": None, "device": None, "compute_type": None}
|
||||
result = apply_device_defaults(defaults, "openvino", cli, {})
|
||||
assert result["model"] == "medium"
|
||||
assert result["compute_type"] == "int8"
|
||||
|
||||
@@ -58,6 +58,34 @@ def test_build_output_path_custom():
|
||||
def test_detect_device_explicit():
|
||||
assert detect_device("cpu") == "cpu"
|
||||
assert detect_device("cuda") == "cuda"
|
||||
assert detect_device("openvino") == "openvino"
|
||||
|
||||
|
||||
def test_detect_device_auto_openvino():
|
||||
"""Нет nvidia-smi, есть openvino_genai, x86_64 → openvino."""
|
||||
with (
|
||||
patch("local_transcriber.utils.shutil.which", return_value=None),
|
||||
patch("local_transcriber.utils._is_openvino_available", return_value=True),
|
||||
):
|
||||
assert detect_device("auto") == "openvino"
|
||||
|
||||
|
||||
def test_detect_device_cuda_over_openvino():
|
||||
"""nvidia-smi доступен и openvino тоже → cuda побеждает."""
|
||||
with (
|
||||
patch("local_transcriber.utils.shutil.which", return_value="/usr/bin/nvidia-smi"),
|
||||
patch("local_transcriber.utils._is_openvino_available", return_value=True),
|
||||
):
|
||||
assert detect_device("auto") == "cuda"
|
||||
|
||||
|
||||
def test_detect_device_auto_cpu_fallback():
|
||||
"""Ни nvidia-smi, ни openvino → cpu."""
|
||||
with (
|
||||
patch("local_transcriber.utils.shutil.which", return_value=None),
|
||||
patch("local_transcriber.utils._is_openvino_available", return_value=False),
|
||||
):
|
||||
assert detect_device("auto") == "cpu"
|
||||
|
||||
|
||||
def test_get_gpu_name_no_nvidia_smi():
|
||||
|
||||
Reference in New Issue
Block a user