feat(transcriber): добавлен прогресс транскрипции, исправлена формулировка статуса
- Зачем:
- при длительной транскрипции пользователь видел только спиннер без информации
о ходе обработки; формулировка "Загружаю модель" путала с загрузкой из сети.
- Что:
- спиннер показывает позицию и длительность: "Транскрибирую... 05:32 / 15:52 [87 сегм.]".
- статус инициализации изменён на "Инициализирую модель на cuda/cpu...".
- VAD-фильтр протестирован и отклонён: ухудшает сегментацию для совещаний
(315-321 сегмент вместо 235 без VAD).
- Проверка:
- uv run pytest -v (52 passed, 1 skipped).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -66,7 +66,7 @@ def transcribe(
|
||||
lang_arg = language if language and language != "auto" else None
|
||||
|
||||
try:
|
||||
_notify_status(on_status, f"Загружаю модель на {device}...")
|
||||
_notify_status(on_status, f"Инициализирую модель на {device}...")
|
||||
model = _create_model(model_name, device, compute_type)
|
||||
except (RuntimeError, ValueError) as exc:
|
||||
if device != "cpu" and _is_cuda_error(exc):
|
||||
@@ -78,14 +78,14 @@ def transcribe(
|
||||
stacklevel=2,
|
||||
)
|
||||
actual_device = "cpu"
|
||||
_notify_status(on_status, "Загружаю модель на cpu...")
|
||||
_notify_status(on_status, "Инициализирую модель на cpu...")
|
||||
model = _create_model(model_name, "cpu", compute_type)
|
||||
else:
|
||||
raise
|
||||
|
||||
try:
|
||||
_notify_status(on_status, "Транскрибирую...")
|
||||
segments, info = _run_transcription(model, file_path, lang_arg, on_segment)
|
||||
segments, info = _run_transcription(model, file_path, lang_arg, on_segment, on_status)
|
||||
except (RuntimeError, ValueError) as exc:
|
||||
if actual_device != "cpu" and _is_cuda_error(exc):
|
||||
if strict_device:
|
||||
@@ -96,10 +96,10 @@ def transcribe(
|
||||
stacklevel=2,
|
||||
)
|
||||
actual_device = "cpu"
|
||||
_notify_status(on_status, "Загружаю модель на cpu...")
|
||||
_notify_status(on_status, "Инициализирую модель на cpu...")
|
||||
model = _create_model(model_name, "cpu", compute_type)
|
||||
_notify_status(on_status, "Транскрибирую...")
|
||||
segments, info = _run_transcription(model, file_path, lang_arg, on_segment)
|
||||
segments, info = _run_transcription(model, file_path, lang_arg, on_segment, on_status)
|
||||
else:
|
||||
raise
|
||||
|
||||
@@ -139,15 +139,21 @@ def ensure_model_available(
|
||||
return str(downloaded_path)
|
||||
|
||||
|
||||
def _run_transcription(model, file_path, lang_arg, on_segment):
|
||||
def _run_transcription(model, file_path, lang_arg, on_segment, on_status=None):
|
||||
"""Run model.transcribe and iterate segments. Returns (segments, info)."""
|
||||
segment_generator, info = model.transcribe(str(file_path), language=lang_arg)
|
||||
total_duration = info.duration
|
||||
segments: list[Segment] = []
|
||||
for raw_seg in segment_generator:
|
||||
seg = Segment(start=raw_seg.start, end=raw_seg.end, text=raw_seg.text)
|
||||
if on_segment is not None:
|
||||
on_segment(seg)
|
||||
segments.append(seg)
|
||||
_notify_status(
|
||||
on_status,
|
||||
f"Транскрибирую... {_fmt_time(seg.end)} / {_fmt_time(total_duration)}"
|
||||
f" [{len(segments)} сегм.]",
|
||||
)
|
||||
return segments, info
|
||||
|
||||
|
||||
@@ -174,6 +180,12 @@ def _is_missing_socksio_error(exc: BaseException) -> bool:
|
||||
return "socks proxy" in msg and "socksio" in msg
|
||||
|
||||
|
||||
def _fmt_time(seconds: float) -> str:
|
||||
m, s = divmod(int(seconds), 60)
|
||||
h, m = divmod(m, 60)
|
||||
return f"{h}:{m:02d}:{s:02d}" if h else f"{m:02d}:{s:02d}"
|
||||
|
||||
|
||||
def _notify_status(on_status: Callable[[str], None] | None, message: str) -> None:
|
||||
if on_status is not None:
|
||||
on_status(message)
|
||||
|
||||
@@ -247,8 +247,9 @@ def test_transcribe_reports_status_transitions(mock_model_cls):
|
||||
)
|
||||
|
||||
assert statuses == [
|
||||
"Загружаю модель на cpu...",
|
||||
"Инициализирую модель на cpu...",
|
||||
"Транскрибирую...",
|
||||
"Транскрибирую... 00:04 / 01:00 [1 сегм.]",
|
||||
]
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user