feat: Make Whisper tiny the default engine and download during install (#45)

* feat: Make Whisper tiny the default engine and download during install

- Changed default engine from 'vosk' to 'whisper' in config_manager.py
- Changed default model_size from 'small' to 'tiny' in config_manager.py
- Added install_whisper_model() function to install.sh that downloads
  the Whisper tiny model (~75MB) during installation
- Whisper model is downloaded when Whisper package is installed
  (in non-interactive mode or with --with-whisper flag)
- Updated installation summary to show Whisper model status
- Updated documentation (README.md, INSTALL.md, SECURITY.md, USER_GUIDE.md)
  to reflect Whisper tiny as the default engine

This provides a better out-of-box experience: users can install and
immediately use Vocalinux without any additional downloads or prompts.

* test: Update test to reflect whisper as default engine
This commit is contained in:
Jatin K Malik
2025-12-28 20:31:29 -08:00
committed by GitHub
parent b9455390ec
commit f8e5de5621
7 changed files with 115 additions and 16 deletions
+1 -1
View File
@@ -42,7 +42,7 @@ This will:
- Set up a virtual environment in `~/.local/share/vocalinux/venv`
- Install **both VOSK and Whisper AI** speech engines
- Create a symlink at `~/.local/bin/vocalinux`
- Download the default VOSK speech model
- Download the default **Whisper tiny** speech model (~75MB)
> ⏱️ **Note**: Installation takes ~5-10 minutes due to Whisper AI dependencies (PyTorch).
+3 -3
View File
@@ -42,14 +42,14 @@ We take security seriously. If you discover a security vulnerability within Voca
Vocalinux is designed with privacy in mind:
- **Offline by default**: The VOSK engine works completely offline
- **Offline by default**: Both Whisper (default) and VOSK engines work completely offline
- **Local processing**: All speech recognition happens on your device
- **No data collection**: We don't collect or transmit your voice data
- **No telemetry**: We don't track usage or behavior
### Whisper AI
### Whisper AI (Default Engine)
When using Whisper, be aware:
Whisper is the default speech recognition engine:
- Whisper processes locally on your machine
- Models are downloaded once and cached locally
- No audio data is sent to external servers
+4 -3
View File
@@ -83,7 +83,7 @@ Options:
1. **Detects your Linux distribution** and installs appropriate system packages
2. **Creates a Python virtual environment** with system site-packages access
3. **Installs the Vocalinux package** and all dependencies
4. **Downloads speech recognition models** (VOSK small model by default)
4. **Downloads speech recognition models** (Whisper tiny model by default, VOSK as fallback)
5. **Installs desktop integration** (icons, .desktop file)
6. **Creates activation script** for easy environment activation
@@ -108,8 +108,9 @@ vocalinux
```bash
vocalinux --help # Show all options
vocalinux --debug # Enable debug logging
vocalinux --engine whisper # Use Whisper AI engine
vocalinux --engine vosk # Use VOSK engine (default)
vocalinux --engine whisper # Use Whisper AI engine (default)
vocalinux --engine vosk # Use VOSK engine
vocalinux --model tiny # Use tiny model (default, fastest)
vocalinux --model small # Use small model
vocalinux --model medium # Use medium model
vocalinux --model large # Use large model
+2 -2
View File
@@ -63,8 +63,8 @@ You can change the speech recognition model for better accuracy or faster perfor
1. Open settings from the tray icon menu
2. Go to the "Recognition" tab
3. Select your preferred model size
4. Choose between VOSK (offline, faster) and Whisper (offline, more accurate)
3. Select your preferred model size (tiny is the default, use larger models for better accuracy)
4. Choose between Whisper (default, more accurate) and VOSK (lighter weight, faster)
## Troubleshooting
+100 -2
View File
@@ -699,6 +699,83 @@ if ! install_python_package; then
exit 1
fi
# Function to download and install Whisper tiny model
install_whisper_model() {
print_info "Installing Whisper tiny model (~75MB)..."
# Create whisper models directory
local WHISPER_DIR="$DATA_DIR/models/whisper"
mkdir -p "$WHISPER_DIR"
# Whisper tiny model URL and path
local TINY_MODEL_URL="https://openaipublic.azureedge.net/main/whisper/models/65147644a518d12f04e32d6f3b26facc3f8dd46e5390956a9424a650c0ce22b9/tiny.pt"
local TINY_MODEL_PATH="$WHISPER_DIR/tiny.pt"
# Check if model already exists
if [ -f "$TINY_MODEL_PATH" ]; then
print_info "Whisper tiny model already exists at $TINY_MODEL_PATH"
return 0
fi
# Check internet connectivity
if ! command -v wget >/dev/null 2>&1 && ! command -v curl >/dev/null 2>&1; then
print_warning "Neither wget nor curl found. Cannot download Whisper model."
print_warning "Model will be downloaded on first application run."
return 1
fi
# Test internet connectivity
if ! ping -c 1 google.com >/dev/null 2>&1; then
print_warning "No internet connection detected."
print_warning "Whisper model will be downloaded on first application run."
return 1
fi
print_info "Downloading Whisper tiny model..."
print_info "This may take a few minutes depending on your internet connection."
local TEMP_FILE="$TINY_MODEL_PATH.tmp"
# Download the model
if command -v wget >/dev/null 2>&1; then
if ! wget --progress=bar:force:noscroll -O "$TEMP_FILE" "$TINY_MODEL_URL" 2>&1; then
print_error "Failed to download Whisper model with wget"
rm -f "$TEMP_FILE"
return 1
fi
elif command -v curl >/dev/null 2>&1; then
if ! curl -L --progress-bar -o "$TEMP_FILE" "$TINY_MODEL_URL"; then
print_error "Failed to download Whisper model with curl"
rm -f "$TEMP_FILE"
return 1
fi
fi
# Verify download
if [ ! -f "$TEMP_FILE" ] || [ ! -s "$TEMP_FILE" ]; then
print_error "Downloaded model file is empty or missing"
rm -f "$TEMP_FILE"
return 1
fi
# Move to final location
mv "$TEMP_FILE" "$TINY_MODEL_PATH"
# Verify the model file
if [ -f "$TINY_MODEL_PATH" ]; then
local MODEL_SIZE=$(du -h "$TINY_MODEL_PATH" | cut -f1)
print_success "Whisper tiny model installed successfully ($MODEL_SIZE)"
# Create a marker file to indicate this model was pre-installed
echo "$(date)" > "$WHISPER_DIR/.vocalinux_preinstalled"
return 0
else
print_error "Whisper model installation failed"
return 1
fi
}
# Function to download and install VOSK models
install_vosk_models() {
print_info "Installing VOSK speech recognition models..."
@@ -906,7 +983,21 @@ install_desktop_entry || print_warning "Desktop entry installation failed"
# Install icons
install_icons || print_warning "Icon installation failed"
# Install VOSK models
# Install Whisper tiny model (if Whisper was installed)
if [ "$WITH_WHISPER" = "yes" ] || [ "$NON_INTERACTIVE" = "yes" ]; then
# Check if Whisper is actually installed before downloading model
if python -c "import whisper" 2>/dev/null; then
if [ "$SKIP_MODELS" = "no" ]; then
install_whisper_model || print_warning "Whisper model download failed - model will be downloaded on first run"
else
print_info "Skipping Whisper model download (--skip-models specified)"
fi
else
print_info "Whisper not available, skipping model download"
fi
fi
# Install VOSK models (as fallback)
if [ "$SKIP_MODELS" = "no" ]; then
install_vosk_models || print_warning "VOSK model installation failed - models will be downloaded on first run"
else
@@ -1036,9 +1127,16 @@ print_installation_summary() {
print_info "- Configuration: $CONFIG_DIR"
print_info "- Data directory: $DATA_DIR"
# Check if Whisper model was installed
if [ -f "$DATA_DIR/models/whisper/tiny.pt" ]; then
print_info "- Whisper tiny model: $DATA_DIR/models/whisper/tiny.pt (default engine)"
elif python -c "import whisper" 2>/dev/null; then
print_info "- Whisper tiny model: Will be downloaded on first run"
fi
# Check if VOSK model was installed
if [ "$SKIP_MODELS" = "no" ] && [ -d "$DATA_DIR/models/vosk-model-small-en-us-0.15" ]; then
print_info "- VOSK small model: $DATA_DIR/models/vosk-model-small-en-us-0.15"
print_info "- VOSK small model: $DATA_DIR/models/vosk-model-small-en-us-0.15 (fallback)"
elif [ "$SKIP_MODELS" = "yes" ]; then
print_info "- VOSK models: Will be downloaded on first run (--skip-models used)"
else
+2 -2
View File
@@ -19,8 +19,8 @@ CONFIG_FILE = os.path.join(CONFIG_DIR, "config.json")
# Default configuration
DEFAULT_CONFIG = {
"speech_recognition": { # Changed section name
"engine": "vosk", # "vosk" or "whisper"
"model_size": "small", # "small", "medium", or "large"
"engine": "whisper", # "vosk" or "whisper"
"model_size": "tiny", # "tiny", "small", "medium", or "large"
"vad_sensitivity": 3, # Voice Activity Detection sensitivity (1-5) - Moved here
"silence_timeout": 2.0, # Seconds of silence before stopping recognition - Moved here
},
+3 -3
View File
@@ -142,7 +142,7 @@ class TestConfigManager(unittest.TestCase):
"""Test getting an existing configuration value."""
config_manager = ConfigManager()
value = config_manager.get("speech_recognition", "engine")
self.assertEqual(value, "vosk")
self.assertEqual(value, "whisper") # Default is now whisper
def test_get_nonexistent_value(self):
"""Test getting a nonexistent configuration value."""
@@ -153,9 +153,9 @@ class TestConfigManager(unittest.TestCase):
def test_set_existing_section(self):
"""Test setting a value in an existing section."""
config_manager = ConfigManager()
result = config_manager.set("speech_recognition", "engine", "whisper")
result = config_manager.set("speech_recognition", "engine", "vosk")
self.assertTrue(result)
self.assertEqual(config_manager.config["speech_recognition"]["engine"], "whisper")
self.assertEqual(config_manager.config["speech_recognition"]["engine"], "vosk")
def test_set_new_section(self):
"""Test setting a value in a new section."""