fix(installer): reuse existing whispercpp builds (#421)

This commit is contained in:
Jatin K Malik
2026-05-06 22:48:05 -07:00
committed by GitHub
parent 0556d169b3
commit ff9fd0a961
2 changed files with 106 additions and 5 deletions
+13
View File
@@ -103,6 +103,8 @@ Options:
--test Run tests after installation
--venv-dir=PATH Specify custom virtual environment directory
--skip-models Skip downloading speech models during installation
--rebuild-whispercpp Rebuild/reinstall pywhispercpp even if already installed
--no-rebuild-whispercpp Reuse existing pywhispercpp when present (auto-mode default)
--tag=TAG Install specific release tag
--help Show this help message
@@ -360,6 +362,17 @@ vulkaninfo --summary | grep -i "deviceName"
# [INFO] whisper.cpp using Vulkan GPU backend: AMD Radeon RX 6800
```
### Reusing Existing whisper.cpp Builds
When updating an existing install, the installer checks for a working `pywhispercpp`
installation before rebuilding it. Interactive installs ask whether to rebuild, with
the default set to no. Automatic installs reuse the existing build by default.
```bash
./install.sh --auto # Reuse pywhispercpp if already installed
./install.sh --auto --rebuild-whispercpp # Force a rebuild/reinstall
```
### Switching Engines
If you want to try a different engine after installation:
+93 -5
View File
@@ -106,6 +106,7 @@ NO_WHISPER_EXPLICIT="no"
NON_INTERACTIVE="no"
INTERACTIVE_MODE="yes" # Default to interactive mode
AUTO_MODE="no"
REBUILD_WHISPERCPP="ask"
HAS_NVIDIA_GPU="unknown"
GPU_NAME=""
GPU_MEMORY=""
@@ -117,8 +118,14 @@ VULKAN_DEVICE=""
# If no terminal is available at all (headless/CI), fall back to automatic mode.
if [ ! -t 0 ]; then
if [ -e /dev/tty ] && [ -r /dev/tty ]; then
exec < /dev/tty
INTERACTIVE_MODE="ask"
if { true < /dev/tty; } 2>/dev/null; then
exec < /dev/tty
INTERACTIVE_MODE="ask"
else
AUTO_MODE="yes"
INTERACTIVE_MODE="no"
NON_INTERACTIVE="yes"
fi
else
AUTO_MODE="yes"
INTERACTIVE_MODE="no"
@@ -144,6 +151,14 @@ while [[ $# -gt 0 ]]; do
SKIP_MODELS="yes"
shift
;;
--rebuild-whispercpp)
REBUILD_WHISPERCPP="yes"
shift
;;
--no-rebuild-whispercpp)
REBUILD_WHISPERCPP="no"
shift
;;
--engine=*)
SELECTED_ENGINE="${1#*=}"
shift
@@ -180,6 +195,8 @@ while [[ $# -gt 0 ]]; do
echo " --test Run tests after installation"
echo " --venv-dir=PATH Specify custom virtual environment directory"
echo " --skip-models Skip downloading speech models during installation"
echo " --rebuild-whispercpp Rebuild/reinstall pywhispercpp even if already installed"
echo " --no-rebuild-whispercpp Reuse existing pywhispercpp when present (auto-mode default)"
echo " --tag=TAG Install specific release tag (default: latest release)"
echo " --help Show this help message"
echo ""
@@ -1881,6 +1898,56 @@ EOF
chmod +x "$ACTIVATION_SCRIPT"
print_info "Created activation script: $ACTIVATION_SCRIPT"
is_pywhispercpp_installed() {
[ -x "$VENV_DIR/bin/python" ] || return 1
"$VENV_DIR/bin/python" -c "from pywhispercpp.model import Model" >/dev/null 2>&1
}
get_pywhispercpp_version() {
[ -x "$VENV_DIR/bin/python" ] || return 1
"$VENV_DIR/bin/python" - <<'PY' 2>/dev/null
from importlib import metadata
try:
print(metadata.version("pywhispercpp"))
except metadata.PackageNotFoundError:
raise SystemExit(1)
PY
}
should_rebuild_whispercpp() {
local INSTALLED_VERSION
INSTALLED_VERSION=$(get_pywhispercpp_version || true)
print_success "Found existing pywhispercpp installation${INSTALLED_VERSION:+ (version $INSTALLED_VERSION)}"
case "$REBUILD_WHISPERCPP" in
yes)
print_info "Rebuilding pywhispercpp because --rebuild-whispercpp was specified."
return 0
;;
no)
print_info "Reusing existing pywhispercpp installation."
return 1
;;
esac
if [[ "$NON_INTERACTIVE" == "yes" ]]; then
print_info "Non-interactive mode: reusing existing pywhispercpp installation."
print_info "Use --rebuild-whispercpp to force a rebuild."
return 1
fi
read -p "Rebuild/reinstall pywhispercpp? This can take several minutes. (y/N) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
return 0
fi
print_info "Reusing existing pywhispercpp installation."
return 1
}
# Function to install Python package with error handling and verification
install_python_package() {
# Create a temporary directory for pip logs
@@ -1893,6 +1960,11 @@ install_python_package() {
GI_TYPELIB_DETECTED=$(detect_typelib_path)
print_info "Detected GI_TYPELIB_PATH: $GI_TYPELIB_DETECTED"
local WHISPERCPP_ALREADY_INSTALLED=false
if is_pywhispercpp_installed; then
WHISPERCPP_ALREADY_INSTALLED=true
fi
# Function to verify package installation
verify_package_installed() {
local PKG_NAME="vocalinux"
@@ -1957,9 +2029,21 @@ install_python_package() {
local GPU_BACKEND="CPU"
local GPU_INSTALL_SUCCESS=false
local SKIP_WHISPERCPP_INSTALL=false
if [[ "$WHISPERCPP_ALREADY_INSTALLED" == "true" ]]; then
GPU_BACKEND="existing"
if should_rebuild_whispercpp; then
print_info "Existing pywhispercpp will be replaced."
else
SKIP_WHISPERCPP_INSTALL=true
fi
fi
# Check if user explicitly chose CPU backend in interactive mode
if [[ "${WHISPERCPP_BACKEND}" == "cpu" ]]; then
if [[ "$SKIP_WHISPERCPP_INSTALL" == "true" ]]; then
print_info "Skipping pywhispercpp reinstall; existing compiled bindings remain in place."
elif [[ "${WHISPERCPP_BACKEND}" == "cpu" ]]; then
print_info "ℹ Installing CPU-only version (as requested)..."
GPU_BACKEND="CPU"
else
@@ -1989,7 +2073,7 @@ install_python_package() {
fi
# Fall back to CPU version if GPU install failed or no GPU detected
if [[ "$GPU_INSTALL_SUCCESS" != "true" ]]; then
if [[ "$SKIP_WHISPERCPP_INSTALL" != "true" && "$GPU_INSTALL_SUCCESS" != "true" ]]; then
if [[ "$GPU_BACKEND" != "CPU" ]]; then
print_warning "Failed to install pywhispercpp with $GPU_BACKEND support, falling back to CPU version..."
@@ -2015,7 +2099,11 @@ install_python_package() {
}
fi
print_success "pywhispercpp installed with $GPU_BACKEND backend"
if [[ "$SKIP_WHISPERCPP_INSTALL" == "true" ]]; then
print_success "pywhispercpp reused from existing installation"
else
print_success "pywhispercpp installed with $GPU_BACKEND backend"
fi
echo ""
;;