fix: HF-Cache zurueck + Banner-Bug + config_request Pattern
Vier Bugs in einem Aufwasch: 1. HF-Cache als Bind-Mount zurueck xtts/hf-cache:/root/.cache/huggingface fuer beide Bridges. War vorher raus, dadurch jedes Container-Restart = ~3GB Whisper-Download + ~1GB F5-TTS-Download. User dachte 5min ist einmalig — ist aber bei jedem Restart. Jetzt: einmal pro Maschine geladen, fertig. 2. Banner zeigte stale "ready" whisper-bridge sendete beim Connect nur dann Status wenn Modell schon geladen war. Sonst blieb der App/Diagnostic Banner auf dem alten "ready" State von vor dem Restart haengen — User sah "bereit" obwohl gerade gar nichts geladen war. Jetzt wird IMMER ein Status broadcast: ready oder loading. 3. config_request Pattern aria-bridge wusste nicht wann Gamebox-Bridges sich (re)connecten. Wenn die nach aria-bridge kamen, verpassten sie den Config-Broadcast und blieben mit Hard-Defaults stehen. Jetzt: whisper- und f5tts-bridge senden beim Connect ein config_request, aria-bridge antwortet mit der persistierten Config (whisperModel, xttsVoice, f5tts*-Felder). 4. RVS ALLOWED_TYPES um config_request erweitert. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
37c5f6c368
commit
744a27cfd1
|
|
@ -1460,6 +1460,17 @@ class ARIABridge:
|
||||||
logger.info("[rvs] whisper-bridge -> %s", state)
|
logger.info("[rvs] whisper-bridge -> %s", state)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
elif msg_type == "config_request":
|
||||||
|
# Eine andere Bridge (whisper/f5tts) bittet um die aktuelle Voice-
|
||||||
|
# Config — passiert wenn sie sich connected, weil sie sonst die
|
||||||
|
# Diagnostic-Settings nicht kennt. Wir broadcasten die persistierte
|
||||||
|
# Config (auch beim normalen Connect von aria-bridge selber, aber
|
||||||
|
# da war eventuell die andere Bridge noch nicht connected).
|
||||||
|
requester = payload.get("service", "?")
|
||||||
|
logger.info("[rvs] config_request von %s — broadcaste Voice-Config", requester)
|
||||||
|
asyncio.create_task(self._broadcast_persisted_config())
|
||||||
|
return
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logger.debug("[rvs] Unbekannter Typ: %s", msg_type)
|
logger.debug("[rvs] Unbekannter Typ: %s", msg_type)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ const ALLOWED_TYPES = new Set([
|
||||||
"voice_preload", "voice_ready",
|
"voice_preload", "voice_ready",
|
||||||
"stt_request", "stt_response",
|
"stt_request", "stt_response",
|
||||||
"service_status",
|
"service_status",
|
||||||
|
"config_request",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Token-Raum: token -> { clients: Set<ws> }
|
// Token-Raum: token -> { clients: Set<ws> }
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
# HuggingFace Model-Cache (Whisper + F5-TTS, geteilt zwischen den
|
||||||
|
# beiden Bridges via Bind-Mount, kann mehrere GB werden)
|
||||||
|
hf-cache/
|
||||||
|
|
||||||
# Voice-Samples (lokal, gehoert nicht ins Repo)
|
# Voice-Samples (lokal, gehoert nicht ins Repo)
|
||||||
voices/
|
voices/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,11 +31,11 @@ services:
|
||||||
capabilities: [gpu]
|
capabilities: [gpu]
|
||||||
volumes:
|
volumes:
|
||||||
- ./voices:/voices # WAV + TXT Referenz
|
- ./voices:/voices # WAV + TXT Referenz
|
||||||
# KEIN HF-Cache-Mount mehr —
|
- ./hf-cache:/root/.cache/huggingface # HF-Cache als Bind-Mount.
|
||||||
# Modell wird beim Start neu
|
# Direkt sichtbar im xtts/hf-cache/,
|
||||||
# gezogen. Diagnostic zeigt
|
# einfach manuell zu loeschen, kein
|
||||||
# "TTS laedt..." Banner bis
|
# Docker-Desktop .vhdx Bloat.
|
||||||
# service_status: ready kommt.
|
# Wird mit whisper-bridge geteilt.
|
||||||
environment:
|
environment:
|
||||||
# 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.
|
||||||
|
|
@ -77,6 +77,9 @@ services:
|
||||||
- WHISPER_DEVICE=${WHISPER_DEVICE:-cuda}
|
- WHISPER_DEVICE=${WHISPER_DEVICE:-cuda}
|
||||||
- WHISPER_COMPUTE_TYPE=${WHISPER_COMPUTE_TYPE:-float16}
|
- WHISPER_COMPUTE_TYPE=${WHISPER_COMPUTE_TYPE:-float16}
|
||||||
- WHISPER_LANGUAGE=${WHISPER_LANGUAGE:-de}
|
- WHISPER_LANGUAGE=${WHISPER_LANGUAGE:-de}
|
||||||
# KEIN HF-Cache-Mount — Whisper-Modell wird beim Start neu gezogen.
|
volumes:
|
||||||
# Wechsel via Diagnostic triggert ebenso Re-Download.
|
- ./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.
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
|
||||||
|
|
@ -615,20 +615,23 @@ async def run_loop(runner: F5Runner) -> None:
|
||||||
# Status-Broadcast: erst loading, dann ready nach erfolgreichem Load.
|
# Status-Broadcast: erst loading, dann ready nach erfolgreichem Load.
|
||||||
# Modell wird hier (nicht ausserhalb der Schleife) gestartet damit
|
# Modell wird hier (nicht ausserhalb der Schleife) gestartet damit
|
||||||
# der Loading-Status auch wirklich uebertragen werden kann.
|
# der Loading-Status auch wirklich uebertragen werden kann.
|
||||||
|
# Plus: config_request damit wir die persistierte Diagnostic-Config
|
||||||
|
# bekommen, falls aria-bridge ihre nicht von alleine sendet.
|
||||||
async def _load_with_status():
|
async def _load_with_status():
|
||||||
if runner.model is not None:
|
if runner.model is not None:
|
||||||
await _broadcast_status(ws, "ready",
|
await _broadcast_status(ws, "ready",
|
||||||
model=runner.model_id,
|
model=runner.model_id,
|
||||||
loadSeconds=runner.last_load_seconds)
|
loadSeconds=runner.last_load_seconds)
|
||||||
return
|
else:
|
||||||
await _broadcast_status(ws, "loading", model=runner.model_id)
|
await _broadcast_status(ws, "loading", model=runner.model_id)
|
||||||
try:
|
try:
|
||||||
await runner.ensure_loaded()
|
await runner.ensure_loaded()
|
||||||
await _broadcast_status(ws, "ready",
|
await _broadcast_status(ws, "ready",
|
||||||
model=runner.model_id,
|
model=runner.model_id,
|
||||||
loadSeconds=runner.last_load_seconds)
|
loadSeconds=runner.last_load_seconds)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
await _broadcast_status(ws, "error", error=str(e)[:200])
|
await _broadcast_status(ws, "error", error=str(e)[:200])
|
||||||
|
await _send(ws, "config_request", {"service": "f5tts"})
|
||||||
asyncio.create_task(_load_with_status())
|
asyncio.create_task(_load_with_status())
|
||||||
|
|
||||||
# TTS-Worker fuer diese Verbindung starten
|
# TTS-Worker fuer diese Verbindung starten
|
||||||
|
|
|
||||||
|
|
@ -220,15 +220,20 @@ async def run_loop(runner: WhisperRunner) -> None:
|
||||||
retry_s = 2
|
retry_s = 2
|
||||||
tls_fallback_tried = False
|
tls_fallback_tried = False
|
||||||
|
|
||||||
# KEIN initialer Preload. Der aria-bridge broadcastet kurz nach
|
# Initialer Status-Broadcast — uebertont alten "ready"-State
|
||||||
# RVS-Connect die persistierte Config (whisperModel) — wir laden
|
# im App/Diagnostic Banner (sonst denkt der User noch alles ist
|
||||||
# erst wenn der drinsteht, sonst wuerde 2x geladen werden
|
# gut von vorher). Wenn Modell schon geladen → ready, sonst
|
||||||
# (small als ENV-Default + dann das echte Modell).
|
# loading mit aktuellem (Default-)Namen.
|
||||||
# Wenn ein stt_request schneller kommt als die Config: ensure_loaded
|
# Plus: config_request an aria-bridge — wir wissen nicht ob
|
||||||
# im Handler greift dann ein und laedt das angeforderte Modell.
|
# sie auch grad reconnected hat oder schon laenger online ist.
|
||||||
if runner.model is not None:
|
async def _initial_handshake():
|
||||||
# Wir sind reconnectet — Modell schon im RAM, einfach 'ready'
|
if runner.model is not None:
|
||||||
asyncio.create_task(_broadcast_status(ws, "ready", model=runner.model_size))
|
await _broadcast_status(ws, "ready", model=runner.model_size)
|
||||||
|
else:
|
||||||
|
await _broadcast_status(ws, "loading", model=runner.model_size or WHISPER_MODEL)
|
||||||
|
# aria-bridge soll uns die persistierte Voice-Config schicken
|
||||||
|
await _send(ws, "config_request", {"service": "whisper"})
|
||||||
|
asyncio.create_task(_initial_handshake())
|
||||||
|
|
||||||
async for raw in ws:
|
async for raw in ws:
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue