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 │ WebSocket Tunnel │ WebSocket Tunnel
▼ ▼ ▼ ▼
┌─────────────────────────────────┐ ┌─────────────────────────────────┐
Gamebox (Windows + WSL2) Compute-Node(s) (NVIDIA GPU)
RTX 3060, Docker Desktop beliebig viele, je per .env
│ konfiguriert (COMPOSE_PROFILES) │
│ ┌──────────────────────────┐ │ │ ┌──────────────────────────┐ │
│ │ aria-f5tts-bridge │ │ │ aria-voxtral-bridge Profil: voxtral (Default-STT)
│ │ F5-TTS Voice Cloning │ │ │ │ aria-f5tts-bridge │ │ Profil: f5tts (TTS)
│ │ PCM-Streaming an die App │ │ │ │ aria-llm-adapter+swap │ │ Profil: llm (lokales LLM)
├──────────────────────────┤ │ │ aria-whisper-bridge │ │ Profil: whisper (STT-Fallback)
│ │ aria-whisper-bridge │ │
│ │ Faster-Whisper CUDA │ │
│ │ STT in fast-Echtzeit │ │
│ └──────────────────────────┘ │ │ └──────────────────────────┘ │
Beide teilen ./voices Volume Aufteilbar: 1 Node pro Dienst
│ ODER All-in-One. GPU per *_GPU. │
│ xtts/docker-compose.yml │ │ xtts/docker-compose.yml │
└─────────────────────────────────┘ └─────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────┐
@@ -95,12 +94,16 @@ ARIA hat zwei Rollen:
|-----|----|-----| |-----|----|-----|
| RVS | Rechenzentrum | `cd rvs && docker compose up -d` | | RVS | Rechenzentrum | `cd rvs && docker compose up -d` |
| ARIA Brain/Bridge/Diagnostic | Debian 13 VM | `./init.sh && ./aria-setup.sh && 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` | | 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) | | 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). > 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=true
RVS_TLS_FALLBACK=true RVS_TLS_FALLBACK=true
# Pairing-Token: Verbindet App, Bridge, Diagnostic und Gamebox im gleichen RVS-Room # Pairing-Token: Verbindet App, Bridge, Diagnostic und Compute-Nodes im gleichen RVS-Room
# MUSS auf allen Geraeten identisch sein (ARIA-VM, Gaming-PC, App) # MUSS auf allen Geraeten identisch sein (ARIA-VM, Compute-Nodes, App)
RVS_TOKEN= # ./generate-token.sh RVS_TOKEN= # ./generate-token.sh
``` ```
@@ -304,28 +307,28 @@ Danach wird der Proxy gepatcht:
## Voice Bridge ## Voice Bridge
Die Bridge verbindet die Android App mit ARIA und orchestriert die GPU-Services Die Bridge verbindet die Android App mit ARIA und orchestriert die GPU-Dienste
auf der Gamebox. auf den Compute-Nodes.
**Nachrichtenfluss:** **Nachrichtenfluss:**
``` ```
Text: App → RVS → Bridge → aria-brain (HTTP) Text: App → RVS → Bridge → aria-brain (HTTP)
Audio: App → RVS → Bridge → stt_request (RVS) → whisper-bridge (Gamebox) Audio: App → RVS → STT-Node (voxtral/whisper) direkt (Streaming)
→ stt_response → Bridge → aria-brain → stt_endpoint/stt_stream_done → Bridge → aria-brain
Fallback bei Timeout: lokales faster-whisper (CPU) Fallback bei Timeout: lokales faster-whisper (CPU)
Datei: App → RVS → Bridge → /shared/uploads/ → aria-brain (mit Pfad) Datei: App → RVS → Bridge → /shared/uploads/ → aria-brain (mit Pfad)
aria-brain → Antwort → Bridge → RVS → App aria-brain → Antwort → Bridge → RVS → App
→ xtts_request (RVS) → f5tts-bridge → xtts_request (RVS) → f5tts-Node
→ audio_pcm Stream → RVS → App AudioTrack → audio_pcm Stream → RVS → App AudioTrack
``` ```
### Features ### Features
- **STT primaer remote**: aria-bridge sendet `stt_request` an die Gamebox-Whisper - **STT primaer remote**: die App streamt Audio direkt an einen STT-Node
(faster-whisper CUDA, fast Echtzeit). 45s Timeout, dann Fallback auf lokales (Voxtral-3B default, faster-whisper Fallback-Profil), fast Echtzeit. Timeout
CPU-Whisper. Modell-Wahl in Diagnostic, Hot-Swap via config-Broadcast. Fallback auf lokales CPU-Whisper. Modell-Wahl in Diagnostic, Hot-Swap via config.
- **TTS via F5-TTS**: aria-f5tts-bridge auf der Gamebox. Voice Cloning mit - **TTS via F5-TTS**: aria-f5tts-bridge auf einem Compute-Node. Voice Cloning mit
Referenz-Audio + automatisch transkribiertem Referenz-Text. Referenz-Audio + automatisch transkribiertem Referenz-Text.
- **Text-Cleanup**: `<voice>...</voice>` Tag bevorzugt; Markdown, Code, - **Text-Cleanup**: `<voice>...</voice>` Tag bevorzugt; Markdown, Code,
Einheiten und URLs werden TTS-gerecht aufbereitet. Dezimalzahlen werden 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) - **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%. - **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 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 - **Settings Export/Import**: `voice_config.json` + `highlight_triggers.json` als JSON-Bundle
- **Claude Login**: Browser-Terminal zum Einloggen in den Proxy - **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 - **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 - **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 - **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 - **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 - **"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 - **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 - **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 App (Mikrofon) → AAC/MP4 Aufnahme → Base64 → RVS → Bridge
Bridge: FFmpeg (16kHz PCM) → Whisper STT → Text → aria-brain Bridge: FFmpeg (16kHz PCM) → Whisper STT → Text → aria-brain
Bridge: STT-Ergebnis → RVS → App (Placeholder wird durch transkribierten Text ersetzt) 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 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). Die GPU-Dienste laufen auf einem oder mehreren separaten Rechnern mit NVIDIA GPU.
Verbindet sich ueber RVS mit der ARIA-Infrastruktur — kein VPN noetig, funktioniert Jeder **Compute-Node** verbindet sich ueber RVS mit der ARIA-Infrastruktur — kein
ueber verschiedene Netze hinweg. 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) STT-Box COMPOSE_PROFILES=voxtral VOXTRAL_GPU=0
├── aria-f5tts-bridge F5-TTS Voice Cloning + RVS-Relay TTS-Box COMPOSE_PROFILES=f5tts F5TTS_GPU=0
│ Hoert auf xtts_request, streamt audio_pcm LLM-Box COMPOSE_PROFILES=llm LLM_GPU=0
├── aria-whisper-bridge faster-whisper auf CUDA (float16) ── oder All-in-One ──
│ Hoert auf stt_request, antwortet mit stt_response Gamebox COMPOSE_PROFILES=voxtral,f5tts,llm VOXTRAL_GPU=1 F5TTS_GPU=0 LLM_GPU=0
└── ./voices/ Geteilt zwischen beiden:
{name}.wav — Referenz-Audio (~6-10s)
{name}.txt — Referenz-Text (auto via Whisper)
↕ RVS (Rechenzentrum, WebSocket Relay) ↕ RVS (Rechenzentrum, WebSocket Relay)
ARIA-VM ARIA-VM
└── aria-bridge: STT primaer remote (45s Timeout, dann lokaler CPU-Fallback) └── aria-bridge: orchestriert TTS/LLM (xtts_request/llm_request),
TTS via xtts_request → audio_pcm Stream 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) ### Voraussetzungen (pro Node)
- NVIDIA Container Toolkit
- GPU mit mindestens 6GB VRAM (Whisper-large + F5-TTS gemeinsam) - 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!** - **Gleicher RVS_TOKEN wie auf der ARIA-VM!**
### Setup ### Setup
@@ -834,13 +852,17 @@ ARIA-VM
```bash ```bash
cd xtts cd xtts
cp .env.example .env 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 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 Die Modelle liegen im Bind-Mount `./hf-cache/` (bzw. `./models/` fuer LLM-GGUFs)
und muessen nur einmal geladen werden. und muessen pro Node nur einmal geladen werden.
### Features ### Features
@@ -862,7 +884,7 @@ In der Diagnostic unter Einstellungen → Sprachausgabe:
- **TTS aktiv**: Global An/Aus - **TTS aktiv**: Global An/Aus
- **F5-TTS Stimme**: Default oder gecloned (Maia etc.) - **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). > Chat-Antworten kommen weiter an (nur kein Audio).
### Stimme klonen ### Stimme klonen
+34 -3
View File
@@ -1,11 +1,42 @@
# ════════════════════════════════════════════════ # ════════════════════════════════════════════════
# ARIA XTTS v2 — Konfiguration # ARIA Compute-Node — Konfiguration
# Kopieren nach .env und anpassen # 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_HOST=mobil.hacker-net.de
RVS_PORT=444 RVS_PORT=444
RVS_TLS=true RVS_TLS=true
RVS_TLS_FALLBACK=true RVS_TLS_FALLBACK=true
RVS_TOKEN=dein_token_hier 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 # ARIA Compute-Node — GPU-Dienste (STT / TTS / LLM)
# Laeuft auf dem Gaming-PC (RTX 3060)
# Verbindet sich zum RVS fuer TTS/STT-Requests
# #
# FLUX-Bildgenerierung liegt im /flux Verzeichnis im Repo-Root — # KEINE feste "Gamebox" mehr: dieser Stack laeuft auf beliebig vielen
# eigener Compose-Stack, kann auch auf einer anderen Maschine laufen. # 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: # Voraussetzungen:
# - Docker Desktop mit WSL2 # - Docker + NVIDIA Container Toolkit (registriert die `nvidia`-Runtime)
# - NVIDIA Container Toolkit # - .env mit RVS-Verbindungsdaten, COMPOSE_PROFILES, NODE_NAME, *_GPU
# - .env mit RVS-Verbindungsdaten
# #
# Start: docker compose up -d # Start: docker compose up -d (liest COMPOSE_PROFILES aus der .env)
# ════════════════════════════════════════════════ # ════════════════════════════════════════════════
services: services:
# ─── F5-TTS Bridge (GPU) ────────────────────── # ─── F5-TTS Bridge (GPU) ──────────────────────
# Ersetzt den frueheren XTTS-Stack. Empfaengt xtts_request via RVS, # Empfaengt xtts_request via RVS, rendert via F5-TTS mit Voice-Cloning,
# rendert via F5-TTS mit Voice-Cloning, streamt PCM an die App. # streamt PCM an die App. Voice-Upload: speichert WAV und laesst eine
# Voice-Upload: speichert WAV und laesst whisper-bridge den Referenz- # STT-Bridge den Referenztext transkribieren — der User tippt nichts.
# text transkribieren — der User muss nichts eintippen.
f5tts-bridge: f5tts-bridge:
build: ./f5tts build: ./f5tts
container_name: aria-f5tts-bridge container_name: aria-f5tts-bridge
deploy: profiles: ["f5tts"] # startet nur mit COMPOSE_PROFILES=…f5tts…
resources: runtime: nvidia
reservations:
devices:
- driver: nvidia
device_ids: ["0"] # TTS → GPU 0 (8 GB; F5 ist klein)
capabilities: [gpu]
volumes: volumes:
- ./voices:/voices # WAV + TXT Referenz - ./voices:/voices # WAV + TXT Referenz
- ./hf-cache:/root/.cache/huggingface # HF-Cache als Bind-Mount. - ./hf-cache:/root/.cache/huggingface # HF-Cache als Bind-Mount.
# Direkt sichtbar im xtts/hf-cache/, # Direkt sichtbar im xtts/hf-cache/,
# einfach manuell zu loeschen, kein # einfach manuell zu loeschen, kein
# Docker-Desktop .vhdx Bloat. # Docker-Desktop .vhdx Bloat.
# Wird mit whisper-bridge geteilt. # Wird mit STT-Bridges geteilt.
environment: 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, # Bootstrap-only — alle anderen F5-TTS-Settings (Modell, cfg_strength,
# nfe_step, Custom-Checkpoint) kommen ueber Diagnostic via RVS-config. # nfe_step, Custom-Checkpoint) kommen ueber Diagnostic via RVS-config.
- RVS_HOST=${RVS_HOST} - RVS_HOST=${RVS_HOST}
@@ -51,27 +56,22 @@ services:
- VOICES_DIR=/voices - VOICES_DIR=/voices
restart: unless-stopped restart: unless-stopped
# ─── Whisper STT (GPU) ──────────────────────── # ─── Whisper STT (GPU) — opt-in Fallback-STT ──
# Faster-Whisper auf der Gamebox statt auf der VM (CPU) — # Faster-Whisper auf CUDA. Verbindet sich selbst per WebSocket an den RVS
# deutlich schneller. Verbindet sich selbst per WebSocket an # und nimmt stt_request / stt_stream_* Nachrichten entgegen. Zusaetzlich
# den RVS und nimmt dort stt_request Nachrichten der aria-bridge # nutzt die f5tts-bridge Whisper intern fuer die Referenz-Transkription bei
# entgegen, antwortet mit stt_response. Zusaetzlich nutzt die # Voice-Uploads. Modell-Hot-Swap via Diagnostic (config-Broadcast).
# f5tts-bridge Whisper intern fuer die Referenz-Transkription bei # Nur EINEN STT-Provider pro Node laufen lassen (voxtral ODER whisper) —
# Voice-Uploads. Laedt das Modell beim Start vor; auf Config- # sonst beantworten beide dieselbe Anfrage doppelt.
# Broadcasts (Diagnostic → whisperModel) wird zur Laufzeit hot-
# swapped.
whisper-bridge: whisper-bridge:
build: ./whisper build: ./whisper
container_name: aria-whisper-bridge container_name: aria-whisper-bridge
profiles: ["whisper"] # Fallback-STT — startet nur mit --profile whisper profiles: ["whisper"] # startet nur mit COMPOSE_PROFILES=…whisper
deploy: runtime: nvidia
resources:
reservations:
devices:
- driver: nvidia
device_ids: ["1"] # STT/groesstes Modell → GPU 1 (12 GB; spaeter Voxtral-STT-3B ~9 GB)
capabilities: [gpu]
environment: environment:
- NVIDIA_VISIBLE_DEVICES=${WHISPER_GPU:-1}
- NVIDIA_DRIVER_CAPABILITIES=compute,utility
- NODE_NAME=${NODE_NAME:-node}
- RVS_HOST=${RVS_HOST} - RVS_HOST=${RVS_HOST}
- RVS_PORT=${RVS_PORT:-443} - RVS_PORT=${RVS_PORT:-443}
- RVS_TLS=${RVS_TLS:-true} - RVS_TLS=${RVS_TLS:-true}
@@ -91,74 +91,22 @@ services:
# Container-Restarts. # Container-Restarts.
restart: unless-stopped 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 ───────── # ─── Voxtral STT-3B (Transformers, GPU) — DEFAULT-STT ─────────
# Ersetzt whisper als STT. Laeuft auf Treiber 550/CUDA 12.4 (torch cu124, KEIN # Voxtral-Mini-3B-2507 (~9 GB bf16). Laeuft auf Treiber 550/CUDA 12.4
# Treiber-Upgrade noetig). Modell Voxtral-Mini-3B-2507 (~9 GB bf16) → GPU 1. # (torch cu124, KEIN Treiber-Upgrade noetig). Whisper ist der opt-in
# Startet bei jedem `docker compose up -d`. Whisper ist der opt-in Fallback # Fallback — immer nur EINEN STT-Provider pro Node aktiv haben.
# (Profil "whisper") — beide zusammen wuerden stt_* doppelt beantworten, also
# immer nur EINEN STT laufen lassen.
voxtral-bridge: voxtral-bridge:
build: ./voxtral build: ./voxtral
container_name: aria-voxtral-bridge container_name: aria-voxtral-bridge
deploy: profiles: ["voxtral"] # startet nur mit COMPOSE_PROFILES=…voxtral…
resources: runtime: nvidia
reservations:
devices:
- driver: nvidia
device_ids: ["1"] # 12-GB-Karte (STT-3B ~9 GB); GPU 0 (8 GB) bleibt fuer F5/LLM
capabilities: [gpu]
volumes: volumes:
- ./hf-cache:/root/.cache/huggingface # gleicher Modell-Cache wie whisper/f5 - ./hf-cache:/root/.cache/huggingface # gleicher Modell-Cache wie whisper/f5
- ./voice-id:/voice-id # Speaker-Fingerprint (wie whisper) - ./voice-id:/voice-id # Speaker-Fingerprint (wie whisper)
environment: 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_HOST=${RVS_HOST}
- RVS_PORT=${RVS_PORT:-443} - RVS_PORT=${RVS_PORT:-443}
- RVS_TLS=${RVS_TLS:-true} - RVS_TLS=${RVS_TLS:-true}
@@ -169,3 +117,46 @@ services:
- HUGGING_FACE_HUB_TOKEN=${HF_TOKEN:-} # falls das Modell HF-gated ist - HUGGING_FACE_HUB_TOKEN=${HF_TOKEN:-} # falls das Modell HF-gated ist
- PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True # weniger VRAM-Fragmentierung - PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True # weniger VRAM-Fragmentierung
restart: unless-stopped 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