feat: implement streaming mode (-s) and 4-bit quantization (-q) for performance

This commit is contained in:
Adolfo Reyna
2026-02-28 19:00:56 -05:00
parent 3c874c113c
commit 6f60d49c7b
2 changed files with 24 additions and 0 deletions
+2
View File
@@ -55,6 +55,8 @@ Run the script using `python3 transcribe.py` with optional flags.
- `-i`, `--ingest`: Enable data transmission to the remote server. - `-i`, `--ingest`: Enable data transmission to the remote server.
- `-l`, `--list-devices`: Show available audio devices and exit. - `-l`, `--list-devices`: Show available audio devices and exit.
- `-d`, `--device [ID]`: Input device index (bypasses selection prompt). - `-d`, `--device [ID]`: Input device index (bypasses selection prompt).
- `-q`, `--quantize`: Use 4-bit quantized Whisper model for faster transcription (Strategy 3).
- `-s`, `--stream`: Enable real-time streaming transcription/draft mode (Strategy 1).
--- ---
+22
View File
@@ -83,6 +83,7 @@ def ingest_worker():
ingest_queue.task_done() ingest_queue.task_done()
def main(): def main():
global WHISPER_MODEL
parser = argparse.ArgumentParser(description="Live transcription and translation with Whisper.") parser = argparse.ArgumentParser(description="Live transcription and translation with Whisper.")
parser.add_argument("-es", action="store_true", help="Enable Spanish translation") parser.add_argument("-es", action="store_true", help="Enable Spanish translation")
parser.add_argument("-en", action="store_true", help="Enable English (detected or bridged)") parser.add_argument("-en", action="store_true", help="Enable English (detected or bridged)")
@@ -91,9 +92,14 @@ def main():
parser.add_argument("-i", "--ingest", action="store_true", help="Enable data transmission to server") parser.add_argument("-i", "--ingest", action="store_true", help="Enable data transmission to server")
parser.add_argument("-l", "--list-devices", action="store_true", help="Show available audio devices and exit") parser.add_argument("-l", "--list-devices", action="store_true", help="Show available audio devices and exit")
parser.add_argument("-d", "--device", type=int, help="Input device index") parser.add_argument("-d", "--device", type=int, help="Input device index")
parser.add_argument("-q", "--quantize", action="store_true", help="Use 4-bit quantized Whisper model for speed")
parser.add_argument("-s", "--stream", action="store_true", help="Enable real-time streaming transcription (Draft mode)")
args = parser.parse_args() args = parser.parse_args()
if args.quantize:
WHISPER_MODEL = "mlx-community/whisper-small-mlx-4bit"
if args.list_devices: if args.list_devices:
print("\nAvailable Audio Devices:") print("\nAvailable Audio Devices:")
print(sd.query_devices()) print(sd.query_devices())
@@ -140,6 +146,7 @@ def main():
audio_buffer = [] audio_buffer = []
speech_started = False speech_started = False
last_stream_time = time.time()
try: try:
with sd.InputStream(samplerate=SAMPLERATE, channels=CHANNELS, callback=callback, blocksize=BLOCK_SIZE, device=device_index): with sd.InputStream(samplerate=SAMPLERATE, channels=CHANNELS, callback=callback, blocksize=BLOCK_SIZE, device=device_index):
@@ -167,6 +174,11 @@ def main():
if (buffer_len_samples - last_end) > (SAMPLERATE * MIN_SILENCE_DURATION_MS / 1000) or buffer_len_samples > BUFFER_LIMIT: if (buffer_len_samples - last_end) > (SAMPLERATE * MIN_SILENCE_DURATION_MS / 1000) or buffer_len_samples > BUFFER_LIMIT:
# Clear draft line if it was used
if args.stream:
sys.stdout.write("\r\033[K")
sys.stdout.flush()
# 1. Transcribe & Detect Language # 1. Transcribe & Detect Language
transcription_result = mlx_whisper.transcribe(current_audio, path_or_hf_repo=WHISPER_MODEL) transcription_result = mlx_whisper.transcribe(current_audio, path_or_hf_repo=WHISPER_MODEL)
original_text = transcription_result['text'].strip() original_text = transcription_result['text'].strip()
@@ -220,6 +232,16 @@ def main():
audio_buffer = [] audio_buffer = []
speech_started = False speech_started = False
last_stream_time = time.time()
elif args.stream and (time.time() - last_stream_time) > 1.0:
# Draft transcription
draft_result = mlx_whisper.transcribe(current_audio, path_or_hf_repo=WHISPER_MODEL)
draft_text = draft_result['text'].strip()
if draft_text:
sys.stdout.write(f"\r\033[K[DRAFT]: {draft_text}")
sys.stdout.flush()
last_stream_time = time.time()
elif not speech_started and len(current_audio) > SAMPLERATE * 2: elif not speech_started and len(current_audio) > SAMPLERATE * 2:
audio_buffer = [] audio_buffer = []