Audit / engine.py
openmodelai's picture
Upload 11 files
688378c verified
Raw History Blame Contribute Delete
2.36 kB
"""Engine: аудио → текст на базе Whisper base (CTranslate2).
Модель не загружает torch — инференс через ctranslate2 + faster-whisper.
"""
from __future__ import annotations
from pathlib import Path
from typing import Any, Dict, List, Optional, Union
from faster_whisper import WhisperModel
DEFAULT_MODEL_DIR = Path(__file__).resolve().parent.parent / "model"
class AuditEngine:
"""Расшифровщик речи в текст (ASR, 99 языков)."""
def __init__(
self,
model_dir: Optional[Union[str, Path]] = None,
device: str = "cpu",
compute_type: str = "int8",
cpu_threads: int = 0,
) -> None:
model_dir = Path(model_dir or DEFAULT_MODEL_DIR)
if not (model_dir / "model.bin").exists():
raise FileNotFoundError(
f"Веса модели не найдены: {model_dir}/model.bin\n"
"Запустите сначала: python scripts/build_model.py"
)
self.model_dir = model_dir
self.model = WhisperModel(
str(model_dir),
device=device,
compute_type=compute_type,
cpu_threads=cpu_threads,
)
def transcribe(
self,
audio: Union[str, Path],
language: Optional[str] = None,
beam_size: int = 5,
vad_filter: bool = False,
) -> Dict[str, Any]:
"""Транскрибировать аудио. Возвращает dict с текстом и метаданными."""
segments, info = self.model.transcribe(
str(audio),
language=language,
beam_size=beam_size,
vad_filter=vad_filter,
)
parts: List[Dict[str, Any]] = []
for seg in segments:
parts.append(
{
"start": round(float(seg.start), 2),
"end": round(float(seg.end), 2),
"text": seg.text.strip(),
}
)
return {
"text": " ".join(p["text"] for p in parts).strip(),
"language": info.language,
"language_probability": round(float(info.language_probability), 4),
"duration": round(float(info.duration), 2),
"segments": parts,
}