skald (engine/kokoro): public release prep — AGPL-3.0, generic config, engine-variant README

This commit is contained in:
Sulkta 2026-06-28 21:38:51 -07:00
parent b5de9776a2
commit 286c53759d
12 changed files with 785 additions and 197 deletions

View file

@ -35,24 +35,23 @@ generalise. Examples:
question intonation, paragraph/scene/breath gap durations tuned
for af_heart's pacing, notes on how respellings need to be all-
lowercase to avoid letter-by-letter spell-out by misaki.
- `engine/tortoise`GPU exclusivity coordinator (stops F5 +
Kokoro before a Tortoise run since the 2070 Super can't host
all three at once), preset choice ergonomics, character→tortoise-
voice seed assignments.
- `engine/tortoise`sentence chunking, device selection, and
pitch/rate modulation tuned for Tortoise's audiobook-quality
output. On an 8GB card Tortoise wants the GPU largely to itself,
so run it when the other engines are stopped.
When deploying an engine to the host, the build dir at
`/srv/appdata/<engine>/build/` tracks the engine's branch:
To deploy a tuned engine, check out the engine's branch in the build
dir and `docker compose up -d --build`:
```bash
cd /srv/appdata/kokoro/build
git fetch && git checkout engine/kokoro
docker compose -p <name> up -d --build
docker compose up -d --build
```
## GPU coordination (2070 Super)
## GPU coordination
The 8GB card is the bottleneck. F5 + Kokoro can co-reside (~5GB +
~1GB). Tortoise pushes the budget over and needs the GPU largely
to itself — the `engine/tortoise` branch will carry the script
that stops kokoro + f5 before a tortoise run and restarts them
after. Replace with proper coordination once we have more VRAM.
On an 8GB card F5 + Kokoro can co-reside (~5GB + ~1GB). Tortoise
pushes the budget over and needs the GPU largely to itself — stop
kokoro + f5 before a Tortoise run and restart them after, or give
Tortoise its own card. Proper multi-engine coordination is left to
the deployment once more VRAM is available.

View file

@ -1,9 +1,6 @@
# Sulkta build of F5-TTS — upstream ghcr.io/swivid/f5-tts:main was
# shipped with torch 2.11/torchaudio 2.4 ABI mismatch on 2026-05-13,
# breaking import torchaudio at boot. We rebuild on a known-good
# pytorch base + pip install f5-tts.
#
# Image tag in localhost-registry: registry.example.local:5000/f5-tts:<ver>
# F5-TTS rebuild on a known-good pytorch base. Upstream
# ghcr.io/swivid/f5-tts:main shipped a torch/torchaudio ABI mismatch
# that broke `import torchaudio` at boot; this image bypasses that.
#
# License: Apache 2.0 (code) / CC-BY-NC (Emilia-trained weights).
# Personal use OK; redistribution gray-area — flagged.
@ -30,12 +27,11 @@ RUN pip install --no-cache-dir 'f5-tts>=1.0.0'
# Pre-warm the HF cache directory.
RUN mkdir -p /cache/hf /audio /voices
COPY f5_server.py /app/f5_server.py
COPY server.py /app/server.py
WORKDIR /app
EXPOSE 7860
# Skald talks to our purpose-built FastAPI server, not Gradio.
# Models load at startup (first request would otherwise pay the
# cold-start cost). uvicorn on :7860 to keep the port stable.
CMD ["uvicorn", "f5_server:app", "--host", "0.0.0.0", "--port", "7860"]
# Purpose-built FastAPI server, not Gradio. Models load at startup
# so the first request doesn't pay the cold-start cost.
CMD ["uvicorn", "server:app", "--host", "0.0.0.0", "--port", "7860"]

View file

@ -1,19 +1,21 @@
# F5-TTS standalone stack on the host.
# F5-TTS sidecar.
#
# License posture (acknowledged 2026-05-13): code is Apache 2.0, but
# the pretrained model weights are CC-BY-NC (Emilia training data).
# Personal listen is fine; public sharing is a flagged gray area.
# Sulkta's call: ship anyway.
# Code is Apache 2.0; pretrained F5TTS_v1_Base weights are CC-BY-NC
# (Emilia training data). Personal use is fine; redistribution is a
# flagged gray area.
#
# Runtime: 8GB GPU is plenty (F5 inference ~4-6GB peak).
# First run downloads ~2GB of model weights from HuggingFace into
# the hf-cache volume; subsequent runs are warm.
#
# First-run cost: ~2GB model download from HuggingFace into hf-cache,
# happens on first inference request. Subsequent runs are warm.
# Set in .env (or override):
# F5_HOST_PORT=7792
# F5_DATA=./data # ${F5_DATA}/hf-cache + voices + audio
name: f5-tts
services:
f5-tts:
image: registry.example.local:5000/f5-tts:0.3
build: .
image: f5-tts:0.3
container_name: f5-tts
restart: unless-stopped
deploy:
@ -24,20 +26,11 @@ services:
count: all
capabilities: [gpu]
ports:
- "127.0.0.1:7792:7860"
- "127.0.0.1:7792:7860"
- "${F5_HOST_PORT:-7792}:7860"
volumes:
# HF model weights cache — persists ~2GB after first download.
- /srv/appdata/f5-tts/hf-cache:/cache/hf
# Reference voice clips (lj_speech.wav, etc).
- /srv/appdata/f5-tts/voices:/voices:ro
# Rendered audio output — skald writes story narrations here.
- /srv/appdata/f5-tts/audio:/audio
- ${F5_DATA:-./data}/hf-cache:/cache/hf
- ${F5_DATA:-./data}/voices:/voices:ro
- ${F5_DATA:-./data}/audio:/audio
environment:
HF_HOME: /cache/hf
HF_HUB_DISABLE_TELEMETRY: "1"
labels:
org.sulkta.domain: "sulkta"
org.sulkta.owner: "Sulkta"
org.sulkta.managed-by: "compose"
org.sulkta.role: "f5-tts"

