aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/bootstrap.sh
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/bootstrap.sh')
-rwxr-xr-xscripts/bootstrap.sh132
1 files changed, 132 insertions, 0 deletions
diff --git a/scripts/bootstrap.sh b/scripts/bootstrap.sh
new file mode 100755
index 0000000..9ba694e
--- /dev/null
+++ b/scripts/bootstrap.sh
@@ -0,0 +1,132 @@
+#!/usr/bin/env bash
+# Deja el repositorio en condiciones de ejecutarse: submódulos, parches,
+# binarios y modelos.
+#
+# Es idempotente: se puede volver a lanzar sin miedo. Y no copia modelos —son
+# más de 5 GB—, sino que los enlaza desde donde ya estén.
+set -euo pipefail
+
+cd "$(dirname "$0")/.."
+RAIZ="$PWD"
+
+# Repositorios ya clonados en el sistema, para no volver a bajar de la red ni
+# recompilar lo que ya está compilado.
+ESPEJO="${ASIST_ESPEJO:-$HOME/GIT-MIRRO}"
+HF="${ASIST_HF:-$HOME/HF}"
+
+azul() { printf '\033[36m%s\033[0m\n' "$*"; }
+verde() { printf '\033[32m%s\033[0m\n' "$*"; }
+aviso() { printf '\033[33m%s\033[0m\n' "$*" >&2; }
+malo() { printf '\033[31m%s\033[0m\n' "$*" >&2; }
+
+enlazar() { # origen destino descripción
+ local origen="$1" destino="$2" que="$3"
+ if [ ! -e "$origen" ]; then
+ aviso " no está $que: $origen"
+ return 1
+ fi
+ mkdir -p "$(dirname "$destino")"
+ if [ -L "$destino" ] || [ -e "$destino" ]; then
+ rm -rf "$destino"
+ fi
+ ln -s "$origen" "$destino"
+ verde " $que -> $(basename "$origen")"
+}
+
+# ---------------------------------------------------------------------------
+azul "1/5 Submódulos"
+# Si el repositorio está clonado al lado, se usa como referencia: llama.cpp son
+# 406 MB de objetos que no hace falta volver a descargar.
+for nombre in canary-rs qwentts.cpp llama.cpp; do
+ ruta="vendor/$nombre"
+ if [ -f "$ruta/.git" ] || [ -d "$ruta/.git" ]; then
+ continue
+ fi
+ if [ -d "$ESPEJO/$nombre/.git" ]; then
+ git -c protocol.file.allow=always submodule update --init \
+ --reference "$ESPEJO/$nombre" "$ruta"
+ else
+ git submodule update --init "$ruta"
+ fi
+done
+git submodule status | sed 's/^/ /'
+
+# ---------------------------------------------------------------------------
+azul "2/5 Parches y ficheros sueltos"
+# Los parches recogen los cambios locales sobre cada repositorio: sin ellos, el
+# ASR se comporta distinto al que se midió.
+for nombre in canary-rs qwentts.cpp llama.cpp; do
+ parche="$RAIZ/vendor/patches/$nombre.patch"
+ [ -s "$parche" ] || continue
+ (
+ cd "vendor/$nombre"
+ if git apply --check "$parche" 2>/dev/null; then
+ git apply "$parche"
+ verde " $nombre: parche aplicado"
+ elif git apply --reverse --check "$parche" 2>/dev/null; then
+ verde " $nombre: parche ya aplicado"
+ else
+ malo " $nombre: el parche no aplica; revísalo a mano"
+ fi
+ )
+done
+# Ficheros que sólo existían en el árbol de trabajo local y que un parche no
+# puede llevar. canary-rs no compila sin bench_live.rs: su Cargo.toml lo declara.
+if [ -d vendor/extra ]; then
+ for nombre in canary-rs qwentts.cpp; do
+ [ -d "vendor/extra/$nombre" ] || continue
+ cp -rn "vendor/extra/$nombre/." "vendor/$nombre/" 2>/dev/null || true
+ done
+ verde " ficheros sueltos copiados"
+fi
+
+# ---------------------------------------------------------------------------
+azul "3/5 Motores en C++"
+enlazar_o_construir() { # nombre ruta_build orden_de_construccion...
+ local nombre="$1" build="$2"; shift 2
+ if [ -e "vendor/$nombre/$build" ]; then
+ verde " $nombre ya está construido"
+ return
+ fi
+ if [ -e "$ESPEJO/$nombre/$build" ]; then
+ enlazar "$ESPEJO/$nombre/$(dirname "$build")" \
+ "$RAIZ/vendor/$nombre/$(dirname "$build")" "build de $nombre"
+ return
+ fi
+ aviso " $nombre sin construir. Construyendo (esto tarda)…"
+ ( cd "vendor/$nombre" && "$@" )
+}
+enlazar_o_construir llama.cpp build/bin/llama-server \
+ bash -c 'cmake -B build -DCMAKE_BUILD_TYPE=Release -DGGML_CUDA=ON && cmake --build build -j --target llama-server'
+enlazar_o_construir qwentts.cpp build/tts-server \
+ bash -c './buildcuda.sh'
+
+# ---------------------------------------------------------------------------
+azul "4/5 Modelos"
+# Se enlazan, no se copian: son más de 5 GB entre todos.
+enlazar "$HF/Qwen/Qwen3.5-2B.Q5_K_M.gguf" "$RAIZ/models/Qwen3.5-2B.Q5_K_M.gguf" "modelo del LLM" || true
+enlazar "$HF/Qwen/mmproj-BF16.gguf" "$RAIZ/models/mmproj-BF16.gguf" "proyector multimodal" || true
+for m in qwen-talker-1.7b-base-Q8_0.gguf qwen-tokenizer-12hz-Q8_0.gguf; do
+ enlazar "$ESPEJO/qwentts.cpp/models/$m" "$RAIZ/models/$m" "$m" || true
+done
+if [ ! -d vendor/canary-rs/models/canary-180m-flash-onnx ] \
+ && [ -d "$ESPEJO/canary-rs/models/canary-180m-flash-onnx" ]; then
+ enlazar "$ESPEJO/canary-rs/models/canary-180m-flash-onnx" \
+ "$RAIZ/vendor/canary-rs/models/canary-180m-flash-onnx" "modelo Canary" || true
+fi
+
+# ---------------------------------------------------------------------------
+azul "5/5 Voz de referencia"
+# El asistente habla con una voz clonada. Si no hay una preparada, se dice cómo
+# hacerla en vez de fallar: el resto ya funciona con una voz del modelo.
+if [ -f assets/voices/asistente.spk ]; then
+ verde " ya hay una voz en assets/voices/"
+else
+ aviso " sin voz clonada. Prepárala con:"
+ aviso " scripts/clonar-voz.sh <grabacion.wav> <transcripcion.txt>"
+ aviso " o quita la sección [tts.reference] de config/asistente.toml para"
+ aviso " usar una voz del propio modelo."
+fi
+
+echo
+azul "Listo. Comprueba con: cargo run --release -- check"