# ════════════════════════════════════════════════ # ARIA Compute-Node — GPU-Dienste (STT / TTS / LLM) # # KEINE feste "AI-Box" 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 AI-Box) # # FLUX-Bildgenerierung liegt im /flux Verzeichnis — eigener Stack. # ════════════════════════════════════════════════ # # Voraussetzungen: # - Docker + NVIDIA Container Toolkit (registriert die `nvidia`-Runtime) # - .env mit RVS-Verbindungsdaten, COMPOSE_PROFILES, NODE_NAME, *_GPU # # Start: docker compose up -d (liest COMPOSE_PROFILES aus der .env) # ════════════════════════════════════════════════ services: # ─── F5-TTS Bridge (GPU) ────────────────────── # 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 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 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} - RVS_PORT=${RVS_PORT:-443} - RVS_TLS=${RVS_TLS:-true} - RVS_TLS_FALLBACK=${RVS_TLS_FALLBACK:-true} - RVS_TOKEN=${RVS_TOKEN} - F5TTS_DEVICE=${F5TTS_DEVICE:-cuda} - VOICES_DIR=/voices restart: unless-stopped # ─── 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"] # 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} - RVS_TLS_FALLBACK=${RVS_TLS_FALLBACK:-true} - RVS_TOKEN=${RVS_TOKEN} - WHISPER_MODEL=${WHISPER_MODEL:-small} - WHISPER_DEVICE=${WHISPER_DEVICE:-cuda} - WHISPER_COMPUTE_TYPE=${WHISPER_COMPUTE_TYPE:-float16} - WHISPER_LANGUAGE=${WHISPER_LANGUAGE:-de} volumes: - ./hf-cache:/root/.cache/huggingface # gleicher Cache wie f5tts-bridge — # ein Modell muss nur einmal pro # Maschine geladen werden, kein # Re-Download bei Container-Restart. - ./voice-id:/voice-id # Speaker-ID-Fingerprint (Stefans # Stimm-Embedding) persistent zwischen # Container-Restarts. restart: unless-stopped # ─── Voxtral STT-3B (Transformers, GPU) — DEFAULT-STT ───────── # 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 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} - RVS_TLS_FALLBACK=${RVS_TLS_FALLBACK:-true} - RVS_TOKEN=${RVS_TOKEN} - VOXTRAL_MODEL=mistralai/Voxtral-Mini-3B-2507 - VOXTRAL_LANGUAGE=${WHISPER_LANGUAGE:-de} - 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. Die Modell-Liste erzeugt der llm-adapter dynamisch aus # ./llama-swap/config.yaml (Basis) + Registry → /models/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-Cache + generierte Config environment: - NVIDIA_VISIBLE_DEVICES=${LLM_GPU:-0} - NVIDIA_DRIVER_CAPABILITIES=compute,utility - LLAMA_CACHE=/models # llama-server legt -hf-Downloads hier ab # Liest die vom llm-adapter generierte Config. Beim allerersten Boot faengt # restart: unless-stopped die Reihenfolge ab, bis der Adapter sie geschrieben hat. command: ["--config", "/models/llama-swap.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. Verwaltet ausserdem # llama-swaps Config (Modelle hinzufuegen/entfernen via llm_provision_model). llm-adapter: build: ./llm-adapter container_name: aria-llm-adapter profiles: ["llm"] runtime: nvidia # nur fuer nvidia-smi (Auslastungs-Monitor) — kein Compute depends_on: - llama-swap volumes: - ./models:/models # generierte Config + Registry + Cache - ./llama-swap:/llamaswap:ro # Basis-Template (config.yaml) environment: - NVIDIA_VISIBLE_DEVICES=all # alle Karten sichtbar (nur nvidia-smi) - NVIDIA_DRIVER_CAPABILITIES=utility # utility = nvidia-smi, KEIN VRAM/Compute - 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} - LLAMA_BASE_CONFIG=/llamaswap/config.yaml - LLAMA_GEN_CONFIG=/models/llama-swap.config.yaml - LLM_REGISTRY=/models/aria_models.json # Erster Load eines Modells kann ein GGUF ziehen (mehrere GB) — grosszuegig. - LLM_TIMEOUT_SEC=${LLM_TIMEOUT_SEC:-600} restart: unless-stopped