Skip to content

Add optional Silero VAD backend for longform transcription - #85

Open
gman-dev-nov wants to merge 4 commits into
salute-developers:mainfrom
gman-dev-nov:feat/silero-vad-backend
Open

Add optional Silero VAD backend for longform transcription#85
gman-dev-nov wants to merge 4 commits into
salute-developers:mainfrom
gman-dev-nov:feat/silero-vad-backend

Conversation

@gman-dev-nov

@gman-dev-nov gman-dev-nov commented Aug 10, 2026

Copy link
Copy Markdown

Motivation

transcribe_longform depends on the gated pyannote/segmentation-3.0 model, so the first run requires a Hugging Face account, accepting the model conditions, and an HF_TOKEN. That first step is a real hurdle in corporate and air-gapped environments where creating an HF account or reaching the Hub is not an option.

This PR adds an opt-in alternative: transcribe_longform(..., vad_backend="silero"), using Silero VAD, whose weights ship inside the silero-vad pip package — no account or token needed.

Relation to #24

#24 proposed replacing the pyannote pipeline and was declined. This PR is deliberately different:

  • The default is unchangedtranscribe_longform(...) behaves exactly as before; the pyannote pipeline code in vad_utils.py is untouched.
  • Each backend lives in its own module; the existing chunk-merging logic is shared by both instead of being reimplemented.

Changes

  • gigaam/chunking_utils.py (new) — the span-merging logic moved verbatim out of segment_audio_file; it operates on plain (start, end) tuples, so it is independent of which VAD produced the spans. The four tuning knobs are grouped into a frozen ChunkingConfig dataclass.
  • gigaam/vad_utils.py — pyannote code untouched; segment_audio_file keeps its public signature and delegates merging to chunking_utils.
  • gigaam/silero_vad_utils.py (new) — Silero counterpart of segment_audio_file with a slimmer signature: (wav_file, sr, config: Optional[ChunkingConfig]) — no device argument, since Silero VAD always runs on CPU. Importable without pyannote installed; a missing silero-vad package raises an ImportError pointing to pip install gigaam[silero].
  • gigaam/model.pytranscribe_longform gains a vad_backend: str = "pyannote" keyword (backwards-compatible) and dispatches to the backend module via match/case; the import was already function-local upstream. Unknown values are rejected with a ValueError before any audio is decoded.
  • pyproject.toml — new silero extra (silero-vad==6.2.* — the tested minor, pinned in the repo's style; validated against 6.2.1); also added to tests so CI exercises the new path — happy to drop that if you prefer to keep the tests extra minimal (the new tests importorskip silero-vad, so they degrade to skips).
  • tests/test_longform.py — 3 new tests that run without HF_TOKEN, giving longform coverage even where the secret is unavailable (e.g. PRs from forks). The e2e test compares merged text against the pyannote-based reference via similarity > 0.9 rather than exact boundaries, since chunk borders legitimately differ between VADs.
  • README.md / README_ru.md — one sentence in the longform setup block.

Testing

  • pytest tests/test_longform.py -k "silero or unknown_backend" — 3 passed (Apple M-series: MPS and CPU; silero-vad 6.2.1).
  • black --check, isort --check-only, flake8 (workflow flags), mypy --ignore-missing-imports --no-strict-optional — all clean.
  • Verified in a pyannote-free environment: gigaam.silero_vad_utils imports, vad_backend="silero" transcribes end-to-end.
  • Real-world check: the 71-second sample transcribed with vad_backend="silero" on MPS in ~6 s, merged text matching the pyannote-based reference.

Note on CI: the pre-existing pyannote longform tests will be red on this PR — GitHub does not expose secrets.HF_TOKEN to pull requests from forks. The new silero tests are unaffected and should pass.

@gman-dev-nov
gman-dev-nov force-pushed the feat/silero-vad-backend branch 2 times, most recently from 617f562 to ef2f35b Compare August 10, 2026 13:39
No behavior change. The span-merging logic moves verbatim from
segment_audio_file into chunking_utils.merge_speech_spans and operates
on plain (start, end) tuples, so it no longer depends on which VAD
produced the spans; the four tuning knobs are grouped into a frozen
ChunkingConfig dataclass. The pyannote pipeline code and the public
segment_audio_file signature are untouched.
transcribe_longform(..., vad_backend="silero") segments speech with
Silero VAD, whose weights ship inside the silero-vad package
(new 'silero' extra), so no Hugging Face account or token is required
and the backend is importable without pyannote installed. The silero
segment_audio_file takes an optional ChunkingConfig and no device
argument (Silero always runs on CPU); the chunk-merging logic is shared
with the default pyannote backend, which is unchanged.
The new tests run without HF_TOKEN (silero-vad added to the tests
extra), so longform now has CI coverage even where the secret is
unavailable, e.g. pull requests from forks. The end-to-end test
compares the merged transcription against the pyannote-based reference
by similarity instead of exact boundaries, since chunk borders
legitimately differ between VADs.
@gman-dev-nov
gman-dev-nov force-pushed the feat/silero-vad-backend branch from ef2f35b to 8808e81 Compare August 10, 2026 14:42
@gman-dev-nov

Copy link
Copy Markdown
Author

@Bobrosoft98 @georgygospodinov @sverdoot @nshmyrev watch please 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant