# How to Switch Between Whisper and Parakeet Transcription Models in Meetily

> Easily switch between Whisper.cpp and Parakeet transcription models in Meetily using the set_transcription_provider command. Learn how to manage your Meetily transcription settings instantly.

- Repository: [Zackriya Solutions/meetily](https://github.com/Zackriya-Solutions/meetily)
- Tags: how-to-guide
- Published: 2026-07-13

---

**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`](https://github.com/Zackriya-Solutions/meetily/blob/main/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`](https://github.com/Zackriya-Solutions/meetily/blob/main/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`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/onboarding.rs):

```rust
// 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`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/parakeet_engine/commands.rs) and [`frontend/src-tauri/src/whisper_engine/commands.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/whisper_engine/commands.rs). The switch logic validates the provider string and initializes the corresponding engine:

```rust
// 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`](https://github.com/Zackriya-Solutions/meetily/blob/main/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:

```rust
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`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/parakeet_engine/mod.rs) and [`frontend/src-tauri/src/whisper_engine/mod.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/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):

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

```

Switching to Whisper (CPU/GPU):

```typescript
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:

```rust
#[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`](https://github.com/Zackriya-Solutions/meetily/blob/main/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:

```rust
// 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`](https://github.com/Zackriya-Solutions/meetily/blob/main/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`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/pipeline.rs)
- Global engine handles in [`mod.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/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`](https://github.com/Zackriya-Solutions/meetily/blob/main/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`](https://github.com/Zackriya-Solutions/meetily/blob/main/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.