Add model selection wizard with speed estimates and origin preference

Replace fixed model defaults with an interactive wizard:

Origin preference:
  1) Western-only      — Codestral (Mistral 🇫🇷) · Phi4 · Mistral 7B
  2) Performance-first — Qwen2.5 + Qwen2.5-Coder (top benchmarks)
  3) Mixed             — Western chat/reasoning, Qwen for coding only
  4) Custom            — free-form model names

Size tier table — speed estimated for the user's actual VRAM with no
hard limits (Ollama already uses all available VRAM via NUM_GPU=999):
  ✓ fast  — fully in VRAM
  ~ good  — fits with small overhang (~reading speed)
  ✗ slow  — partial CPU offload
  ✗ very slow — heavy CPU offload

Recommended tier shown as suggestion based on VRAM, user can override.
pull-models.sh now bakes in the chosen model names at install time.
REASON_MODEL replaces hardcoded deepseek-r1:14b; skipped if empty or
same as chat model.

https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
This commit is contained in:
Claude
2026-03-21 00:23:11 +00:00
parent 796a073c0a
commit 7953ba9d99
+139 -27
View File
@@ -235,27 +235,127 @@ if command -v ufw &>/dev/null && { [[ ! -f "$BASE/.ufw-done" ]] || $FORCE; }; th
[[ "$LAN_SUBNET" =~ /[0-9]+$ ]] || LAN_SUBNET="${LAN_SUBNET}/24"
fi
# ── Q5: Pull Ollama models now? ───────────────────────────────────────────────
# ── Q5: Model selection wizard ────────────────────────────────────────────────
PULL_MODELS=false
PULL_DEEPSEEK=false
REASON_MODEL=""
if $INSTALL_AI; then
# speed estimate based on Q4 model size vs available VRAM
# no hard limits — just honest labels so the user can choose
speed_label() {
local mgb="$1" # approximate Q4 size in GB
if [[ "$VRAM_GB" -eq 0 ]]; then
printf "CPU only — very slow"
elif (( mgb <= VRAM_GB )); then
printf "✓ fast — fully in VRAM"
elif (( mgb <= VRAM_GB + 2 )); then
printf "~ good — fits with small overhang (~reading speed)"
elif (( mgb <= VRAM_GB + 8 )); then
printf "✗ slow — partial CPU offload"
else
printf "✗ very slow — heavy CPU offload"
fi
}
echo ""
echo -e " ${BOLD}[5/6] Download AI models now?${NC}"
echo " GPU detected: ${GPU_NAME} (${VRAM_GB}GB VRAM) → recommended tier: ${GPU_TIER}"
echo -e " ${BOLD}[5/6] Model selection${NC}"
echo " GPU: ${GPU_NAME:-None} (${VRAM_GB}GB VRAM)"
echo ""
echo " Models that will be downloaded:"
echo " nomic-embed-text (~300MB) — RAG embeddings (required)"
echo " ${FAST_MODEL} (~5GB) — fast chat"
echo " ${CHAT_MODEL} (~9GB) — smart chat"
echo " ${CODE_MODEL} (~5GB) — code assistant"
echo " Origin preference:"
echo " 1) Western-only — Codestral (Mistral 🇫🇷) · Phi4 (Microsoft 🇺🇸) · Mistral 7B"
echo " 2) Performance-first — Qwen2.5 · Qwen2.5-Coder (Chinese, top benchmarks)"
echo " 3) Mixed — Western for chat/reasoning, Qwen for coding only"
echo " 4) Custom — enter model names manually"
echo ""
read -rp " Download models now? (~20GB total) [Y/n]: " DO_PULL
if [[ "${DO_PULL,,}" != "n" ]]; then
PULL_MODELS=true
read -rp " Also download DeepSeek-R1:14b for reasoning? (~9GB extra) [y/N]: " DO_DS
[[ "${DO_DS,,}" == "y" ]] && PULL_DEEPSEEK=true
read -rp " Choice [1]: " MODEL_PREF
MODEL_PREF="${MODEL_PREF:-1}"
# Q4 approximate sizes in GB: 7B=4, 13-15B=9, 22B=13, 32B=19, 70-72B=41
echo ""
echo " Size tier — estimated speed on your ${VRAM_GB}GB GPU:"
echo " (No hard limits — Ollama uses all available VRAM automatically)"
echo ""
printf " %-8s %-42s %s\n" "Tier" "Models" "Speed on your system"
printf " %-8s %-42s %s\n" "--------" "------------------------------------------" "--------------------"
case "$MODEL_PREF" in
1) # Western
printf " %-8s %-42s %s\n" "7B" "mistral:7b + codellama:7b" "$(speed_label 4)"
printf " %-8s %-42s %s\n" "14B" "phi4:14b + starcoder2:15b" "$(speed_label 9)"
printf " %-8s %-42s %s\n" "22B" "phi4:14b + codestral:22b" "$(speed_label 13)"
printf " %-8s %-42s %s\n" "70B" "llama3.3:70b + codestral:22b" "$(speed_label 41)"
;;
2) # Performance
printf " %-8s %-42s %s\n" "7B" "qwen2.5:7b + qwen2.5-coder:7b" "$(speed_label 4)"
printf " %-8s %-42s %s\n" "14B" "qwen2.5:14b + qwen2.5-coder:14b" "$(speed_label 9)"
printf " %-8s %-42s %s\n" "32B" "qwen2.5:14b + qwen2.5-coder:32b" "$(speed_label 19)"
printf " %-8s %-42s %s\n" "72B" "qwen2.5:72b + qwen2.5-coder:32b" "$(speed_label 41)"
;;
3) # Mixed
printf " %-8s %-42s %s\n" "7B" "mistral:7b + qwen2.5-coder:7b" "$(speed_label 4)"
printf " %-8s %-42s %s\n" "14B" "phi4:14b + qwen2.5-coder:14b" "$(speed_label 9)"
printf " %-8s %-42s %s\n" "32B" "phi4:14b + qwen2.5-coder:32b" "$(speed_label 19)"
printf " %-8s %-42s %s\n" "70B" "llama3.3:70b + qwen2.5-coder:32b" "$(speed_label 41)"
;;
esac
# VRAM-based recommendation (soft — shown as suggestion only)
if [[ "$VRAM_GB" -ge 20 ]]; then REC_TIER="32B"
elif [[ "$VRAM_GB" -ge 12 ]]; then REC_TIER="22B"
elif [[ "$VRAM_GB" -ge 6 ]]; then REC_TIER="14B"
else REC_TIER="7B"
fi
# performance pref has no 22B tier
[[ "$MODEL_PREF" == "2" && "$REC_TIER" == "22B" ]] && REC_TIER="32B"
echo ""
if [[ "$MODEL_PREF" == "4" ]]; then
# Custom — free-form entry
echo " Current defaults: fast=$FAST_MODEL chat=$CHAT_MODEL code=$CODE_MODEL"
echo " Press Enter on any line to keep the default shown."
echo ""
read -rp " Fast/chat model [$FAST_MODEL]: " _in; FAST_MODEL="${_in:-$FAST_MODEL}"
read -rp " Smart chat model [$CHAT_MODEL]: " _in; CHAT_MODEL="${_in:-$CHAT_MODEL}"
read -rp " Code model [$CODE_MODEL]: " _in; CODE_MODEL="${_in:-$CODE_MODEL}"
read -rp " Reasoning model (Enter to skip): " REASON_MODEL
else
read -rp " Choose tier [$REC_TIER]: " TIER_PICK
TIER_PICK="${TIER_PICK:-$REC_TIER}"
case "${MODEL_PREF}:${TIER_PICK}" in
# Western
1:7B) FAST_MODEL="mistral:7b"; CHAT_MODEL="mistral:7b"; CODE_MODEL="codellama:7b"; REASON_MODEL="" ;;
1:14B) FAST_MODEL="mistral:7b"; CHAT_MODEL="phi4:14b"; CODE_MODEL="starcoder2:15b"; REASON_MODEL="phi4:14b" ;;
1:22B) FAST_MODEL="mistral:7b"; CHAT_MODEL="phi4:14b"; CODE_MODEL="codestral:22b"; REASON_MODEL="phi4:14b" ;;
1:70B) FAST_MODEL="mistral:7b"; CHAT_MODEL="llama3.3:70b"; CODE_MODEL="codestral:22b"; REASON_MODEL="llama3.3:70b" ;;
# Performance-first
2:7B) FAST_MODEL="qwen2.5:7b"; CHAT_MODEL="qwen2.5:7b"; CODE_MODEL="qwen2.5-coder:7b"; REASON_MODEL="" ;;
2:14B) FAST_MODEL="qwen2.5:7b"; CHAT_MODEL="qwen2.5:14b"; CODE_MODEL="qwen2.5-coder:14b"; REASON_MODEL="deepseek-r1:14b" ;;
2:32B) FAST_MODEL="qwen2.5:7b"; CHAT_MODEL="qwen2.5:14b"; CODE_MODEL="qwen2.5-coder:32b"; REASON_MODEL="deepseek-r1:14b" ;;
2:72B) FAST_MODEL="qwen2.5:7b"; CHAT_MODEL="qwen2.5:72b"; CODE_MODEL="qwen2.5-coder:32b"; REASON_MODEL="deepseek-r1:14b" ;;
# Mixed
3:7B) FAST_MODEL="mistral:7b"; CHAT_MODEL="mistral:7b"; CODE_MODEL="qwen2.5-coder:7b"; REASON_MODEL="" ;;
3:14B) FAST_MODEL="mistral:7b"; CHAT_MODEL="phi4:14b"; CODE_MODEL="qwen2.5-coder:14b"; REASON_MODEL="phi4:14b" ;;
3:32B) FAST_MODEL="mistral:7b"; CHAT_MODEL="phi4:14b"; CODE_MODEL="qwen2.5-coder:32b"; REASON_MODEL="phi4:14b" ;;
3:70B) FAST_MODEL="mistral:7b"; CHAT_MODEL="llama3.3:70b"; CODE_MODEL="qwen2.5-coder:32b"; REASON_MODEL="llama3.3:70b" ;;
*)
warn "Unrecognised tier '$TIER_PICK' — keeping detected defaults"
;;
esac
fi
echo ""
echo " Models selected:"
printf " %-16s %s\n" "Fast chat:" "$FAST_MODEL"
printf " %-16s %s\n" "Smart chat:" "$CHAT_MODEL"
printf " %-16s %s\n" "Code:" "$CODE_MODEL"
[[ -n "$REASON_MODEL" ]] && printf " %-16s %s\n" "Reasoning:" "$REASON_MODEL"
printf " %-16s %s\n" "Embed (RAG):" "$EMBED_MODEL"
echo ""
read -rp " Download these models now? [Y/n]: " DO_PULL
[[ "${DO_PULL,,}" != "n" ]] && PULL_MODELS=true
fi
# ── Summary ───────────────────────────────────────────────────────────────────
@@ -276,7 +376,7 @@ if $INSTALL_AI; then
fi
fi
$INSTALL_KIWIX && echo " ✓ Kiwix ZIMs → $KIWIX_DIR"
$PULL_MODELS && echo " ✓ Pull models : embed + ${FAST_MODEL} + ${CHAT_MODEL} + ${CODE_MODEL}${PULL_DEEPSEEK:+ + deepseek-r1:14b}"
$PULL_MODELS && echo " ✓ Pull models : $EMBED_MODEL + $FAST_MODEL + $CHAT_MODEL + $CODE_MODEL${REASON_MODEL:+ + $REASON_MODEL}"
[[ "$ZIM_CHOICE" == "1" ]] && echo " ✓ Download all ZIMs in background (~130GB)"
[[ "$ZIM_CHOICE" == "2" ]] && echo " ✓ Select ZIMs to download (prompted after stack starts)"
echo ""
@@ -786,25 +886,37 @@ ok "status.sh"
cat > "$BASE/pull-models.sh" << PULLSH
#!/bin/bash
# Models chosen at install time — re-run setup to change selection
EMBED_MODEL="$EMBED_MODEL"
FAST_MODEL="$FAST_MODEL"
CHAT_MODEL="$CHAT_MODEL"
CODE_MODEL="$CODE_MODEL"
REASON_MODEL="$REASON_MODEL"
echo "Waiting for Ollama..."
until docker exec ollama ollama list &>/dev/null; do sleep 3; done
echo "Ollama ready."
echo ""
echo "Pulling embed model (needed for RAG)..."
docker exec ollama ollama pull $EMBED_MODEL
echo "Pulling embed model (RAG — required)..."
docker exec ollama ollama pull "\$EMBED_MODEL"
echo "Pulling fast chat model (~5GB)..."
docker exec ollama ollama pull $FAST_MODEL
echo "Pulling fast chat model..."
docker exec ollama ollama pull "\$FAST_MODEL"
echo "Pulling smart chat model (~9GB)..."
docker exec ollama ollama pull $CHAT_MODEL
echo "Pulling smart chat model..."
[[ "\$CHAT_MODEL" != "\$FAST_MODEL" ]] && docker exec ollama ollama pull "\$CHAT_MODEL"
echo "Pulling code model (~5GB)..."
docker exec ollama ollama pull $CODE_MODEL
echo "Pulling code model..."
docker exec ollama ollama pull "\$CODE_MODEL"
if [[ -n "\$REASON_MODEL" && "\$REASON_MODEL" != "\$CHAT_MODEL" ]]; then
echo "Pulling reasoning model..."
docker exec ollama ollama pull "\$REASON_MODEL"
fi
echo ""
echo "Done. Models:"
echo "Done. Installed models:"
docker exec ollama ollama list
PULLSH
chmod +x "$BASE/pull-models.sh"
@@ -888,9 +1000,9 @@ if $INSTALL_AI && $PULL_MODELS; then
info "Pulling code model..."
docker exec ollama ollama pull "$CODE_MODEL"
if $PULL_DEEPSEEK; then
info "Pulling DeepSeek-R1:14b (reasoning)..."
docker exec ollama ollama pull deepseek-r1:14b
if [[ -n "$REASON_MODEL" ]]; then
info "Pulling reasoning model ($REASON_MODEL)..."
docker exec ollama ollama pull "$REASON_MODEL"
fi
ok "All models pulled."