diff --git a/src/server/backends/whisper.js b/src/server/backends/whisper.js index 7c64384..68e1578 100644 --- a/src/server/backends/whisper.js +++ b/src/server/backends/whisper.js @@ -16,6 +16,39 @@ function getAudioThreshold() { return settingsManager.getSetting('audioThreshold') || parseFloat(process.env.AUDIO_THRESHOLD) || 0.01; } +// Preload tiny model for faster initial transcriptions +async function warmupWhisper() { + console.log('Warming up Whisper with tiny model...'); + const tempDir = os.tmpdir(); + const tempFile = path.join(tempDir, 'warmup_audio.wav'); + + try { + // Create a minimal audio file for warmup + const silentAudio = Buffer.alloc(8000); // 0.5 seconds of silence + await fs.writeFile(tempFile, silentAudio); + + const warmupProcess = spawn('python', [ + '-m', 'whisper', tempFile, + '--model', 'tiny', + '--language', 'en', + '--output_format', 'txt', + '--output_dir', tempDir + ]); + + warmupProcess.on('close', async () => { + await fs.unlink(tempFile).catch(() => {}); + await fs.unlink(tempFile.replace('.wav', '.txt')).catch(() => {}); + console.log('Whisper warmup completed'); + }); + + } catch (error) { + console.log('Whisper warmup failed (optional):', error.message); + } +} + +// Warmup on module load +setTimeout(warmupWhisper, 2000); // Delay to let server start first + async function transcribeLocal(audioBuffer) { // Check audio level before processing const audioLevel = getAudioLevel(audioBuffer); @@ -37,15 +70,23 @@ async function transcribeLocal(audioBuffer) { await fs.writeFile(tempFile, audioBuffer); return new Promise((resolve, reject) => { - // Build Whisper command with current settings (not cached) - const currentModel = settingsManager.getSetting('whisperModel') || process.env.WHISPER_MODEL || 'base'; + // Build Whisper command with current settings (optimized for speed) + const selectedModel = settingsManager.getSetting('whisperModel') || process.env.WHISPER_MODEL || 'base'; + + // Use tiny model for faster processing of short audio chunks + const currentModel = audioBuffer.length < 32000 ? 'tiny' : selectedModel; // ~2 seconds of audio + const whisperArgs = [ tempFile, '--model', currentModel, '--language', 'en', '--task', 'transcribe', '--output_format', 'txt', - '--output_dir', tempDir + '--output_dir', tempDir, + '--no_speech_threshold', '0.6', // Skip processing obvious non-speech + '--logprob_threshold', '-1.0', // Skip low-confidence segments + '--compression_ratio_threshold', '2.4', // Skip repetitive audio + '--condition_on_previous_text', 'False' // Don't wait for previous context ]; // Get current GPU settings (not cached)