"""Speech recognition via WhisperX or GigaAM (onnx-asr). Also exposes `transcribe_aligned()` for word-level alignment (used by LRC). Models are cached; aggressive VRAM cleanup happens after each file. """ from __future__ import annotations import gc import time from pathlib import Path from typing import Optional class CudaOOMError(RuntimeError): """CUDA OOM, переживший все стратегии понижения нагрузки.""" def _is_cuda_error(exc: BaseException) -> bool: err = str(exc).lower() return ( "out of memory" in err or "cuda" in err or "device ordinal" in err or "cublas" in err or "cudnn" in err ) def _resolve_device(device: str) -> str: if device in ("cuda", "cpu"): return device try: import torch return "cuda" if torch.cuda.is_available() else "cpu" except Exception: return "cpu" def _retry(fn, attempts: int = 3, base_delay: float = 2.0): last = None for i in range(attempts): try: return fn() except Exception as e: last = e if i < attempts - 1: time.sleep(base_delay * (i + 1)) raise last def _free_vram() -> None: gc.collect() try: import torch if torch.cuda.is_available(): torch.cuda.empty_cache() except Exception: # noqa: BLE001 — cleanup must never mask the original error pass def _model_transcribe_with_retry( model_obj, audio, language, batch_size, vad_filter, name="