Add README.md, BEDIENUNGSANLEITUNG.md, and setup/start scripts
README.md gives the precise, reproducible install path (tested the two scripts against the live instance - both idempotent, correctly detect already-registered credentials/models). BEDIENUNGSANLEITUNG.md covers daily usage: notebooks/sources, the three chat context modes (and why "nur Erkenntnisse" needs a transformation run first), podcasts, voice cloning, and troubleshooting for the issues actually hit during setup (num_ctx truncation, embedding GPU contention, ufw). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
778f820e27
commit
7838863dbf
4 changed files with 652 additions and 0 deletions
137
scripts/setup_models.sh
Executable file
137
scripts/setup_models.sh
Executable file
|
|
@ -0,0 +1,137 @@
|
|||
#!/usr/bin/env bash
|
||||
# Registriert Ollama + OpenRouter + lokale TTS/STT-Wrapper als AI-Provider in
|
||||
# Open Notebook und setzt sinnvolle Standardmodelle. Für einen frischen Stack
|
||||
# gedacht (siehe README.md) — prüft vor dem Anlegen jeweils, ob Credential/
|
||||
# Modell mit demselben Namen schon existiert, ist also im Wesentlichen
|
||||
# wiederholbar, aber nicht für abweichende Konfigurationen gedacht.
|
||||
set -euo pipefail
|
||||
|
||||
API="http://127.0.0.1:5055/api"
|
||||
|
||||
echo "Warte auf Open Notebook API..."
|
||||
until curl -sf "${API}/models/providers" >/dev/null 2>&1; do sleep 2; done
|
||||
|
||||
# --- Hilfsfunktionen -------------------------------------------------------
|
||||
|
||||
credential_id_by_name() {
|
||||
curl -s "${API}/credentials" | python3 -c "
|
||||
import json, sys
|
||||
name = sys.argv[1]
|
||||
for c in json.load(sys.stdin):
|
||||
if c['name'] == name:
|
||||
print(c['id']); break
|
||||
" "$1"
|
||||
}
|
||||
|
||||
model_id_by_name() {
|
||||
curl -s "${API}/models" | python3 -c "
|
||||
import json, sys
|
||||
name = sys.argv[1]
|
||||
for m in json.load(sys.stdin):
|
||||
if m['name'] == name:
|
||||
print(m['id']); break
|
||||
" "$1"
|
||||
}
|
||||
|
||||
ensure_credential() {
|
||||
# ensure_credential <name> <json-payload>
|
||||
local name="$1" payload="$2" id
|
||||
id=$(credential_id_by_name "$name")
|
||||
if [ -n "$id" ]; then
|
||||
echo "Credential '$name' existiert bereits ($id)" >&2
|
||||
echo "$id"
|
||||
return
|
||||
fi
|
||||
id=$(curl -s -X POST "${API}/credentials" -H "Content-Type: application/json" -d "$payload" \
|
||||
| python3 -c "import json,sys; print(json.load(sys.stdin)['id'])")
|
||||
echo "Credential '$name' angelegt ($id)" >&2
|
||||
echo "$id"
|
||||
}
|
||||
|
||||
ensure_model() {
|
||||
# ensure_model <name> <provider> <type> [credential_id]
|
||||
local name="$1" provider="$2" type="$3" cred="${4:-}" id
|
||||
id=$(model_id_by_name "$name")
|
||||
if [ -n "$id" ]; then
|
||||
echo "Modell '$name' existiert bereits ($id)" >&2
|
||||
echo "$id"
|
||||
return
|
||||
fi
|
||||
local cred_json="null"
|
||||
[ -n "$cred" ] && cred_json="\"$cred\""
|
||||
id=$(curl -s -X POST "${API}/models" -H "Content-Type: application/json" \
|
||||
-d "{\"name\": \"$name\", \"provider\": \"$provider\", \"type\": \"$type\", \"credential\": ${cred_json}}" \
|
||||
| python3 -c "import json,sys; print(json.load(sys.stdin)['id'])")
|
||||
echo "Modell '$name' ($type) angelegt ($id)" >&2
|
||||
echo "$id"
|
||||
}
|
||||
|
||||
# --- 1. OpenRouter: API-Key aus Environment in die DB migrieren -----------
|
||||
|
||||
echo "== OpenRouter =="
|
||||
curl -s -X POST "${API}/credentials/migrate-from-env" >/dev/null
|
||||
echo "OPENROUTER_API_KEY aus Environment migriert (falls gesetzt)"
|
||||
|
||||
# --- 2. Ollama-Credential (Chat/Embedding), num_ctx=98304 -----------------
|
||||
# 98304 ist der größte Kontext, der bei qwen3.5:27b auf dieser Hardware noch
|
||||
# vollständig auf einer GPU bleibt (100% GPU laut `ollama ps`) — 131072
|
||||
# spillt auf die CPU und macht Antworten 5-6x langsamer. Ohne num_ctx
|
||||
# begrenzt esperanto Ollama-Chat-Aufrufe fest auf 8192 Tokens.
|
||||
echo "== Ollama (Chat + Embedding) =="
|
||||
OLLAMA_CRED=$(ensure_credential "Ollama (local)" '{
|
||||
"name": "Ollama (local)",
|
||||
"provider": "ollama",
|
||||
"modalities": ["language", "embedding"],
|
||||
"base_url": "http://host.docker.internal:11434",
|
||||
"num_ctx": 98304
|
||||
}')
|
||||
|
||||
QWEN_CHAT=$(ensure_model "qwen3.5:27b" "ollama" "language" "$OLLAMA_CRED")
|
||||
QWEN_CODER=$(ensure_model "qwen3-coder-30b-128k:latest" "ollama" "language" "$OLLAMA_CRED")
|
||||
NOMIC_EMBED=$(ensure_model "nomic-embed-text" "ollama" "embedding" "$OLLAMA_CRED")
|
||||
|
||||
# --- 3. OpenRouter-Sprachmodelle (kuratiert, nicht alle ~400) --------------
|
||||
echo "== OpenRouter Sprachmodelle =="
|
||||
CLAUDE_SONNET=$(ensure_model "anthropic/claude-sonnet-5" "openrouter" "language")
|
||||
QWEN_MAX=$(ensure_model "qwen/qwen3-max" "openrouter" "language")
|
||||
GEMINI_FLASH=$(ensure_model "google/gemini-3.5-flash" "openrouter" "language")
|
||||
|
||||
# --- 4. Lokale TTS/STT-Wrapper (siehe services/) --------------------------
|
||||
echo "== Lokales TTS (Chatterbox) =="
|
||||
TTS_CRED=$(ensure_credential "Chatterbox TTS (local)" '{
|
||||
"name": "Chatterbox TTS (local)",
|
||||
"provider": "openai_compatible",
|
||||
"modalities": ["text_to_speech"],
|
||||
"base_url": "http://host.docker.internal:8901",
|
||||
"api_key": "not-required"
|
||||
}')
|
||||
TTS_MODEL=$(ensure_model "chatterbox-tts" "openai_compatible" "text_to_speech" "$TTS_CRED")
|
||||
|
||||
echo "== Lokales STT (faster-whisper) =="
|
||||
STT_CRED=$(ensure_credential "faster-whisper STT (local)" '{
|
||||
"name": "faster-whisper STT (local)",
|
||||
"provider": "openai_compatible",
|
||||
"modalities": ["speech_to_text"],
|
||||
"base_url": "http://host.docker.internal:8902",
|
||||
"api_key": "not-required"
|
||||
}')
|
||||
STT_MODEL=$(ensure_model "faster-whisper-large-v3" "openai_compatible" "speech_to_text" "$STT_CRED")
|
||||
|
||||
# --- 5. Standardmodelle setzen ---------------------------------------------
|
||||
# Alles lokal/kostenlos außer Tools-Modell optional auf ein OpenRouter-Modell
|
||||
# umstellbar (siehe BEDIENUNGSANLEITUNG.md, Abschnitt "Modelle wechseln").
|
||||
echo "== Standardmodelle setzen =="
|
||||
curl -s -X PUT "${API}/models/defaults" -H "Content-Type: application/json" -d "{
|
||||
\"default_chat_model\": \"$QWEN_CHAT\",
|
||||
\"default_transformation_model\": \"$QWEN_CHAT\",
|
||||
\"large_context_model\": \"$QWEN_CHAT\",
|
||||
\"default_embedding_model\": \"$NOMIC_EMBED\",
|
||||
\"default_tools_model\": \"$QWEN_CHAT\",
|
||||
\"default_text_to_speech_model\": \"$TTS_MODEL\",
|
||||
\"default_speech_to_text_model\": \"$STT_MODEL\"
|
||||
}" | python3 -m json.tool
|
||||
|
||||
echo
|
||||
echo "Fertig. Registrierte, aber nicht als Standard gesetzte Zusatzmodelle:"
|
||||
echo " - qwen3-coder-30b-128k:latest ($QWEN_CODER) — für reine Coding-Aufgaben"
|
||||
echo " - anthropic/claude-sonnet-5 ($CLAUDE_SONNET), qwen/qwen3-max ($QWEN_MAX), google/gemini-3.5-flash ($GEMINI_FLASH) — OpenRouter-Alternativen"
|
||||
Loading…
Add table
Add a link
Reference in a new issue