#!/usr/bin/env bash set -euo pipefail # Startet das zentrale, lokale LLM des Voice-Assistants als llama.cpp-Server # (OpenAI-kompatibel). Dieses grosse, unzensierte Modell ist die Haupt-KI fuer # den Provider "local-openai-compatible". # # Alles ueber ENV ueberschreibbar, z. B.: # HOST_PORT=8101 GPU_DEVICE=2 ./start-llm-server.sh # MODEL_REL_PATH="models/qwen3/anderes-modell.gguf" ./start-llm-server.sh HF_HOME="${HF_HOME:-/home/dschlueter/nvme2n1p7_home/huggingface}" MODEL_REL_PATH="${MODEL_REL_PATH:-models/qwen3/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive-Q4_K_M.gguf}" IMAGE="${IMAGE:-ghcr.io/ggml-org/llama.cpp:server-cuda}" CONTAINER_NAME="${CONTAINER_NAME:-va_llm}" HOST_PORT="${HOST_PORT:-8001}" CONTAINER_PORT="${CONTAINER_PORT:-8000}" MODEL_ALIAS="${MODEL_ALIAS:-va_llm}" GPU_DEVICE="${GPU_DEVICE:-1}" echo "[*] Verwende HF_HOME = $HF_HOME" echo "[*] Modell = $MODEL_REL_PATH" echo "[*] GPU device = $GPU_DEVICE (ueberschreibbar: GPU_DEVICE=2 ./start-llm-server.sh)" echo "[*] Port = $HOST_PORT | Alias = $MODEL_ALIAS | Container = $CONTAINER_NAME" if [ ! -f "$HF_HOME/$MODEL_REL_PATH" ]; then echo "[!] Modell-Datei nicht gefunden: $HF_HOME/$MODEL_REL_PATH" >&2 exit 1 fi if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}\$"; then echo "[*] Stoppe existierenden Container $CONTAINER_NAME ..." docker rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true fi echo "[*] Starte llama.cpp-Server (zentrale Voice-Assistant-KI) ..." docker run -d \ --gpus "\"device=${GPU_DEVICE}\"" \ --name "$CONTAINER_NAME" \ --restart unless-stopped \ -e HF_HOME="/hf_home" \ -v "$HF_HOME:/hf_home:ro" \ -p "${HOST_PORT}:${CONTAINER_PORT}" \ "$IMAGE" \ -m "/hf_home/${MODEL_REL_PATH}" \ --alias "${MODEL_ALIAS}" \ -c 262144 \ -n 16384 \ --jinja \ --reasoning on \ --no-context-shift \ --temp 0.65 \ --top-p 0.80 \ --top-k 20 \ --min-p 0.01 \ --repeat-penalty 1.05 \ --main-gpu 0 \ -ngl 999 \ -fa on \ --kv-unified \ --cache-type-k q4_0 \ --cache-type-v q4_0 \ --batch-size 1024 \ --ubatch-size 512 \ --parallel 1 \ --cont-batching \ --host 0.0.0.0 \ --port "$CONTAINER_PORT" echo "[*] Warte auf Modell-Bereitschaft (Completion-Check, max. 300 s) ..." MODEL_READY=0 for i in {1..150}; do HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 \ -X POST "http://localhost:${HOST_PORT}/v1/chat/completions" \ -H "Content-Type: application/json" \ -d "{\"model\":\"${MODEL_ALIAS}\",\"messages\":[{\"role\":\"user\",\"content\":\"ping\"}],\"max_tokens\":1,\"temperature\":0.0,\"stream\":false}") || HTTP_CODE="000" if [ "$HTTP_CODE" = "200" ]; then MODEL_READY=1; break; fi echo " [${i}/150] HTTP ${HTTP_CODE:-000} — Modell laedt noch, warte 2s ..." sleep 2 done if [ "$MODEL_READY" -ne 1 ]; then echo "[!] Modell wurde nicht rechtzeitig bereit (kein HTTP 200 auf Completion)." >&2 docker logs --tail 200 "$CONTAINER_NAME" || true exit 1 fi echo "[*] Modell bereit — erster Completion-Request erfolgreich (HTTP 200)." echo "[*] Server laeuft auf http://0.0.0.0:${HOST_PORT}/v1 (Alias: ${MODEL_ALIAS})" echo "[*] Setze im Gateway: LOCAL_LLM_BASE_URL=http://127.0.0.1:${HOST_PORT}/v1 LOCAL_LLM_MODEL=${MODEL_ALIAS}" echo "[*] Stoppen mit: scripts/llm-server/stop-llm-server.sh"