feat(compute): Multi-Node-Aufteilung via Compose-Profile + GPU-Wahl per .env

Die feste "Gamebox" wird zu beliebig vielen Compute-Nodes. Jeder Node startet
ueber COMPOSE_PROFILES nur die Dienste, die er anbieten soll, und pinnt sie per
*_GPU auf bestimmte Grafikkarten.

- xtts/docker-compose.yml: jeder GPU-Dienst hinter einem Profil
  (voxtral/whisper/f5tts/llm); deploy.devices-Block ersetzt durch
  runtime: nvidia + NVIDIA_VISIBLE_DEVICES=${SVC_GPU} (erlaubt auch "0,1");
  NODE_NAME an alle RVS-Dienste.
- xtts/.env.example: COMPOSE_PROFILES, NODE_NAME, VOXTRAL/WHISPER/F5TTS/LLM_GPU
  mit Beschreibungen; Beispiele STT-Box / TTS-Box / LLM-Box / All-in-One.
- README: "Gamebox-Stack" → "Compute-Nodes"; Diagramm, Deploy-Tabelle und
  Setup-Abschnitt auf Multi-Node umgeschrieben.

Stage 1 von 3 (Aufteilung+Config+Docs). Reine Config/Docs, kein Verhaltens-
Risiko: Single-Node mit COMPOSE_PROFILES=voxtral,f5tts,llm laeuft wie bisher.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-09-18 12:14:58 +02:00
co-authored by Claude Opus 4.8
parent 2bd7c747d9
commit e75f1eeb6a
3 changed files with 195 additions and 151 deletions
+72 -50
View File
@@ -35,18 +35,17 @@ ARIA hat zwei Rollen:
│ WebSocket Tunnel │ WebSocket Tunnel
▼ ▼
┌─────────────────────────────────┐
Gamebox (Windows + WSL2)
RTX 3060, Docker Desktop
Compute-Node(s) (NVIDIA GPU)
beliebig viele, je per .env
│ konfiguriert (COMPOSE_PROFILES) │
│ ┌──────────────────────────┐ │
│ │ aria-f5tts-bridge │
│ │ F5-TTS Voice Cloning │ │
│ │ PCM-Streaming an die App │ │
├──────────────────────────┤ │
│ │ aria-whisper-bridge │ │
│ │ Faster-Whisper CUDA │ │
│ │ STT in fast-Echtzeit │ │
│ │ aria-voxtral-bridge Profil: voxtral (Default-STT)
│ │ aria-f5tts-bridge │ │ Profil: f5tts (TTS)
│ │ aria-llm-adapter+swap │ │ Profil: llm (lokales LLM)
│ aria-whisper-bridge │ │ Profil: whisper (STT-Fallback)
│ └──────────────────────────┘ │
Beide teilen ./voices Volume
Aufteilbar: 1 Node pro Dienst
│ ODER All-in-One. GPU per *_GPU. │
│ xtts/docker-compose.yml │
└─────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
@@ -95,12 +94,16 @@ ARIA hat zwei Rollen:
|-----|----|-----|
| RVS | Rechenzentrum | `cd rvs && docker compose up -d` |
| ARIA Brain/Bridge/Diagnostic | Debian 13 VM | `./init.sh && ./aria-setup.sh && docker compose up -d` |
| Gamebox-Stack (F5-TTS + Whisper) | Gamebox (GPU) | `cd xtts && docker compose up -d` |
| Compute-Node(s) (STT/TTS/LLM) | 1..n GPU-Rechner | `cd xtts && cp .env.example .env && docker compose up -d` |
| Satellit(en) 🛰️ (optional) | Fremdes Netz (Büro …) | `cd satellite && cp .env.example .env && docker compose up -d --build` |
| Android App | Stefans Handy | APK installieren (Auto-Update via RVS) |
> Der Gamebox-Stack ist optional: ohne ihn faellt STT auf lokales Whisper (CPU,
> Compute-Nodes sind optional: ohne sie faellt STT auf lokales Whisper (CPU,
> langsamer) zurueck; TTS bleibt aus (ARIA antwortet dann nur als Text).
> Jeder Node startet per `COMPOSE_PROFILES` in seiner `.env` nur die Dienste,
> die er anbieten soll (`voxtral`/`f5tts`/`llm`/`whisper`) — so laesst sich der
> GPU-Stack auf mehrere Maschinen verteilen (STT-Box, TTS-Box, LLM-Box) oder
> als All-in-One auf einer Kiste fahren (`voxtral,f5tts,llm`).
---
@@ -135,8 +138,8 @@ RVS_PORT=443
RVS_TLS=true
RVS_TLS_FALLBACK=true
# Pairing-Token: Verbindet App, Bridge, Diagnostic und Gamebox im gleichen RVS-Room
# MUSS auf allen Geraeten identisch sein (ARIA-VM, Gaming-PC, App)
# Pairing-Token: Verbindet App, Bridge, Diagnostic und Compute-Nodes im gleichen RVS-Room
# MUSS auf allen Geraeten identisch sein (ARIA-VM, Compute-Nodes, App)
RVS_TOKEN= # ./generate-token.sh
```
@@ -304,28 +307,28 @@ Danach wird der Proxy gepatcht:
## Voice Bridge
Die Bridge verbindet die Android App mit ARIA und orchestriert die GPU-Services
auf der Gamebox.
Die Bridge verbindet die Android App mit ARIA und orchestriert die GPU-Dienste
auf den Compute-Nodes.
**Nachrichtenfluss:**
```
Text: App → RVS → Bridge → aria-brain (HTTP)
Audio: App → RVS → Bridge → stt_request (RVS) → whisper-bridge (Gamebox)
→ stt_response → Bridge → aria-brain
Audio: App → RVS → STT-Node (voxtral/whisper) direkt (Streaming)
→ stt_endpoint/stt_stream_done → Bridge → aria-brain
Fallback bei Timeout: lokales faster-whisper (CPU)
Datei: App → RVS → Bridge → /shared/uploads/ → aria-brain (mit Pfad)
aria-brain → Antwort → Bridge → RVS → App
→ xtts_request (RVS) → f5tts-bridge
→ xtts_request (RVS) → f5tts-Node
→ audio_pcm Stream → RVS → App AudioTrack
```
### Features
- **STT primaer remote**: aria-bridge sendet `stt_request` an die Gamebox-Whisper
(faster-whisper CUDA, fast Echtzeit). 45s Timeout, dann Fallback auf lokales
CPU-Whisper. Modell-Wahl in Diagnostic, Hot-Swap via config-Broadcast.
- **TTS via F5-TTS**: aria-f5tts-bridge auf der Gamebox. Voice Cloning mit
- **STT primaer remote**: die App streamt Audio direkt an einen STT-Node
(Voxtral-3B default, faster-whisper Fallback-Profil), fast Echtzeit. Timeout
Fallback auf lokales CPU-Whisper. Modell-Wahl in Diagnostic, Hot-Swap via config.
- **TTS via F5-TTS**: aria-f5tts-bridge auf einem Compute-Node. Voice Cloning mit
Referenz-Audio + automatisch transkribiertem Referenz-Text.
- **Text-Cleanup**: `<voice>...</voice>` Tag bevorzugt; Markdown, Code,
Einheiten und URLs werden TTS-gerecht aufbereitet. Dezimalzahlen werden
@@ -486,7 +489,7 @@ Erreichbar unter `http://<VM-IP>:3001`. Teilt das Netzwerk mit der Bridge.
- **Disk-Voll Banner** mit copy-baren Cleanup-Befehlen (safe + aggressiv)
- **Token/Call-Metrics**: pro Claude-Call ein Eintrag in `/data/metrics.jsonl` mit ts + Token-Schaetzung. Gehirn-Tab zeigt 1h/5h/24h/30d-Aggregat plus Progress-Bar gegen Plan-Limit (Pro / Max 5x / Max 20x / Custom). Warn-Schwelle 80%, kritisch 90%.
- **Voice Cloning**: Audio-Samples hochladen, Whisper transkribiert den Ref-Text automatisch
- **Voice Export/Import**: einzelne Stimmen als `.tar.gz` zwischen Gameboxen mitnehmen
- **Voice Export/Import**: einzelne Stimmen als `.tar.gz` zwischen Compute-Nodes mitnehmen
- **Settings Export/Import**: `voice_config.json` + `highlight_triggers.json` als JSON-Bundle
- **Claude Login**: Browser-Terminal zum Einloggen in den Proxy
- **ARIA Live**: read-only Mirror der Claude-Code-Session — alle Tool-Calls + Inputs + Outputs live in einer Monospace-Liste, farbcodiert. **Persistenz**: jeder `agent_stream`-Event wird parallel in `/shared/logs/agent_stream.jsonl` (soft-cap 50 MB) geschrieben, Live-View laedt beim Tab-Oeffnen / Page-Reload die letzten 200 Eintraege — Browser-Standby wirft nichts mehr weg. Plus ⛔ **Not-Aus**-Button der per RVS einen `cancel_request` mit `hard:true` ausloest → aria-bridge ruft den proxy-internen `/cancel-all` Side-Channel → alle Claude-Subprocesses werden sofort gekillt
@@ -515,7 +518,7 @@ Erreichbar unter `http://<VM-IP>:3001`. Teilt das Netzwerk mit der Bridge.
- **Wake-Word waehrend TTS**: Du kannst "Computer" sagen waehrend ARIA noch redet — AcousticEchoCanceler verhindert dass ARIAs eigene Stimme das Wake-Word triggert
- **Anruf-Pause + Auto-Resume**: TTS verstummt bei klassischem Anruf oder VoIP-Call (WhatsApp/Signal/Discord). Nach dem Auflegen geht ARIA von der **genauen Stelle** weiter wo sie unterbrochen wurde — die App misst die Position vom Wiedergabe-Anfang und nutzt den WAV-Cache der Antwort
- **Speech Gate**: Aufnahme wird verworfen wenn keine Sprache erkannt
- **STT (Speech-to-Text)**: 16kHz mono → Bridge → Gamebox-Whisper (CUDA) → Text im Chat. Fast in Echtzeit.
- **STT (Speech-to-Text)**: 16kHz mono → STT-Node (Voxtral-3B, CUDA) → Text im Chat. Fast in Echtzeit.
- **"ARIA denkt..." Indicator**: Zeigt live den Status vom Core (Denken, Tool, Schreiben) + Abbrechen-Button
- **TTS-Wiedergabe**: F5-TTS PCM-Streaming direkt in AudioTrack mit konfigurierbarem Pre-Roll-Buffer (1.06.0s, Default 3.5s) gegen Gaps bei Render-Pausen
- **Audio-Pause**: Andere Apps (Spotify, YouTube etc.) pausieren komplett waehrend ARIA spricht und kommen erst wieder nach echtem Wiedergabe-Ende
@@ -655,7 +658,7 @@ Der Update-Flow:
App (Mikrofon) → AAC/MP4 Aufnahme → Base64 → RVS → Bridge
Bridge: FFmpeg (16kHz PCM) → Whisper STT → Text → aria-brain
Bridge: STT-Ergebnis → RVS → App (Placeholder wird durch transkribierten Text ersetzt)
aria-brain → Antwort → Bridge → F5-TTS (Gaming-PC) → PCM-Stream → RVS → App
aria-brain → Antwort → Bridge → F5-TTS (Compute-Node) → PCM-Stream → RVS → App
App: AudioTrack MODE_STREAM (nahtlos), Cache als WAV pro Message
```
@@ -797,36 +800,51 @@ cp ARIA-v0.0.3.0.apk ~/ARIA-AGENT/rvs/updates/
---
## Gamebox-Stack — F5-TTS + Whisper (GPU-Services)
## Compute-Nodes — STT / TTS / LLM (GPU-Dienste)
Laeuft auf einem separaten Rechner mit NVIDIA GPU (z.B. Gaming-PC mit RTX 3060).
Verbindet sich ueber RVS mit der ARIA-Infrastruktur — kein VPN noetig, funktioniert
ueber verschiedene Netze hinweg.
Die GPU-Dienste laufen auf einem oder mehreren separaten Rechnern mit NVIDIA GPU.
Jeder **Compute-Node** verbindet sich ueber RVS mit der ARIA-Infrastruktur — kein
VPN noetig, funktioniert ueber verschiedene Netze hinweg. Frueher war das *eine*
feste „Gamebox"; jetzt sind es beliebig viele Nodes, jeder per `.env` konfiguriert.
### Architektur
### Dienste & Profile
Jeder Dienst haengt an einem Compose-Profil. Ein Node startet ueber
`COMPOSE_PROFILES` (in seiner `.env`) nur die Profile, die er anbieten soll:
| Profil | Container | Rolle |
|-----------|------------------------------|-------|
| `voxtral` | aria-voxtral-bridge | Default-STT (Voxtral-Mini-3B, ~9 GB) |
| `whisper` | aria-whisper-bridge | STT-Fallback (faster-whisper CUDA) |
| `f5tts` | aria-f5tts-bridge | TTS (F5-TTS Voice Cloning) |
| `llm` | aria-llama-swap + llm-adapter| Lokales LLM (llama-swap, OpenAI-kompat.) |
### Architektur (Aufteilung auf mehrere Nodes)
```
Gamebox (Windows, RTX 3060, Docker Desktop + WSL2)
├── aria-f5tts-bridge F5-TTS Voice Cloning + RVS-Relay
│ Hoert auf xtts_request, streamt audio_pcm
├── aria-whisper-bridge faster-whisper auf CUDA (float16)
│ Hoert auf stt_request, antwortet mit stt_response
└── ./voices/ Geteilt zwischen beiden:
{name}.wav — Referenz-Audio (~6-10s)
{name}.txt — Referenz-Text (auto via Whisper)
STT-Box COMPOSE_PROFILES=voxtral VOXTRAL_GPU=0
TTS-Box COMPOSE_PROFILES=f5tts F5TTS_GPU=0
LLM-Box COMPOSE_PROFILES=llm LLM_GPU=0
── oder All-in-One ──
Gamebox COMPOSE_PROFILES=voxtral,f5tts,llm VOXTRAL_GPU=1 F5TTS_GPU=0 LLM_GPU=0
↕ RVS (Rechenzentrum, WebSocket Relay)
ARIA-VM
└── aria-bridge: STT primaer remote (45s Timeout, dann lokaler CPU-Fallback)
TTS via xtts_request → audio_pcm Stream
└── aria-bridge: orchestriert TTS/LLM (xtts_request/llm_request),
lauscht passiv auf den STT-Stream App↔STT-Node.
STT-Timeout → lokaler CPU-Whisper-Fallback.
```
### Voraussetzungen
Die STT-Node teilt sich das `./voices/`-Volume mit F5-TTS nur, wenn beide auf
demselben Node laufen (Referenz-Text-Transkription beim Voice-Upload). Auf
getrennten Nodes transkribiert F5-TTS ueber den STT-Node via RVS.
- Docker Desktop mit WSL2 (Windows) oder Docker mit NVIDIA Runtime (Linux)
- NVIDIA Container Toolkit
- GPU mit mindestens 6GB VRAM (Whisper-large + F5-TTS gemeinsam)
### Voraussetzungen (pro Node)
- Docker + **NVIDIA Container Toolkit** (registriert die `nvidia`-Runtime — die
Compose nutzt `runtime: nvidia` + `NVIDIA_VISIBLE_DEVICES`).
- Genug VRAM fuer die gewaehlten Profile (Voxtral-3B ~9 GB, F5-TTS ~1 GB, LLM je Modell).
- **Gleicher RVS_TOKEN wie auf der ARIA-VM!**
### Setup
@@ -834,13 +852,17 @@ ARIA-VM
```bash
cd xtts
cp .env.example .env
# .env mit RVS-Verbindungsdaten fuellen (gleicher Token wie ARIA-VM!)
# .env anpassen:
# COMPOSE_PROFILES → welche Dienste dieser Node fahren soll
# NODE_NAME → Name des Rechners (erscheint in Diagnostic + Logs)
# *_GPU → welche Grafikkarte pro Dienst (NVIDIA_VISIBLE_DEVICES)
# RVS_* → gleiche Verbindungsdaten wie die ARIA-VM
docker compose up -d
# Erster Start laedt die Modelle (Whisper ~1-3GB je nach Groesse, F5-TTS ~1GB)
# Erster Start laedt die Modelle der aktiven Profile (Voxtral ~9GB, F5-TTS ~1GB)
```
Die Modelle werden in den Volumes `f5tts-models` und `whisper-models` gecacht
und muessen nur einmal geladen werden.
Die Modelle liegen im Bind-Mount `./hf-cache/` (bzw. `./models/` fuer LLM-GGUFs)
und muessen pro Node nur einmal geladen werden.
### Features
@@ -862,7 +884,7 @@ In der Diagnostic unter Einstellungen → Sprachausgabe:
- **TTS aktiv**: Global An/Aus
- **F5-TTS Stimme**: Default oder gecloned (Maia etc.)
> F5-TTS ist die einzige Engine — wenn die Gamebox offline ist, bleibt ARIA stumm.
> F5-TTS ist die einzige Engine — wenn kein f5tts-Node online ist, bleibt ARIA stumm.
> Chat-Antworten kommen weiter an (nur kein Audio).
### Stimme klonen
+34 -3
View File
@@ -1,11 +1,42 @@
# ════════════════════════════════════════════════
# ARIA XTTS v2 — Konfiguration
# Kopieren nach .env und anpassen
# ARIA Compute-Node — Konfiguration
# Kopieren nach .env und anpassen (pro Worker-Node eine eigene .env)
# ════════════════════════════════════════════════
# RVS Verbindung (gleiche Daten wie auf der ARIA-VM)
# ─── Welche Dienste startet DIESER Node? ──────────
# Komma-getrennt aus: voxtral, whisper, f5tts, llm
# Nur die aufgefuehrten Dienste starten bei `docker compose up -d`.
# nur STT-Box → COMPOSE_PROFILES=voxtral
# nur TTS-Box → COMPOSE_PROFILES=f5tts
# nur LLM-Box → COMPOSE_PROFILES=llm
# All-in-One (alte Gamebox) → COMPOSE_PROFILES=voxtral,f5tts,llm
# Hinweis: voxtral UND whisper zusammen NICHT sinnvoll — beide sind STT und
# wuerden dieselbe Anfrage doppelt beantworten. Whisper ist der Fallback.
COMPOSE_PROFILES=voxtral,f5tts,llm
# ─── Node-Name ────────────────────────────────────
# Freier Name dieses Rechners. Erscheint in Diagnostic (Flotten-Anzeige) und
# in den Logs, und bildet die Instanz-ID der Dienste (z.B. f5tts@gamebox).
NODE_NAME=gamebox
# ─── GPU-Zuordnung pro Dienst ─────────────────────
# Setzt NVIDIA_VISIBLE_DEVICES fuer den jeweiligen Container.
# Einzelne Karte → "0" oder "1"; mehrere Karten → "0,1".
# Braucht das NVIDIA Container Toolkit (registriert die `nvidia`-Runtime).
VOXTRAL_GPU=1 # STT-3B ~9 GB → am besten die groessere Karte (z.B. 12 GB)
WHISPER_GPU=1 # Fallback-STT (nur relevant mit Profil "whisper")
F5TTS_GPU=0 # TTS ist klein → passt auf die kleinere Karte
LLM_GPU=0 # lokales LLM (teilt sich ggf. die Karte mit F5-TTS)
# ─── RVS-Verbindung (gleiche Daten wie auf der ARIA-VM) ───
RVS_HOST=mobil.hacker-net.de
RVS_PORT=444
RVS_TLS=true
RVS_TLS_FALLBACK=true
RVS_TOKEN=dein_token_hier
# ─── Optional ─────────────────────────────────────
# HF_TOKEN= # nur falls ein HF-gated Modell (z.B. Voxtral) geladen wird
# WHISPER_MODEL=small # tiny|base|small|medium|large-v3 (Hot-Swap via Diagnostic)
# WHISPER_LANGUAGE=de
# LLM_MODEL=qwen3-8b # Key aus llama-swap/config.yaml
+89 -98
View File
@@ -1,45 +1,50 @@
# ════════════════════════════════════════════════
# ARIA Gamebox Stack — GPU F5-TTS + Whisper STT
# Laeuft auf dem Gaming-PC (RTX 3060)
# Verbindet sich zum RVS fuer TTS/STT-Requests
# ARIA Compute-Node — GPU-Dienste (STT / TTS / LLM)
#
# FLUX-Bildgenerierung liegt im /flux Verzeichnis im Repo-Root —
# eigener Compose-Stack, kann auch auf einer anderen Maschine laufen.
# KEINE feste "Gamebox" mehr: dieser Stack laeuft auf beliebig vielen
# Worker-Nodes. Jeder Node startet ueber COMPOSE_PROFILES nur die Dienste,
# die er anbieten soll, und pinnt sie per *_GPU auf bestimmte Grafikkarten.
# Alles verbindet sich ueber RVS mit der ARIA-Infrastruktur — kein VPN.
#
# Beispiele (in der jeweiligen .env):
# STT-Box → COMPOSE_PROFILES=voxtral
# TTS-Box → COMPOSE_PROFILES=f5tts
# LLM-Box → COMPOSE_PROFILES=llm
# All-in-One → COMPOSE_PROFILES=voxtral,f5tts,llm (die alte Gamebox)
#
# FLUX-Bildgenerierung liegt im /flux Verzeichnis — eigener Stack.
# ════════════════════════════════════════════════
#
# Voraussetzungen:
# - Docker Desktop mit WSL2
# - NVIDIA Container Toolkit
# - .env mit RVS-Verbindungsdaten
# - Docker + NVIDIA Container Toolkit (registriert die `nvidia`-Runtime)
# - .env mit RVS-Verbindungsdaten, COMPOSE_PROFILES, NODE_NAME, *_GPU
#
# Start: docker compose up -d
# Start: docker compose up -d (liest COMPOSE_PROFILES aus der .env)
# ════════════════════════════════════════════════
services:
# ─── F5-TTS Bridge (GPU) ──────────────────────
# Ersetzt den frueheren XTTS-Stack. Empfaengt xtts_request via RVS,
# rendert via F5-TTS mit Voice-Cloning, streamt PCM an die App.
# Voice-Upload: speichert WAV und laesst whisper-bridge den Referenz-
# text transkribieren — der User muss nichts eintippen.
# Empfaengt xtts_request via RVS, rendert via F5-TTS mit Voice-Cloning,
# streamt PCM an die App. Voice-Upload: speichert WAV und laesst eine
# STT-Bridge den Referenztext transkribieren — der User tippt nichts.
f5tts-bridge:
build: ./f5tts
container_name: aria-f5tts-bridge
deploy:
resources:
reservations:
devices:
- driver: nvidia
device_ids: ["0"] # TTS → GPU 0 (8 GB; F5 ist klein)
capabilities: [gpu]
profiles: ["f5tts"] # startet nur mit COMPOSE_PROFILES=…f5tts…
runtime: nvidia
volumes:
- ./voices:/voices # WAV + TXT Referenz
- ./hf-cache:/root/.cache/huggingface # HF-Cache als Bind-Mount.
# Direkt sichtbar im xtts/hf-cache/,
# einfach manuell zu loeschen, kein
# Docker-Desktop .vhdx Bloat.
# Wird mit whisper-bridge geteilt.
# Wird mit STT-Bridges geteilt.
environment:
# GPU-Wahl: NVIDIA_VISIBLE_DEVICES (mehrere via "0,1"). Default GPU 0.
- NVIDIA_VISIBLE_DEVICES=${F5TTS_GPU:-0}
- NVIDIA_DRIVER_CAPABILITIES=compute,utility
- NODE_NAME=${NODE_NAME:-node} # erscheint in Diagnostic + Logs
# Bootstrap-only — alle anderen F5-TTS-Settings (Modell, cfg_strength,
# nfe_step, Custom-Checkpoint) kommen ueber Diagnostic via RVS-config.
- RVS_HOST=${RVS_HOST}
@@ -51,27 +56,22 @@ services:
- VOICES_DIR=/voices
restart: unless-stopped
# ─── Whisper STT (GPU) ────────────────────────
# Faster-Whisper auf der Gamebox statt auf der VM (CPU) —
# deutlich schneller. Verbindet sich selbst per WebSocket an
# den RVS und nimmt dort stt_request Nachrichten der aria-bridge
# entgegen, antwortet mit stt_response. Zusaetzlich nutzt die
# f5tts-bridge Whisper intern fuer die Referenz-Transkription bei
# Voice-Uploads. Laedt das Modell beim Start vor; auf Config-
# Broadcasts (Diagnostic → whisperModel) wird zur Laufzeit hot-
# swapped.
# ─── Whisper STT (GPU) — opt-in Fallback-STT ──
# Faster-Whisper auf CUDA. Verbindet sich selbst per WebSocket an den RVS
# und nimmt stt_request / stt_stream_* Nachrichten entgegen. Zusaetzlich
# nutzt die f5tts-bridge Whisper intern fuer die Referenz-Transkription bei
# Voice-Uploads. Modell-Hot-Swap via Diagnostic (config-Broadcast).
# Nur EINEN STT-Provider pro Node laufen lassen (voxtral ODER whisper) —
# sonst beantworten beide dieselbe Anfrage doppelt.
whisper-bridge:
build: ./whisper
container_name: aria-whisper-bridge
profiles: ["whisper"] # Fallback-STT — startet nur mit --profile whisper
deploy:
resources:
reservations:
devices:
- driver: nvidia
device_ids: ["1"] # STT/groesstes Modell → GPU 1 (12 GB; spaeter Voxtral-STT-3B ~9 GB)
capabilities: [gpu]
profiles: ["whisper"] # startet nur mit COMPOSE_PROFILES=…whisper
runtime: nvidia
environment:
- NVIDIA_VISIBLE_DEVICES=${WHISPER_GPU:-1}
- NVIDIA_DRIVER_CAPABILITIES=compute,utility
- NODE_NAME=${NODE_NAME:-node}
- RVS_HOST=${RVS_HOST}
- RVS_PORT=${RVS_PORT:-443}
- RVS_TLS=${RVS_TLS:-true}
@@ -91,74 +91,22 @@ services:
# Container-Restarts.
restart: unless-stopped
# ─── Lokales LLM (Plan B, B0.5) — llama-swap (GPU) ────────────
# llama-swap laedt/swappt mehrere Modelle on-demand (nur eins passt gleich-
# zeitig in die 12 GB). Welches geladen wird, bestimmt das `model`-Feld im
# Request — das Brain schickt es aus local_llm.json mit. Erster Load eines
# Modells zieht das GGUF via -hf von HF (Cache unter /models, persistent).
# OpenAI-kompatibel auf :8080, nur im Compose-Netz; die Bruecke macht der
# llm-adapter. Modell-Liste: ./llama-swap/config.yaml.
#
# BLIND GEBAUT (kein Gamebox-Test hier): beim ersten Start
# `docker logs -f aria-llama-swap` pruefen. Image bundelt llama-server.
llama-swap:
image: ghcr.io/mostlygeek/llama-swap:unified-cuda
container_name: aria-llama-swap
deploy:
resources:
reservations:
devices:
- driver: nvidia
device_ids: ["0"] # LLM → GPU 0 (8 GB, teilt sich mit TTS)
capabilities: [gpu]
volumes:
- ./models:/models # HF-Download-Cache (persistent)
- ./llama-swap/config.yaml:/app/config.yaml:ro # Modell-Liste
environment:
- LLAMA_CACHE=/models # llama-server legt -hf-Downloads hier ab
command: ["--config", "/app/config.yaml", "--listen", "0.0.0.0:8080"]
restart: unless-stopped
# ─── Local-LLM-Adapter — RVS <-> llama.cpp (Plan B, B0) ──────
# Verbindet sich per Token an den RVS (wie f5tts/whisper), nimmt
# llm_request entgegen, ruft llama.cpp lokal, antwortet llm_response.
llm-adapter:
build: ./llm-adapter
container_name: aria-llm-adapter
depends_on:
- llama-swap
environment:
- RVS_HOST=${RVS_HOST}
- RVS_PORT=${RVS_PORT:-443}
- RVS_TLS=${RVS_TLS:-true}
- RVS_TLS_FALLBACK=${RVS_TLS_FALLBACK:-true}
- RVS_TOKEN=${RVS_TOKEN}
- LLAMA_URL=http://llama-swap:8080
- LLM_MODEL=${LLM_MODEL:-qwen3-8b}
# Erster Load eines Modells kann ein GGUF ziehen (mehrere GB) — grosszuegig.
- LLM_TIMEOUT_SEC=${LLM_TIMEOUT_SEC:-600}
restart: unless-stopped
# ─── Voxtral STT-3B (Transformers, GPU) — DEFAULT-STT ─────────
# Ersetzt whisper als STT. Laeuft auf Treiber 550/CUDA 12.4 (torch cu124, KEIN
# Treiber-Upgrade noetig). Modell Voxtral-Mini-3B-2507 (~9 GB bf16) → GPU 1.
# Startet bei jedem `docker compose up -d`. Whisper ist der opt-in Fallback
# (Profil "whisper") — beide zusammen wuerden stt_* doppelt beantworten, also
# immer nur EINEN STT laufen lassen.
# Voxtral-Mini-3B-2507 (~9 GB bf16). Laeuft auf Treiber 550/CUDA 12.4
# (torch cu124, KEIN Treiber-Upgrade noetig). Whisper ist der opt-in
# Fallback — immer nur EINEN STT-Provider pro Node aktiv haben.
voxtral-bridge:
build: ./voxtral
container_name: aria-voxtral-bridge
deploy:
resources:
reservations:
devices:
- driver: nvidia
device_ids: ["1"] # 12-GB-Karte (STT-3B ~9 GB); GPU 0 (8 GB) bleibt fuer F5/LLM
capabilities: [gpu]
profiles: ["voxtral"] # startet nur mit COMPOSE_PROFILES=…voxtral…
runtime: nvidia
volumes:
- ./hf-cache:/root/.cache/huggingface # gleicher Modell-Cache wie whisper/f5
- ./voice-id:/voice-id # Speaker-Fingerprint (wie whisper)
environment:
- NVIDIA_VISIBLE_DEVICES=${VOXTRAL_GPU:-1} # STT-3B ~9 GB → 12-GB-Karte
- NVIDIA_DRIVER_CAPABILITIES=compute,utility
- NODE_NAME=${NODE_NAME:-node}
- RVS_HOST=${RVS_HOST}
- RVS_PORT=${RVS_PORT:-443}
- RVS_TLS=${RVS_TLS:-true}
@@ -169,3 +117,46 @@ services:
- HUGGING_FACE_HUB_TOKEN=${HF_TOKEN:-} # falls das Modell HF-gated ist
- PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True # weniger VRAM-Fragmentierung
restart: unless-stopped
# ─── Lokales LLM — llama-swap (GPU) ───────────
# llama-swap laedt/swappt mehrere Modelle on-demand. Welches geladen wird,
# bestimmt das `model`-Feld im Request (Brain schickt es aus local_llm.json).
# Erster Load zieht das GGUF via -hf von HF (Cache unter /models, persistent).
# OpenAI-kompatibel auf :8080, nur im Compose-Netz; die Bruecke macht der
# llm-adapter. Modell-Liste: ./llama-swap/config.yaml.
llama-swap:
image: ghcr.io/mostlygeek/llama-swap:unified-cuda
container_name: aria-llama-swap
profiles: ["llm"] # startet nur mit COMPOSE_PROFILES=…llm…
runtime: nvidia
volumes:
- ./models:/models # HF-Download-Cache (persistent)
- ./llama-swap/config.yaml:/app/config.yaml:ro # Modell-Liste
environment:
- NVIDIA_VISIBLE_DEVICES=${LLM_GPU:-0}
- NVIDIA_DRIVER_CAPABILITIES=compute,utility
- LLAMA_CACHE=/models # llama-server legt -hf-Downloads hier ab
command: ["--config", "/app/config.yaml", "--listen", "0.0.0.0:8080"]
restart: unless-stopped
# ─── Local-LLM-Adapter — RVS <-> llama.cpp ────
# Verbindet sich per Token an den RVS (wie f5tts/whisper), nimmt llm_request
# entgegen, ruft llama.cpp lokal, antwortet llm_response.
llm-adapter:
build: ./llm-adapter
container_name: aria-llm-adapter
profiles: ["llm"]
depends_on:
- llama-swap
environment:
- NODE_NAME=${NODE_NAME:-node}
- RVS_HOST=${RVS_HOST}
- RVS_PORT=${RVS_PORT:-443}
- RVS_TLS=${RVS_TLS:-true}
- RVS_TLS_FALLBACK=${RVS_TLS_FALLBACK:-true}
- RVS_TOKEN=${RVS_TOKEN}
- LLAMA_URL=http://llama-swap:8080
- LLM_MODEL=${LLM_MODEL:-qwen3-8b}
# Erster Load eines Modells kann ein GGUF ziehen (mehrere GB) — grosszuegig.
- LLM_TIMEOUT_SEC=${LLM_TIMEOUT_SEC:-600}
restart: unless-stopped