From 701f5dd56e0ca01e2cd645771cd1bab54005fce3 Mon Sep 17 00:00:00 2001 From: Damien Date: Wed, 17 Jun 2026 11:25:04 +0200 Subject: [PATCH] Update Voxtral STT model to non-realtime batch variant Use Voxtral-Mini-3B-2507-bf16 across all tiers and set appropriate max_tokens for full-file transcription --- src/audio_summary/models/config.py | 9 +++++---- src/audio_summary/pipeline/transcription.py | 18 +++++++++++++----- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/audio_summary/models/config.py b/src/audio_summary/models/config.py index 5ae2709..4de4208 100644 --- a/src/audio_summary/models/config.py +++ b/src/audio_summary/models/config.py @@ -9,7 +9,8 @@ threshold is *less than or equal to* the detected memory is selected (see ``audio_summary.device.select_models``). STT engines: - * ``"voxtral"`` -> Mistral Voxtral via ``mlx-audio`` (streaming, long audio). + * ``"voxtral"`` -> Mistral Voxtral (non-realtime batch model) via ``mlx-audio``. + Honors the requested language and transcribes whole files in one pass. * ``"whisper"`` -> ``mlx-whisper`` (lightweight fallback for low-RAM Macs). """ @@ -42,17 +43,17 @@ TIERS: list[Tier] = [ ), Tier( min_ram_gb=16, - stt=STTModel("voxtral", "mlx-community/Voxtral-Mini-4B-Realtime-2602-4bit"), + stt=STTModel("voxtral", "mlx-community/Voxtral-Mini-3B-2507-bf16"), summarization_repo="mlx-community/Qwen3-8B-4bit", ), Tier( min_ram_gb=24, - stt=STTModel("voxtral", "mlx-community/Voxtral-Mini-4B-Realtime-2602-fp16"), + stt=STTModel("voxtral", "mlx-community/Voxtral-Mini-3B-2507-bf16"), summarization_repo="mlx-community/Qwen3-8B-8bit", ), Tier( min_ram_gb=32, - stt=STTModel("voxtral", "mlx-community/Voxtral-Mini-4B-Realtime-2602-fp16"), + stt=STTModel("voxtral", "mlx-community/Voxtral-Mini-3B-2507-bf16"), summarization_repo="mlx-community/Qwen3-30B-A3B-4bit", ), ] diff --git a/src/audio_summary/pipeline/transcription.py b/src/audio_summary/pipeline/transcription.py index 7cb2606..aefe4c4 100644 --- a/src/audio_summary/pipeline/transcription.py +++ b/src/audio_summary/pipeline/transcription.py @@ -2,22 +2,30 @@ Two engines are supported, selected through ``config.STTModel.engine``: -* ``voxtral`` -> Mistral Voxtral via ``mlx-audio``. Outperforms Whisper - large-v3 on most benchmarks and natively handles long audio with streaming. +* ``voxtral`` -> Mistral Voxtral (non-realtime batch model) via ``mlx-audio``. + Outperforms Whisper large-v3 on most benchmarks. The *realtime* Voxtral + variant is deliberately not used here: it ignores the requested language and + truncates when run one-shot on a full file. * ``whisper`` -> ``mlx-whisper`` fallback for memory-constrained Macs. """ from ..models import STTModel +# Upper bound on generated tokens for a full-file transcription. The non-realtime +# Voxtral ``generate`` defaults to only 128 tokens, which would truncate any real +# recording, so we raise it well above the length of a long-form transcript. +_VOXTRAL_MAX_TOKENS = 32768 + def _transcribe_voxtral(file_path: str, model_repo: str, language: str | None) -> str: """Transcribe using Mistral Voxtral through mlx-audio.""" from mlx_audio.stt.utils import load model = load(model_repo) - # Voxtral handles long audio natively; ``generate`` returns an object with a - # ``.text`` attribute. ``language`` is optional (auto-detected when None). - kwargs: dict = {} + # The non-realtime Voxtral model transcribes the whole file in one pass and + # honors ``language``. ``generate`` returns an object with a ``.text`` + # attribute. ``language`` is optional (auto-detected when None). + kwargs: dict = {"max_tokens": _VOXTRAL_MAX_TOKENS} if language: kwargs["language"] = language result = model.generate(file_path, **kwargs)