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:
+139
-27
@@ -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."
|
||||
|
||||
Reference in New Issue
Block a user