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:
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
},
|
||||
|
||||
@@ -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."""
|
||||
|
||||
Reference in New Issue
Block a user