feat(llm): lokales llama.cpp-Modell (va_llm) als zentrale, sprachoptimierte KI

- scripts/llm-server/: start/stop/status fuer llama.cpp-Server (Port 8001, GPU 1,
  Modell Qwen3.6-35B-A3B-Uncensored, Alias va_llm) - alles per ENV ueberschreibbar
- Defaults auf den lokalen Server umgestellt (config.py, .example-Configs, .env.example)
- Provider local-openai-compatible sprachoptimiert: Reasoning aus
  (chat_template_kwargs.enable_thinking=false) + knapper Sprach-System-Prompt,
  optional max_tokens/temperature - Antwort ~9x schneller, kurze vorlesbare Texte
- Makefile-Targets llm-up/llm-down/llm-status
- Doku (README, BEDIENUNGSANLEITUNG) auf llama.cpp statt Ollama aktualisiert

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-06-18 02:57:57 +02:00
commit 28c729f1d4
11 changed files with 323 additions and 31 deletions

View file

@ -85,6 +85,94 @@ VA_PROFILE=cloud make run # alles über OpenRouter
Aktive Konfiguration prüfen: `curl http://localhost:8080/api/config`.
## Lokales LLM (llama.cpp, unzensiert)
Die zentrale KI kann statt OpenRouter ein **lokales, unzensiertes Modell** über einen
llama.cpp-Server (OpenAI-kompatibel) sein. Der Provider `local-openai-compatible`
spricht direkt dagegen — kein Code, nur Server starten + Profil wählen.
```bash
make llm-up # startet den llama.cpp-Container (Default: Port 8001, GPU 1)
make llm-status # Container- + HTTP-Status
make llm-down # stoppt den Container
```
Das Modell wird über das `--alias va_llm` angesprochen; die Defaults zeigen bereits
auf `http://127.0.0.1:8001/v1` mit Modell `va_llm`. Danach genügt ein lokales Profil:
```bash
VA_PROFILE=hybrid make run # STT/TTS remote, Haupt-LLM lokal (unzensiert)
VA_PROFILE=local-dev make run # komplett lokal (faster-whisper / llama.cpp / piper)
```
Alle Server-Parameter sind per ENV überschreibbar (Defaults in Klammern):
| Variable | Bedeutung | Default |
|------------------|---------------------------------------------|---------|
| `HOST_PORT` | Host-Port des Servers | `8001` |
| `GPU_DEVICE` | GPU-Index (von 3 GPUs) | `1` |
| `MODEL_REL_PATH` | Modellpfad relativ zu `HF_HOME` | `models/qwen3/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive-Q4_K_M.gguf` |
| `HF_HOME` | Wurzel der Modell-Sammlung | `~/nvme2n1p7_home/huggingface` |
| `MODEL_ALIAS` | API-Modellname (= `LOCAL_LLM_MODEL`) | `va_llm` |
| `CONTAINER_NAME` | Docker-Containername | `va_llm` |
Beispiel (andere GPU/Port/Modell):
```bash
GPU_DEVICE=2 HOST_PORT=8101 MODEL_REL_PATH=models/qwen3/Qwopus3.6-35B-A3B-v1-Q4_K_M.gguf \
bash scripts/llm-server/start-llm-server.sh
```
> Wird `HOST_PORT`/`MODEL_ALIAS` geändert, müssen `LOCAL_LLM_BASE_URL`/`LOCAL_LLM_MODEL`
> im Gateway (`.env`) entsprechend angepasst werden.
### Tempo im Sprach-Loop
Ein Reasoning-Modell (Qwen3) „denkt" per Default lang und antwortet ausführlich mit
Markdown/Emojis — schlecht zum Vorlesen und spürbar träge. Der Provider
`local-openai-compatible` stellt daher für **gesprochene** Antworten um:
| Setting | Default | Wirkung |
|---------|---------|---------|
| `LOCAL_LLM_DISABLE_REASONING` | `true` | schaltet die Qwen3-Denkphase ab (Time-to-first-word ~9× schneller) |
| `LOCAL_LLM_SYSTEM_PROMPT` | knapper Sprach-Prompt | kurze, vorlesbare Antworten in Fließtext (kein Markdown/Emoji) |
| `LOCAL_LLM_MAX_TOKENS` | `0` (Server-Limit) | optionaler harter Deckel, z. B. `256` |
| `LOCAL_LLM_TEMPERATURE` | `0.3` | Sampling-Temperatur |
> Gemessen am Modell `va_llm`: dieselbe Frage fällt von **5,5 s / 1433 Zeichen**
> (Reasoning an, ausführlich) auf **0,7 s / ~190 Zeichen** (Reasoning aus + Sprach-Prompt).
> Für unzensierte „freie" Gespräche bleibt der Prompt rein formal (nur Kürze/Format,
> keine inhaltlichen Einschränkungen); per `LOCAL_LLM_SYSTEM_PROMPT=` leerbar.
**Zweiter Hebel — STT:** `faster-whisper` läuft per Default auf `auto` (oft CPU) mit
Modell `base`. Auf einer RTX 3090 lohnt `FASTER_WHISPER_DEVICE=cuda` +
`FASTER_WHISPER_COMPUTE_TYPE=float16`; das verkürzt die Transkriptionszeit pro Turn.
### Komplett lokal: Profil `local-dev`
`VA_PROFILE=local-dev` betreibt **alle** KI-Module ohne Cloud. Die Route löst auf zu:
| Modul | Provider | Quelle |
|-------|----------|--------|
| STT | `faster-whisper` | lokales Whisper-Modell |
| **LLM** | `local-openai-compatible` | llama.cpp-Server `http://127.0.0.1:8001/v1`, Modell `va_llm` |
| TTS | `piper` | lokales Stimmmodell |
**Voraussetzungen:**
- **LLM:** llama.cpp-Container läuft (`make llm-up`)
- **STT:** faster-whisper installiert (`pip install -e .[local]`)
- **TTS:** piper-Binary + Stimme vorhanden (siehe `PIPER_*` in `.env.example`)
**Start (Reihenfolge):**
```bash
make llm-up # 35B-Modell laden; mit make llm-status auf "HTTP OK" warten
make run # Gateway nutzt jetzt das lokale, unzensierte Modell als zentrale KI
```
> `VA_PROFILE` ist in `.env` dauerhaft setzbar (aktuell `local-dev`) oder pro Lauf
> voranstellbar (`VA_PROFILE=hybrid make run`). Prüfen: `curl http://localhost:8080/api/config`.
## API-Überblick
| Methode & Pfad | Zweck |