Expand router into reproducible local AI platform
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
# Architektur
|
||||
|
||||
## Ziel
|
||||
|
||||
Die Plattform stellt eine private, lokal betriebene OpenAI-kompatible API
|
||||
bereit. Jede Komponente hat genau eine Aufgabe und kann unabhängig ersetzt
|
||||
werden. Ein Neuaufbau darf keine Dateien vom alten Host voraussetzen, die nicht
|
||||
in diesem Repository oder im Modellmanifest beschrieben sind.
|
||||
|
||||
## Komponenten
|
||||
|
||||
| Komponente | Port | Ausführung | Aufgabe |
|
||||
|---|---:|---|---|
|
||||
| AI Profile Router | 8081 | systemd, unprivilegiert empfohlen | zentrale Client-API und Orchestrierung |
|
||||
| llama.cpp | 8080 | systemd | Textmodell, Tool Calling und MCP |
|
||||
| Whisper | 8084, nur localhost | systemd | Speech-to-Text |
|
||||
| XTTS | 8085, nur localhost | systemd | Text-to-Speech |
|
||||
| TinySearch | 8000, nur localhost | Docker | kompakte Websuche |
|
||||
| SearXNG | intern | Docker | Suchmaschinen-Metasuche |
|
||||
| LLama-GUI | 5240, optional | systemd | manuelle Administration |
|
||||
| Glances | lokal, optional | systemd | Systemmetriken |
|
||||
|
||||
## Request-Fluss
|
||||
|
||||
1. Ein Client verwendet ausschließlich Port 8081.
|
||||
2. Der Router veröffentlicht `qwen-fast`, `qwen-medium` und `qwen-long`.
|
||||
3. Passt das aktive Profil nicht zum virtuellen Modell, wird llama.cpp kontrolliert
|
||||
mit dem passenden Profil neu gestartet.
|
||||
4. Der Router wartet auf Modellname und erwartete Kontextgröße.
|
||||
5. Erst dann wird die Anfrage an Port 8080 weitergeleitet.
|
||||
|
||||
## Profilprinzip
|
||||
|
||||
Die Profile sind vollständige systemd-Overrides. Ein Profilwechsel kopiert die
|
||||
gewählte Datei atomar auf `override.conf`, lädt systemd neu und startet genau
|
||||
einen llama.cpp-Dienst neu. Es gibt niemals mehrere Textmodelle gleichzeitig.
|
||||
|
||||
## GPU-Hotswap
|
||||
|
||||
Vision und Bildgenerierung teilen sich die RTX mit dem Textmodell. Der Router:
|
||||
|
||||
1. sperrt die GPU-Orchestrierung,
|
||||
2. merkt sich das aktive Textprofil,
|
||||
3. stoppt llama.cpp,
|
||||
4. startet vorübergehend Vision oder FLUX,
|
||||
5. beendet den Hilfsprozess vollständig,
|
||||
6. stellt das ursprüngliche Textprofil wieder her,
|
||||
7. prüft Modell und Kontext vor der Freigabe.
|
||||
|
||||
## Verzeichnislayout auf dem Zielhost
|
||||
|
||||
```text
|
||||
/opt/mike-ai/
|
||||
ai-profile-router/ Routercode und eigenes Venv
|
||||
llama.cpp/ exakt ein produktiver Build
|
||||
models/ Modelle nach Manifest
|
||||
whisper.cpp/ Speech-to-Text Runtime
|
||||
xtts/ XTTS Runtime und Cache
|
||||
web-search/ Docker Compose für TinySearch/SearXNG
|
||||
|
||||
/etc/mike-ai/
|
||||
mcp-servers.json lokale, geheime produktive Konfiguration
|
||||
*.env Credentials, niemals im Git
|
||||
|
||||
/etc/systemd/system/
|
||||
mike-ai-*.service
|
||||
mike-ai-llama-ui.service.d/
|
||||
override.conf
|
||||
profile-fast.conf.disabled
|
||||
profile-medium.conf.disabled
|
||||
profile-long.conf.disabled
|
||||
```
|
||||
|
||||
## Nicht Teil der Zielarchitektur
|
||||
|
||||
- parallele llama.cpp-Builds
|
||||
- allgemeiner Shell-MCP im Standardprofil
|
||||
- doppelte Unraid-MCPs
|
||||
- RX-spezifische Dienste ohne eingebaute RX
|
||||
- automatisch startende Benchmark-Dienste
|
||||
- Modellkopien außerhalb des dokumentierten Modellverzeichnisses
|
||||
@@ -0,0 +1,21 @@
|
||||
# Komponentenverzeichnis
|
||||
|
||||
| Bestandteil | Quelle | Bestandteil dieses Repositories | Status |
|
||||
|---|---|---|---|
|
||||
| AI Profile Router | `router/` | vollständig | Kern |
|
||||
| llama.cpp | ggml-org/llama.cpp, festgeschriebener Commit | Buildskript und Commit | Kern |
|
||||
| Qwen-Profile | `platform/profiles/` | vollständig, Modelle ausgenommen | Kern |
|
||||
| Websuche | TinySearch + SearXNG | Compose und sichere Grundkonfiguration | Kern |
|
||||
| Web-MCP-Fassade | `platform/web-search/web_search_mcp.py` | vollständig | Kern |
|
||||
| Home-Assistant-MCP | separates privates Repository | nur Integration dokumentiert | optional |
|
||||
| ARR-MCP | separates privates Repository | nur Integration dokumentiert | optional |
|
||||
| Unraid-MCP | separates Repository/Installation | read-only Integration dokumentiert | optional |
|
||||
| Whisper | ggml-org/whisper.cpp | Service im Router-Deploy | optional |
|
||||
| XTTS-v2 | Coqui | Worker, Service und Lockdatei | optional |
|
||||
| FLUX.2 klein | Black Forest Labs | Worker und Modellmanifest | optional |
|
||||
| LLama-GUI | separates Upstream-Projekt | nur Betriebsrolle dokumentiert | optional |
|
||||
| Glances | Distribution | nur Betriebsrolle dokumentiert | optional |
|
||||
|
||||
Separate MCP-Repositories werden nicht in dieses Repository kopiert. Ihre
|
||||
Versionen sollen künftig in einem Release-Manifest referenziert werden. So
|
||||
bleiben Zuständigkeiten klar und Updates können unabhängig getestet werden.
|
||||
@@ -0,0 +1,86 @@
|
||||
# Saubere Installation
|
||||
|
||||
Diese Anleitung beschreibt den Neuaufbau. Sie löscht oder migriert keine Daten
|
||||
automatisch.
|
||||
|
||||
## 1. Voraussetzungen
|
||||
|
||||
- Debian 13 oder kompatibles Linux
|
||||
- NVIDIA-Treiber und funktionierendes `nvidia-smi`
|
||||
- Build-Werkzeuge, CMake, Git und CUDA Toolkit
|
||||
- Python 3.13 für Router/FLUX und Python 3.11 für XTTS
|
||||
- Docker plus Compose für Websuche
|
||||
- ausreichend freier Speicher; mindestens 15 Prozent auf `/`
|
||||
|
||||
## 2. Benutzer und Verzeichnisse
|
||||
|
||||
Für produktive Dienste sollen eigene Systembenutzer verwendet werden. Der
|
||||
Router benötigt kontrollierte Berechtigung zum Neustart des llama.cpp-Dienstes;
|
||||
er sollte nicht dauerhaft als root laufen.
|
||||
|
||||
```text
|
||||
/opt/mike-ai/models
|
||||
/opt/mike-ai/ai-profile-router
|
||||
/etc/mike-ai
|
||||
```
|
||||
|
||||
Geheimnisse werden mit Modus `0600` unter `/etc/mike-ai` abgelegt.
|
||||
|
||||
## 3. llama.cpp bauen
|
||||
|
||||
`platform/llama/build-llama-cpp.sh` checkt exakt den in
|
||||
`platform/llama/LLAMA_CPP_COMMIT` hinterlegten Commit aus. Vor einem Upgrade:
|
||||
|
||||
1. neuen Commit in einem separaten Build testen,
|
||||
2. Standardbenchmark ausführen,
|
||||
3. MCP-Grammatik und Tool Calls prüfen,
|
||||
4. Commitdatei erst danach aktualisieren.
|
||||
|
||||
## 4. Modelle bereitstellen
|
||||
|
||||
Modelldateien werden nicht in Git gespeichert. Die erwarteten Rollen und
|
||||
Zielpfade stehen in `platform/models/manifest.example.yaml`. Für die lokale
|
||||
Installation wird daraus eine nicht eingecheckte `manifest.local.yaml` mit
|
||||
SHA256-Prüfsummen erstellt.
|
||||
|
||||
## 5. llama.cpp-Dienst und Profile
|
||||
|
||||
Die Dateien aus `platform/systemd` und `platform/profiles` installieren. Danach:
|
||||
|
||||
```text
|
||||
llama-profile fast
|
||||
```
|
||||
|
||||
Der Befehl muss Port 8080 erst freigeben, wenn Modell und Kontext korrekt sind.
|
||||
|
||||
## 6. MCP-Konfiguration
|
||||
|
||||
`platform/mcp/mcp-servers.example.json` nach `/etc/mike-ai/mcp-servers.json`
|
||||
kopieren und nur benötigte Server aktivieren. Zugangsdaten werden ausschließlich
|
||||
über lokale Environment-Dateien oder einen Secret Broker referenziert.
|
||||
|
||||
## 7. Router installieren
|
||||
|
||||
Das bestehende `deploy/install.sh` installiert Router, Vision/Bild-Worker,
|
||||
Whisper und XTTS. Vor produktiver Verwendung müssen Modellpfade in der
|
||||
systemd-Datei gegen das lokale Manifest geprüft werden.
|
||||
|
||||
## 8. Websuche
|
||||
|
||||
TinySearch und SearXNG bleiben als einziges Docker-Teilsystem isoliert. Die
|
||||
Suchdienste sollen nur an localhost gebunden werden; nur der Web-MCP greift
|
||||
darauf zu.
|
||||
|
||||
## 9. Verifikation
|
||||
|
||||
`platform/checks/verify-platform.sh` kontrolliert:
|
||||
|
||||
- freien Plattenplatz,
|
||||
- GPU und VRAM,
|
||||
- aktive Dienste,
|
||||
- Ports,
|
||||
- Routermodelle und aktives Profil,
|
||||
- llama.cpp-Health,
|
||||
- unerwartete RX- und Benchmark-Dienste.
|
||||
|
||||
Erst nach erfolgreicher Prüfung werden Clients auf Port 8081 umgestellt.
|
||||
@@ -0,0 +1,41 @@
|
||||
# Migration vom bestehenden Host
|
||||
|
||||
## Behalten
|
||||
|
||||
- Qwen3.8-27B IQ4-MIX und das getestete MTP2-Profil
|
||||
- IQ4_XS Pure für Medium
|
||||
- Q3-Vision-Modell und passender `mmproj`
|
||||
- festgeschriebener llama.cpp-Commit
|
||||
- Router, Whisper, XTTS und Websuche
|
||||
- spezialisierte MCPs nach Sicherheitsprofil
|
||||
- relevante Benchmarkresultate
|
||||
|
||||
## Nicht übernehmen
|
||||
|
||||
- RX-470-Dienste
|
||||
- doppelte Whisper-Server
|
||||
- automatisch aktivierte Modellrennen und Benchmarks
|
||||
- unvollständige Modelldownloads
|
||||
- alte llama.cpp-/BeeLlama-Testbuilds
|
||||
- alte systemd-Backups
|
||||
- Caches und generierte Medien
|
||||
- doppelte oder klar unterlegene Modelle
|
||||
|
||||
## Reihenfolge
|
||||
|
||||
1. Repositories und verschlüsselte Konfiguration sichern.
|
||||
2. Modellmanifest mit Dateigrößen und SHA256 erstellen.
|
||||
3. Neuen Host installieren und Speicherlayout festlegen.
|
||||
4. NVIDIA-Treiber und CUDA verifizieren.
|
||||
5. Festgeschriebenen llama.cpp-Commit bauen.
|
||||
6. nur die benötigten Modelle übertragen und Hashes prüfen.
|
||||
7. Fast-Profil ohne MCP starten und testen.
|
||||
8. Medium und Long einzeln testen.
|
||||
9. Router installieren und Profilwechsel testen.
|
||||
10. Web, HA, ARR und Unraid nacheinander hinzufügen.
|
||||
11. STT, TTS und Vision ergänzen.
|
||||
12. Standardbenchmark und Sicherheitsprüfung ausführen.
|
||||
13. Erst danach Clients umstellen.
|
||||
|
||||
Der alte Host bleibt bis zum bestandenen Abnahmetest unverändert und dient nur
|
||||
als Referenz. Es werden keine Caches oder unbekannten Altverzeichnisse kopiert.
|
||||
@@ -0,0 +1,57 @@
|
||||
# Betrieb
|
||||
|
||||
## Profile
|
||||
|
||||
| Profil | Virtuelles Modell | Kontext | Zweck |
|
||||
|---|---|---:|---|
|
||||
| Fast | `qwen-fast` | 73.728 | Alltag, Agenten, hohe Geschwindigkeit |
|
||||
| Medium | `qwen-medium` | 94.208 | mehr Kontext, reine IQ4_XS-Variante |
|
||||
| Long | `qwen-long` | 131.072 | lange Hermes-/MCP-Sitzungen |
|
||||
|
||||
Manuell wird mit `llama-profile fast|medium|long` gewechselt. Über HTTP stehen
|
||||
`POST /fast`, `/medium` und `/long` zur Verfügung. Für eine spätere Version ist
|
||||
`large` als Alias für `long` vorgesehen; bestehende Namen bleiben kompatibel.
|
||||
|
||||
## Clients
|
||||
|
||||
Clients verbinden sich mit:
|
||||
|
||||
```text
|
||||
http://HOST:8081/v1
|
||||
```
|
||||
|
||||
Sie sollen nicht direkt Port 8080 verwenden, weil sie sonst Profilumschaltung,
|
||||
Vision, Bildgenerierung, STT und TTS umgehen.
|
||||
|
||||
## Status
|
||||
|
||||
- `GET /status`: Router, Profil, Upstream, aktive Jobs
|
||||
- `GET /v1/models`: virtuelle Modelle
|
||||
- llama.cpp-Metriken: Port 8080, nur im administrativen Netz freigeben
|
||||
- systemd-Journal: nur Metadaten und Fehler prüfen; keine Promptinhalte sammeln
|
||||
|
||||
## Upgrade-Regel
|
||||
|
||||
Niemals Build, Quantisierung und Profil gleichzeitig ändern. Immer genau eine
|
||||
Variable ändern und anschließend denselben Benchmark ausführen.
|
||||
|
||||
## Kapazitätsregeln
|
||||
|
||||
- Systempartition dauerhaft unter 85 Prozent halten.
|
||||
- Mindestens 1 GiB Sicherheitsreserve für allgemeine GPU-Profile vorsehen;
|
||||
experimentelle Max-GPU-Profile klar kennzeichnen.
|
||||
- Nur ein Textmodell gleichzeitig laden.
|
||||
- Benchmarks sind deaktivierte, manuell gestartete Jobs und keine Boot-Dienste.
|
||||
|
||||
## Backup
|
||||
|
||||
Gesichert werden:
|
||||
|
||||
- dieses Repository,
|
||||
- lokale Modellmanifest-Datei mit Hashes, aber ohne Secrets,
|
||||
- `/etc/mike-ai` verschlüsselt,
|
||||
- systemd-Konfiguration,
|
||||
- Benchmarkresultate.
|
||||
|
||||
Nicht gesichert werden müssen Build-Verzeichnisse, Venvs, Caches oder Modelle,
|
||||
wenn Downloadquelle und Prüfsumme dokumentiert sind.
|
||||
@@ -0,0 +1,59 @@
|
||||
# Sicherheitsmodell
|
||||
|
||||
## Grundsatz
|
||||
|
||||
Das lokale Modell erhält nur die Werkzeuge, die es für den aktuellen Modus
|
||||
benötigt. Lokalität allein ersetzt keine Zugriffskontrolle.
|
||||
|
||||
## MCP-Profile
|
||||
|
||||
Empfohlene Trennung:
|
||||
|
||||
| Modus | Werkzeuge |
|
||||
|---|---|
|
||||
| Standard | Websuche, harmlose lokale Hilfsfunktionen |
|
||||
| Home Assistant | HA-Administration plus Websuche |
|
||||
| ARR | Sonarr/Radarr plus Websuche |
|
||||
| Unraid Read-only | Diagnose, Logs, Status |
|
||||
| Unraid Write | nur bewusst aktiviert, mit Vorschau und Approval Ticket |
|
||||
|
||||
## Nicht im Standardprofil
|
||||
|
||||
- allgemeine Shell
|
||||
- `python3`, `ssh`, `scp` oder beliebiges `curl`
|
||||
- Container erstellen, verändern oder löschen
|
||||
- Registry-/Storage-Direktzugriff
|
||||
- uneingeschränkte Dateisuche
|
||||
|
||||
## Secrets
|
||||
|
||||
- Keine Secrets in Git, Prompts, MCP-Schemas oder Logs.
|
||||
- Konfiguration referenziert nur Namen lokaler Environment-Dateien.
|
||||
- Dateien mit Secrets: Eigentümer root oder Dienstbenutzer, Modus `0600`.
|
||||
- Tokens werden pro Dienst getrennt und minimal berechtigt.
|
||||
- Ein Secret Broker oder Wrapper stellt Verbindungen her, ohne Tokens an das
|
||||
Modell zurückzugeben.
|
||||
|
||||
## Netzwerk
|
||||
|
||||
- Port 8080 nur localhost oder administratives VLAN.
|
||||
- Clients verwenden Port 8081.
|
||||
- Whisper, XTTS, TinySearch und SearXNG nur localhost.
|
||||
- Firewall erlaubt nur bekannte Quellnetze.
|
||||
- Externe Suche erhält nur die tatsächliche Suchanfrage, keine Chat-Historie.
|
||||
|
||||
## Schreibaktionen
|
||||
|
||||
Jede destruktive oder persistente Aktion verwendet:
|
||||
|
||||
1. read-only Bestandsaufnahme,
|
||||
2. exakte Vorschau,
|
||||
3. an diese Vorschau gebundenes Approval Ticket,
|
||||
4. unveränderte Ausführung,
|
||||
5. anschließende Verifikation.
|
||||
|
||||
## Repository-Prüfung vor jedem Push
|
||||
|
||||
- Suche nach Token-, Passwort- und Private-Key-Mustern.
|
||||
- Keine `.env`, Zertifikate, Logs, Bilder, Audio oder Modellartefakte.
|
||||
- Keine echten internen API-Schlüssel in Beispielen.
|
||||
Reference in New Issue
Block a user