aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/bootstrap.sh
blob: 9ba694ebcd7962e80147c879f03d271db0210678 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
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"