How to Switch Between Whisper and Parakeet Transcription Models in Meetily

Users switch between Whisper.cpp and Parakeet transcription models in Meetily by invoking the set_transcription_provider Tauri command, which persists the provider choice in the settings database and initializes the appropriate engine at runtime without requiring an application restart.

Meetily ships with dual speech-to-text backends that cater to different hardware configurations. Knowing how to switch between Whisper and Parakeet transcription models in Meetily allows you to optimize for either CPU-based accuracy or GPU-accelerated real-time performance. Both engines implement a unified API interface (load_model, transcribe_audio, unload_model) and are selected dynamically through the application's settings repository.

Architecture Overview

Meetily supports two distinct transcription engines:

Whisper.cpp (frontend/src-tauri/src/whisper_engine/whisper_engine.rs)

  • CPU-only or GPU-accelerated OpenAI Whisper models
  • Higher accuracy but slower inference
  • Suitable for general-purpose transcription

Parakeet (frontend/src-tauri/src/parakeet_engine/parakeet_engine.rs)

  • NVIDIA NeMo-based implementation
  • GPU-only real-time processing
  • Optimized for modern NVIDIA hardware with significantly faster inference

Both engines expose identical public methods, allowing the audio pipeline to treat them as interchangeable backends.

Configuration Storage and Persistence

The active transcription provider is stored in Meetily's settings database. During onboarding, the selection is persisted in the settings table as shown in frontend/src-tauri/src/onboarding.rs:

// onboarding.rs – line 200
info!("Saved transcription model config: provider=parakeet, model={}", DEFAULT_PARAKEET_MODEL);

The settings repository maintains this value across sessions, enabling the audio pipeline to route transcription requests to the correct engine on subsequent launches.

Runtime Switching via Tauri Commands

Meetily exposes two primary Tauri commands for managing transcription providers:

set_transcription_provider – Switches the active engine and persists the choice load_transcription_model – Loads specific model weights into the initialized engine

These commands are implemented in frontend/src-tauri/src/parakeet_engine/commands.rs and frontend/src-tauri/src/whisper_engine/commands.rs. The switch logic validates the provider string and initializes the corresponding engine:

// src-tauri/src/parakeet_engine/commands.rs
#[tauri::command]
pub async fn set_transcription_provider(app: AppHandle, provider: String) -> Result<(), String> {
    // Persist the provider value
    let mut settings = SettingsRepository::new(app.clone()).await?;
    settings.set_transcription_provider(&provider).await?;
    // Re-initialise the appropriate engine
    match provider.as_str() {
        "parakeet" => ParakeetEngine::initialize(app).await?,
        "whisper"  => WhisperEngine::initialize(app).await?,
        _ => return Err(format!("Unsupported provider: {}", provider)),
    }
    Ok(())
}

Audio Pipeline Routing

The audio pipeline (frontend/src-tauri/src/audio/pipeline.rs) does not directly instantiate engines. Instead, it queries the settings repository for the active provider and routes audio chunks to the corresponding global engine handle:

let provider = settings.get_transcription_provider().await?;
match provider.as_str() {
    "parakeet" => {
        let engine = PARAKEET_ENGINE.read().await;
        engine.transcribe_audio(samples, language).await
    }
    "whisper" => {
        let engine = WHISPER_ENGINE.read().await;
        engine.transcribe_audio(samples, language).await
    }
    _ => Err(anyhow!("Unknown transcription provider")),
}

Global engine handles are stored as Arc<RwLock<Option<...>>> in frontend/src-tauri/src/parakeet_engine/mod.rs and frontend/src-tauri/src/whisper_engine/mod.rs, enabling safe concurrent access from async tasks.

Model Loading and Initialization

After switching providers, you must load the specific model weights. The following TypeScript examples demonstrate the complete workflow:

Switching to Parakeet (GPU-only):

await invoke('set_transcription_provider', { provider: 'parakeet' });
await invoke('load_transcription_model', { model_name: 'large_v2' });

Switching to Whisper (CPU/GPU):

await invoke('set_transcription_provider', { provider: 'whisper' });
await invoke('load_transcription_model', { model_name: 'base' });

Internally, the Rust implementation acquires a write lock on the global engine handle and initializes the new instance:

#[tauri::command]
pub async fn load_transcription_model(app: AppHandle, model_name: String) -> Result<(), String> {
    let mut guard = WHISPER_ENGINE.write().await;
    let engine = WhisperEngine::new().map_err(|e| e.to_string())?;
    engine.load_model(&model_name).await.map_err(|e| e.to_string())?;
    *guard = Some(engine);
    Ok(())
}

UI Feedback and Availability Checks

The system tray UI (frontend/src-tauri/src/tray.rs) monitors model availability for the selected provider. When switching providers, the tray validates whether required model files exist locally:

// tray.rs – line 283
match crate::parakeet_engine::commands::parakeet_has_available_models().await {
    true => menu_item.enable(),
    false => menu_item.disable(),
}

If the chosen provider lacks downloaded models, the recording button is temporarily disabled and the interface displays "⏳ Downloading transcription model…" until the files are available.

Summary

  • Meetily supports Whisper.cpp (CPU/GPU, higher accuracy) and Parakeet (NVIDIA GPU-only, faster real-time) transcription engines
  • The active provider is stored in the settings database via frontend/src-tauri/src/onboarding.rs and updated through set_transcription_provider
  • The audio pipeline routes transcription requests dynamically based on the stored provider value in frontend/src-tauri/src/audio/pipeline.rs
  • Global engine handles in mod.rs files use Arc<RwLock> patterns for thread-safe access
  • The system tray provides real-time feedback on model availability via parakeet_has_available_models()

Frequently Asked Questions

Can I switch transcription models without restarting Meetily?

Yes. Meetily supports hot-switching between Whisper and Parakeet without an application restart. The set_transcription_provider command re-initializes the appropriate engine global state while the application continues running. However, you must invoke load_transcription_model after switching to download and load the specific weights for the new provider.

What hardware requirements does each transcription model have?

Whisper.cpp runs on both CPU and GPU (CUDA/OpenCL) and is suitable for systems without NVIDIA hardware. Parakeet requires modern NVIDIA GPUs and uses the NVIDIA NeMo framework exclusively. If your system lacks compatible NVIDIA hardware, the Parakeet option will be unavailable or non-functional.

How does Meetily handle missing model files when switching providers?

The system tray logic in frontend/src-tauri/src/tray.rs checks for available models before enabling transcription. If you switch to a provider whose models are not downloaded, the recording button is disabled and the UI displays a downloading status indicator. The application waits for the model files to be present before allowing transcription to begin.

Where is the active transcription provider stored?

The provider selection is persisted in Meetily's internal settings database. During onboarding, the value is written in frontend/src-tauri/src/onboarding.rs, and at runtime, the SettingsRepository class provides get_transcription_provider() and set_transcription_provider() methods for reading and updating this configuration.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →