Files
ARIA-AGENT/xtts
duffyduckandClaude Opus 5.5 9be14eef5e fix(diagnostic): Karten kommen im Browser an, lokales Modell springt nicht zurueck
1. "Die LLM-Box meldet noch keine Karten": die Box schickte die Karten-
   Belegung, aber workerList() im Diagnostic-Server gibt nur eine feste
   Feldliste an den Browser — slots stand nicht drauf. Meine UI-Tests haben
   die Flotte direkt im Browser gesetzt und sind an genau dieser Stelle
   vorbeigelaufen. Jetzt Ende-zu-Ende getestet: echter Diagnostic-Server +
   RVS + Box-Meldung → Browser (per DevTools-Protokoll gelesen).

2. Lokales Modell sprang auf "Qwen3 8B" zurueck: die Auswahl wurde gespeichert,
   aber die Seite behielt intern das alte Modell und stellte das Dropdown beim
   naechsten Lebenszeichen der Box (10 s) darauf zurueck. Dazu wie gewuenscht
   umgebaut: nur Modelle, die im Cluster geladen sind, jedes einmal, ohne
   Karte. Ist das gewaehlte gerade nirgends geladen: "(offline)" — geht
   automatisch weiter, sobald eine Box es hat. Nichts da: "kein Modell
   verfuegbar". Waehrend die Auswahl offen ist, wird nicht umgebaut.

3. "Bereit", aber Karte leer: der llm-adapter meldet pro Karte den belegten
   VRAM. Laeuft ein Modell "ready" und die Karte bleibt unter 400 MB, rechnet
   llama.cpp auf der CPU (Treiber zu alt fuer das CUDA im Image) — das sagt
   llama.cpp nicht nach aussen. Diagnostic zeigt es jetzt in Flotte,
   LLM-Karten und Modell-Auswahl ("laeuft auf der CPU").

4. bootstrap.sh: der normale Lauf meldete "✓ Treiber aktiv", auch wenn er fuer
   das LLM zu alt ist. Jetzt Warnung mit Version und dem Befehl
   (--upgrade-driver), wenn das LLM-Profil aktiv ist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 02:11:02 +02:00
..

xtts — AI-Box (Compute-Node) Setup & Bootstrap

Der xtts-Stack sind ARIAs GPU-Dienste (STT: Voxtral/Whisper · TTS: F5-TTS · lokales LLM). Er läuft auf einer oder mehreren AI-Boxen — jede per .env konfiguriert (COMPOSE_PROFILES, GPU-Zuordnung). Details zu Profilen/GPU-Wahl stehen im Haupt-README (Abschnitt „Compute-Nodes").

bootstrap.sh macht aus einem frisch installierten Debian Trixie (headless, nur SSH) einen startklaren GPU-Host für diesen Stack.

Was das Script tut

  1. Basis-Pakete (curl, gnupg, git …)
  2. contrib non-free non-free-firmware aktivieren (Trixie-deb822-Format berücksichtigt)
  3. NVIDIA-Treiber installieren (nvidia-driver + firmware)
  4. Docker Engine + Compose-Plugin
  5. NVIDIA Container Toolkit + Docker-Runtime auf NVIDIA konfigurieren
  6. xtts/.env aus .env.example anlegen (RVS_TOKEN optional gleich setzen)
  7. GPU-im-Container-Test (docker run --gpus all … nvidia-smi)
  8. optional (--up): den xtts-Stack hochziehen

Alles idempotent — mehrfach ausführbar.

Ablauf

git clone <repo> ARIA-AGENT
cd ARIA-AGENT/xtts

sudo ./bootstrap.sh
# → Wenn der Treiber frisch installiert wurde: einmal neu starten, dann nochmal:
sudo reboot
# … nach dem Boot:
cd ARIA-AGENT/xtts
sudo ./bootstrap.sh --up --token <DEIN_RVS_TOKEN>

Der Treiber-Reboot ist normal (Kernel-Modul wird erst beim Boot geladen). Beim zweiten Lauf überspringt das Script alles Erledigte und macht nur noch den GPU-Test + Stack-Start.

Optionen

Option Wirkung
--up am Ende docker compose up -d --build (Default-Profil)
--token <TOK> RVS_TOKEN in xtts/.env eintragen (auch via RVS_TOKEN=… env)
--rvs-host <H> RVS_HOST setzen
--upgrade-driver NVIDIA-Treiber aus NVIDIAs Paketquelle für Debian 13 (siehe unten). Spielt erst durch, zeigt den Plan, fragt nach. Danach Reboot.
--yes bei --upgrade-driver nicht nachfragen

Treiber für das lokale LLM: --upgrade-driver

Debian hat höchstens Treiber 550 (CUDA 12.4). Die aktuellen llama.cpp- und llama-swap-Images brauchen CUDA 12.8/12.9. Mit 550 meldet llama.cpp beim Start failed to initialize CUDA … forward compatibility …, findet keine Karte und rechnet still auf der CPU — das Modell meldet trotzdem „bereit". Erkennbar daran, dass nvidia-smi auf der LLM-Karte kaum Speicher belegt zeigt.

cd ARIA-AGENT/xtts
sudo ./bootstrap.sh --upgrade-driver
sudo reboot
nvidia-smi                 # zeigt den neuen Treiber und eine CUDA-Version >= 12.9
docker compose up -d

Das Script trägt NVIDIAs Paketquelle ein und aktualisiert Treiber, Kernelmodul, nvidia-smi und libcuda1 an Ort und Stelle (gleiche Paketnamen, neuere Version). Alte Debian-Teilpakete, die in den neuen aufgegangen sind, werden entfernt. Das NVIDIA-Container-Toolkit bleibt unberührt — würde apt es anfassen wollen, bricht das Script ab, ohne etwas zu ändern. Ebenso, wenn apt keinen sauberen Weg findet; die Paketquelle wird dann wieder entfernt. Whisper und F5-TTS laufen mit dem neuen Treiber weiter (neuere Treiber können ältere CUDA-Versionen).

Wichtig

  • Stimm-Daten (nicht in git): falls von der alten Box noch vorhanden, xtts/voice-id/ (Speaker-Fingerprint) + xtts/voices/ (F5-Referenz) herkopieren. Sonst egal — in der App neu anlegen: Stimme neu enrollen (ohne Fingerprint läuft die Speaker-ID fail-open, alles geht durch) + F5-Voice-Referenz neu hochladen.
  • Voxtral bleibt aus auf der 3060 (braucht ≥16 GB VRAM). Das Default-Profil fährt Whisper (mit dem M0.1-Fix) + F5-TTS + lokales LLM. Voxtral erst mit der 24-GB-Karte: docker compose stop whisper-bridge && docker compose --profile voxtral up -d --build.
  • Erster Start lädt Modelle (mehrere GB via HuggingFace nach xtts/hf-cache
    • xtts/models) — genug Platz (1 TB NVMe ✓) und etwas Geduld.
  • Box im selben Netz wie der RVS (z.B. Rechenzentrum, direkt auf die interne IP statt NAT-Hairpin): in xtts/.env RVS_HOST=<interne-ip> + RVS_SNI=<zert-name> (Name, für den das Caddy-Zert gilt). Ohne das scheitert TLS an tlsv1 alert internal error. Zuhause / normal: RVS_SNI leer lassen.

Verifizieren

nvidia-smi                                   # Host sieht die GPU
docker run --rm --gpus all nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smi   # Container auch
docker logs -f aria-whisper-bridge           # "RVS verbunden" + service_status ready

Lokales LLM von außen nutzen (OpenAI-Endpunkt)

llama-swap spricht OpenAI-kompatibel (/v1/chat/completions, /v1/models). Damit können Fremd-Tools direkt auf das lokale Modell: OpenHands, Continue, Open WebUI, Aider …

Base-URL:  http://<box>:<LLM_OPENAI_PORT>/v1
Modell:    qwen3-8b   (oder ein anderer Key aus llama-swap/config.yaml)
API-Key:   LLM_OPENAI_KEY  (falls gesetzt)

In der .env:

Variable Bedeutung
LLM_OPENAI_BIND 127.0.0.1 = nur diese Maschine (Default, sicher) · 0.0.0.0 = ganzes LAN
LLM_OPENAI_PORT Host-Port (Default 8081)
LLM_OPENAI_KEY API-Key; leer = ohne Authentifizierung

⚠️ LLM_OPENAI_BIND=0.0.0.0 ohne LLM_OPENAI_KEY heißt: jeder im Netz kann das Modell benutzen. Entweder Key setzen oder auf localhost gebunden lassen.

Wo wird was konfiguriert?

  • Port und Erreichbarkeit immer in der .env. Beides ist ein Docker-Port-Mapping und steht beim Container-Start fest — es lässt sich nicht aus der Ferne ändern.
  • API-Key: entweder in der .env oder — wenn dort leer — in der ARIA-Diagnostic unter Compute-Flotte bei der jeweiligen Box. Dort abgelegt landet er auf der Box unter /models/openai_key.json (Rechte 0600).
  • Die .env hat immer Vorrang. Steht LLM_OPENAI_KEY dort, ist das Feld in der Diagnostic schreibgeschützt (🔒-Hinweis).
  • Ein geänderter Key greift, sobald ein Modell das nächste Mal geladen wird (llama-server bekommt ihn per --api-key). Laufendes Modell also einmal entladen lassen (TTL) oder ein anderes Modell anfragen.

Prüfen:

curl -s http://localhost:8081/v1/models                       # ohne Key
curl -s -H "Authorization: Bearer $LLM_OPENAI_KEY" \
     http://localhost:8081/v1/models                          # mit Key

OpenHands (optionales Profil)

OpenHands ist rein optional und liegt in einem eigenen Profil. Wer es nicht in COMPOSE_PROFILES aufführt, bei dem wird der Container gar nicht erst angelegt — das Image wird nicht einmal geladen. Für den normalen ARIA-Betrieb also einfach weglassen:

COMPOSE_PROFILES=voxtral,f5tts,llm docker compose up -d   # ohne OpenHands
COMPOSE_PROFILES=llm,openhands     docker compose up -d   # mit OpenHands

Dann http://<box>:<OPENHANDS_PORT> (Default 3000) öffnen. Das lokale Modell ist schon vorbelegt (OPENHANDS_LLM_BASE_URL, OPENHANDS_LLM_MODEL) und in der Oberfläche änderbar.

Variable Bedeutung
OPENHANDS_BIND 127.0.0.1 (Default) oder 0.0.0.0 fürs LAN
OPENHANDS_PORT Host-Port (Default 3000)
OPENHANDS_LLM_BASE_URL Default http://llama-swap:8080/v1 (Container-intern — nicht der Host-Port)
OPENHANDS_LLM_MODEL Default openai/qwen3-8b

⚠️ OpenHands startet eigene Arbeits-Container und bekommt dafür den Docker-Socket. Das ist faktisch Root-Zugriff auf diese Maschine — wer die Oberfläche erreicht, kann im Zweifel alles auf der Box.

Deshalb bleibt OPENHANDS_BIND auf 127.0.0.1. Von einem anderen Rechner greifst Du per SSH-Tunnel zu, statt den Port ins LAN zu öffnen:

ssh -L 3000:127.0.0.1:3000 user@box     # dann lokal http://localhost:3000

Das kostet nichts und ist die wirksamste Absicherung, solange der Socket durchgereicht wird. Wer echte Isolation braucht: OpenHands in eine eigene VM, oder einen rootless Docker-Daemon als Beiwagen statt des Host-Sockets.

Ohne das Profil ändert sich nichts: Wer nur ARIAs Box fahren will, startet OpenHands gar nicht.