Ctrl K
ComunidadGuías…

install.sh

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env bash
# Hearthwave native install — run once on a fresh Debian/Ubuntu machine.
# Creates a Python venv at .venv/, installs all deps, and validates the setup.
#
# Usage:
#   bash install.sh                            # full install (small.en + large-v3-turbo)
#   bash install.sh --no-models                # skip model download (copy Models/ manually)
#   bash install.sh --final-model distil-large-v3   # stage a different two-tier
#                                              # final-pass model
#   bash install.sh --final-model none         # skip the final-pass model (single-pass RX)
#   bash install.sh --dev                      # also install test deps (pytest, httpx)

set -euo pipefail

MODELS=true
DEV=false
# Two-tier final-pass model staged by default. whisper_model_final="auto" (the
# fresh-install default) resolves to the best staged model, and its preference
# order puts large-v3-turbo first — so staging turbo here is what makes "auto"
# resolve to anything at all on a new install.
FINAL_MODEL="large-v3-turbo"
while [[ $# -gt 0 ]]; do
  case "$1" in
    --no-models) MODELS=false; shift ;;
    --dev) DEV=true; shift ;;
    --final-model)
      [[ $# -lt 2 ]] && { echo "Error: --final-model requires a value." >&2; exit 1; }
      FINAL_MODEL="$2"; shift 2 ;;
    *) echo "Unknown argument: $1" >&2; exit 1 ;;
  esac
done

# "none"/"off" (and "") mean: single-pass RX, stage no final model.
[[ "$FINAL_MODEL" == "none" || "$FINAL_MODEL" == "off" ]] && FINAL_MODEL=""

# ── 1. System packages ───────────────────────────────────────────────────────

echo "==> Installing system packages..."
sudo apt-get update -qq
sudo apt-get install -y --no-install-recommends \
    python3 \
    python3-venv \
    python3-pip \
    build-essential \
    gcc \
    libportaudio2 \
    libsndfile1 \
    espeak-ng \
    espeak-ng-data \
    pulseaudio-utils \
    curl \
    ca-certificates

# Node.js 20 (LTS) via NodeSource — skip if already at v18+.
NODE_MAJOR=$(node --version 2>/dev/null | grep -oP '(?<=v)\d+' || echo 0)
if [ "$NODE_MAJOR" -lt 18 ]; then
    echo "==> Installing Node.js 20 (LTS)..."
    curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
    sudo apt-get install -y nodejs
else
    echo "==> Node.js $(node --version) already installed, skipping."
fi

# ── 2. Frontend dependencies ─────────────────────────────────────────────────

echo "==> Installing frontend npm packages (MUI, React, Vite, …)..."
(cd frontend && npm ci)

# ── 3. Docker image cache (optional but speeds up first `docker compose up`) ──

if command -v docker &>/dev/null; then
    echo "==> Pulling Docker base images..."
    docker compose pull --quiet 2>/dev/null || true
    docker compose -f docker-compose.yml -f docker-compose.dev.yml pull --quiet 2>/dev/null || true
fi

# ── 4. Python virtual environment ───────────────────────────────────────────

echo "==> Creating Python venv at .venv/ ..."
python3 -m venv .venv
source .venv/bin/activate

echo "==> Installing Python packages (this will take a few minutes)..."
pip install --upgrade pip --quiet
if $DEV; then
    pip install -r backend/requirements.txt -r backend/requirements-dev.txt
    echo "    Test deps installed — run the suite with: cd backend && python -m pytest"
else
    pip install -r backend/requirements.txt
fi

# ── 5. Models ────────────────────────────────────────────────────────────────

if $MODELS; then
    if [[ -n "$FINAL_MODEL" ]]; then
        echo "==> Downloading Whisper STT models (small.en ~464 MB + ${FINAL_MODEL} ~1.6 GB)..."
        python bootstrap_models.py --model small.en "$FINAL_MODEL"
        echo "    whisper_model_final=\"auto\" (new-install default) picks this up automatically."
        echo "    If data/config.json has whisper_model_final=\"\" (explicit off), set it to \"auto\""
        echo "    or \"${FINAL_MODEL}\" to enable the two-tier pass."
    else
        echo "==> Downloading Whisper STT model (small.en, ~464 MB)..."
        python bootstrap_models.py --model small.en
    fi

    echo "==> Downloading Piper TTS voices..."
    mkdir -p Voices
    python - <<'PYEOF'
import os, shutil
from huggingface_hub import hf_hub_download

REPO = "rhasspy/piper-voices"
VOICES = [
    "en/en_US/ryan/high/en_US-ryan-high.onnx",
    "en/en_US/ryan/high/en_US-ryan-high.onnx.json",
    "en/en_US/amy/medium/en_US-amy-medium.onnx",
    "en/en_US/amy/medium/en_US-amy-medium.onnx.json",
    "en/en_US/arctic/medium/en_US-arctic-medium.onnx",
    "en/en_US/arctic/medium/en_US-arctic-medium.onnx.json",
    "en/en_US/hfc_female/medium/en_US-hfc_female-medium.onnx",
    "en/en_US/hfc_female/medium/en_US-hfc_female-medium.onnx.json",
    "en/en_US/kathleen/low/en_US-kathleen-low.onnx",
    "en/en_US/kathleen/low/en_US-kathleen-low.onnx.json",
    "en/en_US/kristin/medium/en_US-kristin-medium.onnx",
    "en/en_US/kristin/medium/en_US-kristin-medium.onnx.json",
    "en/en_US/lessac/high/en_US-lessac-high.onnx",
    "en/en_US/lessac/high/en_US-lessac-high.onnx.json",
    "en/en_US/libritts/high/en_US-libritts-high.onnx",
    "en/en_US/libritts/high/en_US-libritts-high.onnx.json",
]
for path in VOICES:
    name = os.path.basename(path)
    out = os.path.join("Voices", name)
    if os.path.exists(out):
        print(f"  {name} already present, skipping.")
        continue
    print(f"  Downloading {name}...")
    cached = hf_hub_download(REPO, path)
    shutil.copy2(os.path.realpath(cached), out)
    print(f"  {name} done.")
PYEOF
fi

# ── 6. Data directory ────────────────────────────────────────────────────────

mkdir -p data/journals
# Drop directory for installable 3rd-party plugins (loaded from /data/plugins).
mkdir -p data/plugins

if [ ! -f data/config.json ]; then
    echo "==> Copying seed config..."
    if [ -f data/config.json.example ]; then
        cp data/config.json.example data/config.json
    else
        echo "  (no data/config.json.example found — you must create data/config.json manually)"
        echo "  Minimum required fields: callsign, voice"
    fi
fi

# ── 7. Validate ──────────────────────────────────────────────────────────────

echo ""
echo "==> Validating install..."
python -c "import sounddevice; print('  sounddevice    OK')"
python -c "import faster_whisper; print('  faster-whisper OK')"
python -c "import piper; print('  piper-tts      OK')"
python -c "import silero_vad; print('  silero-vad     OK')"
python -c "import numpy; print('  numpy          OK')"
python -c "import huggingface_hub; print('  huggingface_hub OK')"

echo ""
echo "Done. To start the server:"
echo "  source .venv/bin/activate"
echo "  uvicorn backend.server:app --host 0.0.0.0 --port 8765"
echo ""
echo "Edit data/config.json to set your callsign, audio devices, and voice."