View file

@ -1,16 +1,18 @@
# Kokoro-82M TTS stack on the host.
# Kokoro-82M TTS sidecar.
#
# Audiobook-quality narrator engine (Apache 2.0 code + weights —
# clean stack vs F5-TTS's CC-BY-NC asterisk). Sibling to f5-tts;
# both share /srv/appdata/f5-tts/audio so skald's audio
# route serves outputs from either engine through the same path.
# Apache 2.0 code AND model weights — clean stack for share/publish.
# Audiobook-quality narrator; F5-TTS stays around for voice-cloning.
#
# License: Apache 2.0 top to bottom. Right for share/publish.
# Set in .env (or override):
# KOKORO_HOST_PORT=7794
# KOKORO_DATA=./data # ${KOKORO_DATA}/hf-cache
# AUDIO_DIR=../f5-tts/data/audio # shared output dir across engines
name: kokoro
services:
kokoro:
image: registry.example.local:5000/kokoro:0.5
build: .
image: kokoro:0.5
container_name: kokoro
restart: unless-stopped
deploy:
@ -21,17 +23,10 @@ services:
count: all
capabilities: [gpu]
ports:
- "127.0.0.1:7794:7860"
- "127.0.0.1:7794:7860"
- "${KOKORO_HOST_PORT:-7794}:7860"
volumes:
- /srv/appdata/kokoro/hf-cache:/cache/hf
# Shared with f5-tts so skald's /audio route covers both.
- /srv/appdata/f5-tts/audio:/audio
- ${KOKORO_DATA:-./data}/hf-cache:/cache/hf
- ${AUDIO_DIR:-./data/audio}:/audio
environment:
HF_HOME: /cache/hf
HF_HUB_DISABLE_TELEMETRY: "1"
labels:
org.sulkta.domain: "sulkta"
org.sulkta.owner: "Sulkta"
org.sulkta.managed-by: "compose"
org.sulkta.role: "kokoro"

View file

@ -1,19 +1,22 @@
# Tortoise-TTS stack on the host. Audiobook-quality engine with 25+
# named voices (no cloning). Apache 2.0 top to bottom.
# Tortoise-TTS sidecar. 25+ named voices, no cloning needed.
# Apache 2.0 top to bottom.
#
# Slow: ~10x kokoro wall clock at 'standard' preset. Worth it for
# the quality bar. Sulkta's call 2026-05-14: "use higgs (now tortoise)
# and we will only let it use the full gpu for runs" — translated:
# runs are batched, slow is acceptable.
# Slow: ~10x kokoro wall-clock at 'standard' preset. Worth it for the
# quality bar; runs are batched.
#
# Co-resides with kokoro on the 2070 Super since tortoise is ~5GB
# and kokoro is ~1GB (8GB total). If OOM hits during a render,
# we'll add a coordination layer to pause kokoro first.
# Co-resides with kokoro on an 8GB card (tortoise ~5GB + kokoro ~1GB).
# OOM during a render: add a coordinator that pauses kokoro first.
#
# Set in .env (or override):
# TORTOISE_HOST_PORT=7795
# TORTOISE_DATA=./data # ${TORTOISE_DATA}/{hf-cache,models}
# AUDIO_DIR=../f5-tts/data/audio # shared output dir across engines
name: tortoise
services:
tortoise:
image: registry.example.local:5000/tortoise:0.1
build: .
image: tortoise:0.1
container_name: tortoise
restart: unless-stopped
deploy:
@ -24,20 +27,12 @@ services:
count: all
capabilities: [gpu]
ports:
- "127.0.0.1:7795:7860"
- "127.0.0.1:7795:7860"
- "${TORTOISE_HOST_PORT:-7795}:7860"
volumes:
- /srv/appdata/tortoise/hf-cache:/cache/hf
- /srv/appdata/tortoise/models:/cache/tortoise-models
# Shared audio dir with f5/kokoro so skald serves all engines'
# outputs through the same /audio route.
- /srv/appdata/f5-tts/audio:/audio
- ${TORTOISE_DATA:-./data}/hf-cache:/cache/hf
- ${TORTOISE_DATA:-./data}/models:/cache/tortoise-models
- ${AUDIO_DIR:-./data/audio}:/audio
environment:
HF_HOME: /cache/hf
HF_HUB_DISABLE_TELEMETRY: "1"
TORTOISE_MODELS_DIR: /cache/tortoise-models
labels:
org.sulkta.domain: "sulkta"
org.sulkta.owner: "Sulkta"
org.sulkta.managed-by: "compose"
org.sulkta.role: "tortoise-tts"