aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/bootstrap.sh
blob: 809e4e2869a3faf8742b111abc0cefeee8abc6ca (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
#!/usr/bin/env bash
# Gets the repository ready to run: submodules, patches, binaries and models.
#
# It is idempotent: it can be run again safely. And it does not copy models
# (they are more than 5 GB); it links them from wherever they already are.
set -euo pipefail

cd "$(dirname "$0")/.."
ROOT="$PWD"

# Repositories already cloned on the system, so nothing is downloaded or
# rebuilt again. ASIST_ESPEJO is the old name of ASIST_MIRROR.
MIRROR="${ASIST_MIRROR:-${ASIST_ESPEJO:-$HOME/GIT-MIRRO}}"
HF="${ASIST_HF:-$HOME/HF}"

blue()   { printf '\033[36m%s\033[0m\n' "$*"; }
green()  { printf '\033[32m%s\033[0m\n' "$*"; }
warn()   { printf '\033[33m%s\033[0m\n' "$*" >&2; }
bad()    { printf '\033[31m%s\033[0m\n' "$*" >&2; }

link() { # source target description
  local src="$1" dst="$2" what="$3"
  if [ ! -e "$src" ]; then
    warn "  $what not found: $src"
    return 1
  fi
  mkdir -p "$(dirname "$dst")"
  if [ -L "$dst" ] || [ -e "$dst" ]; then
    rm -rf "$dst"
  fi
  ln -s "$src" "$dst"
  green "  $what -> $(basename "$src")"
}

# ---------------------------------------------------------------------------
blue "1/5  Submodules"
# If the repository is cloned next door, it is used as a reference: llama.cpp
# is 406 MB of objects that do not need downloading again.
for name in canary-rs qwentts.cpp llama.cpp; do
  path="vendor/$name"
  if [ -f "$path/.git" ] || [ -d "$path/.git" ]; then
    continue
  fi
  if [ -d "$MIRROR/$name/.git" ]; then
    git -c protocol.file.allow=always submodule update --init \
        --reference "$MIRROR/$name" "$path"
  else
    git submodule update --init "$path"
  fi
done
git submodule status | sed 's/^/  /'

# ---------------------------------------------------------------------------
blue "2/5  Patches and loose files"
# The patches hold the local changes on each repository: without them the ASR
# behaves differently from the one that was measured.
for name in canary-rs qwentts.cpp llama.cpp; do
  patch="$ROOT/vendor/patches/$name.patch"
  [ -s "$patch" ] || continue
  (
    cd "vendor/$name"
    if git apply --check "$patch" 2>/dev/null; then
      git apply "$patch"
      green "  $name: patch applied"
    elif git apply --reverse --check "$patch" 2>/dev/null; then
      green "  $name: patch already applied"
    else
      bad "  $name: the patch does not apply; review it by hand"
    fi
  )
done
# Files that only existed in the local working tree and a patch cannot carry.
# canary-rs does not build without bench_live.rs: its Cargo.toml declares it.
if [ -d vendor/extra ]; then
  for name in canary-rs qwentts.cpp; do
    [ -d "vendor/extra/$name" ] || continue
    cp -rn "vendor/extra/$name/." "vendor/$name/" 2>/dev/null || true
  done
  green "  loose files copied"
fi

# ---------------------------------------------------------------------------
blue "3/5  C++ engines"
link_or_build() { # name build_path build_command...
  local name="$1" build="$2"; shift 2
  if [ -e "vendor/$name/$build" ]; then
    green "  $name is already built"
    return
  fi
  if [ -e "$MIRROR/$name/$build" ]; then
    link "$MIRROR/$name/$(dirname "$build")" \
         "$ROOT/vendor/$name/$(dirname "$build")" "$name build"
    return
  fi
  warn "  $name not built. Building (this takes a while)…"
  ( cd "vendor/$name" && "$@" )
}
link_or_build 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'
link_or_build qwentts.cpp build/tts-server \
  bash -c './buildcuda.sh'

# ---------------------------------------------------------------------------
blue "4/5  Models"
# Linked, not copied: together they are more than 5 GB.
link "$HF/Qwen/Qwen3.5-2B.Q5_K_M.gguf" "$ROOT/models/Qwen3.5-2B.Q5_K_M.gguf" "LLM model" || true
link "$HF/Qwen/mmproj-BF16.gguf"       "$ROOT/models/mmproj-BF16.gguf"       "multimodal projector" || true
for m in qwen-talker-1.7b-base-Q8_0.gguf qwen-tokenizer-12hz-Q8_0.gguf; do
  link "$MIRROR/qwentts.cpp/models/$m" "$ROOT/models/$m" "$m" || true
done
if [ ! -d vendor/canary-rs/models/canary-180m-flash-onnx ] \
   && [ -d "$MIRROR/canary-rs/models/canary-180m-flash-onnx" ]; then
  link "$MIRROR/canary-rs/models/canary-180m-flash-onnx" \
       "$ROOT/vendor/canary-rs/models/canary-180m-flash-onnx" "Canary model" || true
fi

# ---------------------------------------------------------------------------
blue "5/5  Reference voice"
# The assistant speaks with a cloned voice. If none is prepared, say how to make
# one instead of failing: everything else already works with a model voice.
if [ -f assets/voices/asistente.spk ]; then
  green "  there is already a voice in assets/voices/"
else
  warn "  no cloned voice. Prepare one with:"
  warn "      scripts/clone-voice.sh <recording.wav> <transcript.txt>"
  warn "  or remove the [tts.reference] section from config/asistente.toml to"
  warn "  use one of the model's own voices."
fi

echo
blue "Done. Check with:  cargo run --release -- check"