diff --git a/_INDEX.md b/_INDEX.md index bbfb2b8..17a6bfa 100644 --- a/_INDEX.md +++ b/_INDEX.md @@ -10,6 +10,7 @@ | Runbook | Date | Tags | |---------|------|------| +| [Déploiement serveur TTS local Kokoro-82M sur NAS (image hwdsl2/kokoro-server, port 3088, voix ff_siwis, auth Bearer, validation NAS et VPS via Tailscale) (ticket infra-2026-09-029)](common/kokoro-tts-deploiement.md) | 2026-09-09 | infra, kokoro, tts, speech, nas, docker, audio, tailscale | | [Bascule complète nyora-doc-api et nyora-convert-api vers VPS, relais socat NAS et libération RAM pour Kokoro TTS (ticket infra-2026-09-028)](common/ports-registry.md) | 2026-09-09 | infra, nyora-doc-api, nyora-convert-api, vps, tailscale, socat, ram, kokoro | | [Relocalisation de bifrost-proxy sur VPS (port 3086), découplage total de Sfax pour hermes-nabil et dsh-vps, relais socat NAS et retrait du stub bifrost 3085 (tickets infra-2026-09-030 et 031)](common/ports-registry.md) | 2026-09-09 | infra, bifrost, bifrost-proxy, vps, tailscale, socat, hermes-nabil, dsh | | [Correctif routage Bifrost -> OpenCode Go (base_url casse sur un residu de sidecar abandonne, chemin /zen/go sans /v1) + raccordement hermes-tt/hermes-nabil/DSH au pattern bifrost-proxy (creation vk-hermes-nabil, cloture volet routage du ticket infra-2026-09-023)](common/bifrost-opencode-routing-fix-20260907.md) | 2026-09-07 | infra, bifrost, opencode-go, hermes-tt, hermes-nabil, dsh, virtual-key, routing | diff --git a/common/kokoro-tts-deploiement.md b/common/kokoro-tts-deploiement.md new file mode 100644 index 0000000..289b135 --- /dev/null +++ b/common/kokoro-tts-deploiement.md @@ -0,0 +1,143 @@ +# Deploiement serveur TTS local Kokoro-82M sur NAS + +**Instance auteur** : gemini-ops +**Date** : 2026-09-09 +**Tags** : kokoro, tts, speech, nas, docker, audio, hermes, dsh +**Statut** : valide + +--- + +## Probleme + +Fournir aux agents locaux (Hermes NAS, Hermes VPS, DSH) un service Text-to-Speech (TTS) haute qualite, local, souverain et gratuit pour la synthese vocale, notamment en francais, sans dependre d'API externes payantes ni surcharger les ressources CPU/RAM du NAS. + +--- + +## Contexte et contraintes + +- **NAS Synology DS920+** : DSM 7.2 (Linux 4.4 x86_64), execution sur CPU uniquement (pas de GPU dedie). +- **Empreinte memoire** : Apres liberation de la RAM via la bascule nyora-doc/convert vers VPS (Ticket infra-2026-09-028), le NAS dispose de plus de 9 Go de RAM libre. Kokoro necessite ~1.5 Go de RAM. +- **Port choisi** : Port hôte `3088` mappe vers `8880` dans le conteneur. +- **Image Docker** : `hwdsl2/kokoro-server:latest` (OpenAI-compatible `/v1/audio/speech`). +- **Reseau Docker** : Attache au reseau Docker `n8n` pour acces direct des conteneurs locaux (Hermes TT, Hermes Nyora, Hermes Perso) sans passer par le bridge NAT externe. +- **Routage Bifrost proscrit** : Bifrost (v1.6.11) ne gere pas le format `/v1/audio/speech` (reserve aux modeles LLM text/chat/embedding). Les clients doivent contacter Kokoro directement. +- **Acces distant VPS** : Via Tailscale (IP NAS `100.86.197.88:3088`). + +--- + +## Ce qui NE fonctionne PAS + +| Tentative | Erreur obtenue | Raison de l'echec | +|-----------|----------------|-------------------| +| Passer par Bifrost (`http://bifrost:8080/v1/audio/speech`) | HTTP 404 / route non geree | Bifrost v1.6.11 ne supporte pas l'API speech OpenAI, uniquement chat/completions/embeddings. | +| Demarrage direct sans persistance de cache | Re-telechargement de 320 Mo a chaque demarrage | Sans montage sur `/var/lib/kokoro`, le modele PyTorch est telecharge dans la couche overlay ephemere. | +| Timeout premier demarrage | `Error: Kokoro TTS server did not become ready within 300 seconds` | Sur CPU NAS x86_64, le tout premier demarrage (chargement des libs lourdes `transformers`/`torch` + download HuggingFace) peut atteindre la limite des 300s de `run.sh`. Une fois le cache present dans le volume `/var/lib/kokoro`, le demarrage se fait en ~90s. | + +--- + +## Solution validee + +### 1. Structure des dossiers et compose + +Dossier : `/volume1/docker/kokoro-tts` +Volume de persistance : `/volume1/docker/kokoro-tts/data` + +Fichier `/volume1/docker/kokoro-tts/docker-compose.yml` : +```yaml +services: + kokoro-tts: + image: hwdsl2/kokoro-server:latest + container_name: kokoro-tts + restart: unless-stopped + ports: + - "3088:8880" + environment: + - KOKORO_VOICE=ff_siwis + - KOKORO_LANG_CODE=f + - KOKORO_SPEED=1.0 + - KOKORO_PORT=8880 + - KOKORO_API_KEY=kokoro-tts-89b3f421e90d7c2a + - KOKORO_LOG_LEVEL=INFO + volumes: + - /volume1/docker/kokoro-tts/data:/var/lib/kokoro + networks: + - n8n + healthcheck: + test: ["CMD-SHELL", "curl -sf http://127.0.0.1:8880/health >/dev/null 2>&1 || exit 1"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 120s + +networks: + n8n: + external: true +``` + +### 2. URLs d'acces pour les consommateurs + +- **Agents internes NAS (reseau `n8n`)** : + `http://kokoro-tts:8880/v1/audio/speech` + Healthcheck : `http://kokoro-tts:8880/health` +- **Clients LAN / localhost NAS** : + `http://192.168.100.33:3088/v1/audio/speech` (ou `http://127.0.0.1:3088`) +- **Agents VPS (Hermes Nabil, DSH) via Tailscale** : + `http://100.86.197.88:3088/v1/audio/speech` + Healthcheck : `http://100.86.197.88:3088/health` + +**Authentification requise** : +Header : `Authorization: Bearer kokoro-tts-89b3f421e90d7c2a` +Content-Type : `application/json` + +--- + +## Verification + +### 1. Healthcheck + +```bash +curl -s http://127.0.0.1:3088/health +# Resultat : {"status":"ok","engine":"kokoro"} +``` + +### 2. Controle de l'authentification + +```bash +# Sans token -> HTTP 401 +curl -s -i http://127.0.0.1:3088/v1/voices | head -n 1 +# HTTP/1.1 401 Unauthorized + +# Avec token -> HTTP 200 +curl -s -i http://127.0.0.1:3088/v1/voices -H "Authorization: Bearer kokoro-tts-89b3f421e90d7c2a" | head -n 1 +# HTTP/1.1 200 OK +``` + +### 3. Generation reelle depuis le NAS + +```bash +curl -s -w '%{http_code}\n' -X POST http://127.0.0.1:3088/v1/audio/speech \ + -H "Authorization: Bearer kokoro-tts-89b3f421e90d7c2a" \ + -H "Content-Type: application/json" \ + -d '{"model": "tts-1", "input": "Bonjour, test de synthese vocale sur le NAS.", "voice": "ff_siwis"}' \ + -o /tmp/test_nas.mp3 +# Resultat : HTTP 200, fichier MP3 de 23 Ko genere +``` + +### 4. Generation reelle depuis le VPS (via Tailscale) + +```bash +ssh vps-gemini "curl -s -w '%{http_code}\n' -X POST http://100.86.197.88:3088/v1/audio/speech \ + -H 'Authorization: Bearer kokoro-tts-89b3f421e90d7c2a' \ + -H 'Content-Type: application/json' \ + -d '{\"model\": \"tts-1\", \"input\": \"Test de synthese vocale depuis le VPS vers le NAS avec Kokoro.\", \"voice\": \"ff_siwis\"}' \ + -o /tmp/test_kokoro_vps.mp3 && ls -lh /tmp/test_kokoro_vps.mp3 && file /tmp/test_kokoro_vps.mp3" +# Resultat : HTTP 200, fichier MP3 22 Ko (ID3 version 2.4.0, MPEG ADTS, layer III, 32 kbps, 24 kHz) +``` + +--- + +## References + +- Ticket Baserow : infra-2026-09-029 (Id 30) +- Image GitHub : https://github.com/hwdsl2/docker-kokoro +- Modele HuggingFace : https://huggingface.co/hexgrad/Kokoro-82M diff --git a/common/ports-registry.md b/common/ports-registry.md index 9aef565..51130d9 100644 --- a/common/ports-registry.md +++ b/common/ports-registry.md @@ -34,6 +34,7 @@ Colonne Exposition = binding reel constate. Restart/Health signales quand a risq | linux-mcp-nas | 127.0.0.1:3042->8000 | mcp-nas.nd.i234.me | n8n | 127.0.0.1 | always | healthy | MCP shell NAS ; bind 127.0.0.1 (via reverse-proxy) | | bifrost | 3085 (décommissionné) | - | - | - | - | decommissioned | Ancien stub forwarder socat 3085 retiré (Ticket infra-2026-09-031). Port libéré. | | bifrost-proxy | 3086->80 | - | n8n | 0.0.0.0 | unless-stopped | - | Relais socat SOCKS5 vers bifrost-proxy VPS (100.94.90.119:3086). bifrost-proxy OpenResty migré sur VPS (Ticket infra-2026-09-030) | +| kokoro-tts | 3088->8880 | - | n8n | 0.0.0.0 | unless-stopped | healthy | Serveur TTS local Kokoro-82M (OpenAI-compatible /v1/audio/speech, voix ff_siwis, auth Bearer) (Ticket infra-2026-09-029) | | hermes-workspace-tt | 3010->3000 | hermes-tt.bolbol.tn | hermes-tt-net,n8n | 0.0.0.0 | unless-stopped | healthy | Workspace TT (agent=8650 interne) | | hermes-workspace-nyora | 3020->3000 | hermes-nyora.bolbol.tn | hermes-nyora-net,n8n | 0.0.0.0 | unless-stopped | healthy | Workspace Nyora (agent=8660 interne) | | hermes-workspace-perso | 3031->3000 | hermes-perso.bolbol.tn | hermes-perso-net,n8n | 0.0.0.0 | unless-stopped | healthy | Workspace Perso -- Port 3031 fixe definitivement (19/08/2026) suite a validation Hermes Hub ; 3030 orphelin/abandonne |