Commit graph

175 commits

Author SHA1 Message Date
timehexon
015bbdfad6 F5-TTS: Whisper-transcribed ref_texts with full punctuation for all 40 cloned voices 2026-05-24 11:34:12 -04:00
960fda4f5c
F5-TTS: sentence-case + period the LibriSpeech ref_texts for cleaner ref-to-gen transition 2026-05-24 11:26:34 -04:00
fc5af2b653
F5-TTS: drop per-sentence split — single infer() call avoids ref-to-gen artifact per chunk 2026-05-24 11:12:57 -04:00
482b17960c
F5-TTS engine consistency sweep (Makefile, startup, README, docs) 2026-05-24 08:24:38 -04:00
2df34f85cc
Add F5-TTS as tts-1-f5 engine (additive, alongside tts-1-qwen) 2026-05-23 13:24:25 -04:00
bfc5260dfc we update gitignore 2026-04-03 14:17:01 -04:00
074cbbd22f style: avoid "the", use "our" — writing style rule + sweep 2026-04-03 14:17:01 -04:00
timehexon
d4d6344326 Replace "AI" with "machine learning" in CLAUDE.md
Machine learning is what we grow. "AI" is forbidden in all
permacomputer discourse, marketing, & documentation.
2026-02-02 19:56:24 +00:00
7e77c3452d Add voices-qwen Makefile target to download cloned voice samples
Runs scripts/download_diverse_voices.py which pulls speaker samples
from LibriSpeech and assigns permanent human names via voice registry.
Works with venv or system python. Also adds Voices section to help.
2026-01-27 17:31:15 -05:00
fox
f58da54fa3 Expand to all 40 test-clean voices with idempotent registry 2026-01-27 15:30:42 -05:00
69d039d1a5 Add datasets and torchcodec to requirements.txt 2026-01-27 15:15:09 -05:00
3f3918fed2 Simplify CLAUDE.md: remove SSH/rsync references, local-only workflow 2026-01-27 13:59:52 -05:00
c3ac2def48 Add idempotent voice registry system for permanent speaker-to-name assignments
- voice_registry.json: append-only registry with 50 name pools per gender,
  locked speaker assignments, and multi-corpus support
- Rewrite download script to be registry-driven: loads registry, assigns
  names deterministically (sorted by speaker ID), never changes existing
  assignments
- Update docs/VOICES.md with registry system documentation
- Support --registry and --corpora CLI flags for multi-corpus downloads
2026-01-27 13:59:39 -05:00
fox
af5c81928d Regenerate voices with upstream-verified genders from SPEAKERS.TXT 2026-01-27 13:22:26 -05:00
35b083ed34 Fetch speaker genders from upstream LibriSpeech SPEAKERS.TXT 2026-01-27 13:17:52 -05:00
b77af6d603 Fix voice gender assignments - verified against LibriSpeech SPEAKERS.TXT 2026-01-27 13:13:07 -05:00
c56b8cb24e Simplify Makefile to run locally, remove all remote SSH/rsync
Remove REMOTE_HOST, REMOTE_USER, REMOTE_PATH, vars.sh loading.
All docker commands use sudo locally. Tests hit localhost:8000.
Delete old non-gendered voice WAV files (alloy, echo, fable, etc).
2026-01-27 12:51:08 -05:00
ebfa0319d1 Replace voices with 21 distinct gendered speakers from LibriSpeech
11 female (aria, clara, elena, grace, hazel, iris, luna, maya, ruby, sage, sofia)
10 male (atlas, caleb, felix, hugo, jasper, kai, leo, marcus, owen, theo)
Each voice is a unique LibriSpeech test-clean speaker for voice cloning diversity.
2026-01-27 12:41:37 -05:00
cd60e31aa2 Use gendered voice names: 11 female + 10 male = 21 distinct voices 2026-01-27 12:07:31 -05:00
4c5b42c062 Mount cloned-voices directory in container 2026-01-27 11:56:17 -05:00
648281cdb6 Update diverse voices script with correct voice names 2026-01-27 11:53:33 -05:00
aa8af56835 Fix remote paths in CLAUDE.md, add tmux-hosts discovery 2026-01-27 09:32:27 -05:00
16b281bab4 Add webm response format (opus in webm container)
Firefox MediaSource API supports audio/webm;codecs=opus but not
audio/ogg. Adding webm format lets Firefox clients use true
streaming playback via MediaSource instead of full buffering.
2026-01-27 09:28:38 -05:00
8f7f1318a1 Split on every sentence for streaming (no combining) 2026-01-26 19:52:41 -05:00
0a0d023517 Fix sentence splitter to split on every sentence boundary
Previous version accumulated sentences until 500 chars, defeating
the purpose of streaming. Now splits on every sentence, only
combining very short sentences (<50 chars) with the next.
2026-01-26 19:41:44 -05:00
802eaf2b29 Add sentence-by-sentence streaming for Qwen TTS
Split text into sentences and stream each as it's generated,
so first audio arrives much faster for long text.
2026-01-26 19:32:51 -05:00
a148088cb0 Fix Qwen TTS deadlock, reduce workers to 1 for GPU
- Fix subprocess deadlock in Qwen TTS by using threading for stdin write
  (prevents pipe buffer deadlock on large audio output)
- Set WORKERS=1 for GPU models to avoid VRAM duplication
  (4 workers × 3GB model = OOM, 1 worker works fine)
- Update CLAUDE.md: use git push/pull instead of rsync for deployment
2026-01-26 19:14:19 -05:00
cac40d75d3 Set default workers to 4 to prevent server lockup 2026-01-26 18:23:51 -05:00
5e5e7936f1 Add 20 cloned voice samples for Qwen3-TTS
LJ Speech samples (public domain) for voice cloning:
- Standard: alloy, echo, fable, onyx, nova, shimmer
- Extended: amber, breeze, coral, dawn, ember, frost,
            glow, haze, ivy, jade, kite, lark, mist, nectar
2026-01-26 17:44:03 -05:00
02b4e7aaf7 Add 20 diverse voice samples for Qwen3-TTS
Standard voices: alloy, echo, fable, onyx, nova, shimmer
Extended voices: amber, breeze, coral, dawn, ember, frost,
                 glow, haze, ivy, jade, kite, lark, mist, nectar

Source: LJ Speech Dataset (public domain)
2026-01-26 16:50:54 -05:00
6b4f66dcf5 Use LJ Speech sample for voice cloning (Alibaba Cloud URL blocked) 2026-01-26 16:28:39 -05:00
ad6a4d4990 Fix docker-compose.yml for older docker-compose versions 2026-01-26 14:25:06 -05:00
0159f1f216 Add configurable WORKERS env var, default to 1 for GPU models 2026-01-26 13:16:44 -05:00
f299b43f1a Fix qwen-tts version constraint (0.0.5 is latest) 2026-01-26 11:14:26 -05:00
381ba3b462 Pre-download Qwen3-TTS model on container startup 2026-01-26 11:07:30 -05:00
b315659be6 Make Qwen3-TTS the default engine, add CPU-only docker support
- Switch default TTS engine from Piper to Qwen3-TTS (1.7B params)
- Upgrade to Python 3.12
- Add docker-compose.cpu.yml for CPU-only deployments
- Improve GPU configuration with NVIDIA environment variables
- Comment out optional engines (Piper, XTTS, Silero, Kokoro) in requirements
- Update Makefile with local/local-cpu targets and venv support
- Simplify voice_to_speaker.default.yaml for Qwen3-TTS voices
- Update docs/MODELS.md with Qwen3-TTS documentation
- Add git commit guidelines to CLAUDE.md
2026-01-26 10:41:23 -05:00
4a019cf897 Add detailed AGPL v3 license obligations documentation
Explains source code requirements for network service operators,
practical compliance methods, and Raccoon Mission rationale.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 10:39:23 -05:00
99bc6bf014 renamed: docs/CLAUDE.md -> CLAUDE.md 2026-01-26 10:00:07 -05:00
058ad5840b Fix docker-compose image references to use local builds
Replace upstream ghcr.io/matatonic image references with local image names.
This was missed in the naming standardization commit 7559e56.

- docker-compose.yml: uncloseai-speech:local
- docker-compose.min.yml: uncloseai-speech-min:local
- docker-compose.rocm.yml: uncloseai-speech-rocm:local
2025-12-13 10:53:36 -05:00
7559e56d0c Standardize project naming to uncloseai-speech across all files
- Add CHANGELOG.md with full version history (moved from README)
- Update all documentation to use lowercase 'uncloseai-speech' project name
- Update organization references to lowercase 'uncloseai' (not 'UncloseAI')
- Add Brand Identity section to docs/CLAUDE.md with naming guidelines
- Update speech.py argparse description to match branding
- Update README.md headers and sections with consistent naming
- Update all model documentation with consistent branding

Files updated:
- CHANGELOG.md (new file)
- README.md (changelog reference, server options, multilingual section)
- speech.py (--workers argument, branding in argparse)
- Makefile (header comment)
- docs/CLAUDE.md (Brand Identity section)
- docs/MODELS.md
- docs/MIRRORS.md
- docs/AUDIT.md
- docs/models/coqui-tts.md
- docs/research/tts-models-overview.md

Branding standard:
- Project: uncloseai-speech (lowercase, hyphenated)
- Organization: uncloseai (lowercase, one word)

🦝 Generated with Claude Code
2025-11-10 05:23:34 -05:00
da8e960b2d Fix Kokoro defaulting to CPU in worker processes
The DefaultArgs class had xtts_device hardcoded to 'cpu', which meant
all uvicorn worker processes inherited this default instead of using
auto_torch_device() to detect GPU.

Changes:
- Set DefaultArgs.xtts_device to None initially
- Call auto_torch_device() after class definition to set default
- This ensures workers use GPU if available, not hardcoded CPU
- Fixed log message to show actual device being used (not args value)
- Log moved after device calculation for accuracy

This fixes Kokoro loading on CPU even when GPU is available.
2025-11-10 04:22:53 -05:00
ae958d1bb6 Enable GPU acceleration for Kokoro TTS
Kokoro was hardcoded to use CPU, causing very slow generation times
(3+ minutes for long texts). Now Kokoro uses the same device as XTTS
(auto-detected as 'cuda' if available, otherwise 'cpu').

Changes:
- Add device parameter to kokoro_wrapper __init__ (defaults to 'cpu')
- Pass device to KPipeline constructor
- Use args.xtts_device when initializing Kokoro (same as XTTS)
- Add semaphore lock to prevent concurrent Kokoro model loading
- Log which device Kokoro is loading on

Performance improvement: ~60x faster on GPU vs CPU for long texts
2025-11-10 04:14:46 -05:00
4576afac39 Fix UnboundLocalError in cleanup function
The cleanup() callback was trying to delete generator_worker and
out_writer_worker unconditionally, but these variables are only
defined in certain code paths. This caused UnboundLocalError when
cleanup was called after requests that didn't create these workers.

Wrap the deletions in try/except blocks to handle cases where the
variables weren't created.
2025-11-10 04:01:39 -05:00
bb9823f6d0 🦝 Move XTTS imports to module level for worker processes
Worker processes need access to XTTS classes (ModelManager, XttsConfig,
Xtts, split_sentence, detect) but were only imported conditionally in
__main__ block.

**Solution:** Import at module level with try/except for graceful
degradation in minimal installations. Set XTTS_AVAILABLE flag.

This ensures worker processes can handle tts-1-hd requests properly.
2025-11-09 18:40:38 -05:00
3887e9b850 🦝 Streamline CLAUDE.md - reference guide not changelog
Remove verbose explanations and code examples. Keep it concise:
- TTS Engine Status: one-liner per engine
- Testing: condensed workflow steps
- Multiprocess: key pattern + implementation reference

CLAUDE.md is a quick reference, not documentation.
2025-11-09 18:29:24 -05:00
187121558e 📚 Update docs with hydration results and multiprocess fixes
**README.md:**
- Added Raccoon Mission Updates section (2025-11-09)
- Documented 235/245 voices working (95.9% success rate)
- Listed all major fixes: multiprocess architecture, voice auto-detection,
  cache initialization, args initialization
- Added Makefile targets documentation (hydrate, load-test)

**docs/CLAUDE.md:**
- Updated TTS Engine Status with hydration percentages
- Added Testing Philosophy section with hydrate and load-test targets
- Documented Known Issues and Solutions:
  * Worker processes not loading caches - lifespan solution
  * Worker processes AttributeError on args - DefaultArgs solution
- Included code examples for both fixes

These updates capture the complete journey from 0% to 95.9% voice
hydration success and document the multiprocess worker architecture fixes.

🦝 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 18:27:48 -05:00
be374409d6 🦝 Fix args being None in worker processes
**Problem:** Worker processes had `args = None` causing AttributeError
when accessing `args.xtts_device`, `args.use_deepspeed`, etc. This
broke all non-Piper TTS engines (Silero, Kokoro, XTTS).

**Root Cause:** `args` was parsed in `if __name__ == "__main__"` block
which only runs in parent process, not in uvicorn worker processes.

**Solution:** Created DefaultArgs class with sensible defaults for
worker processes. Main process still overrides these with actual
command-line arguments.

**Impact:** All TTS engines now work in worker processes.

🦝 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 18:22:19 -05:00
bc2071900c 🦝 Fix voice cache initialization in multiprocess workers
**Problem:** Voice-to-model cache was only initialized in parent process,
not in worker processes spawned by uvicorn workers=4. This caused ALL
voice auto-detection to fail with "Voice not found in any model" errors.

**Root Cause:** Cache initialization was in `if __name__ == "__main__"`
block, which only runs in the parent process. Worker processes import
the `app` object directly and don't execute the __main__ block.

**Solution:** Moved cache initialization to FastAPI `lifespan` context
manager, which runs during startup in EACH worker process. This ensures
every worker has the voice_to_model_cache and voices_cache populated.

**Impact:**
- Voice auto-detection now works in all 4 worker processes
- /v1/voices endpoint returns cached data in all workers
- All 227 voices can now be used without specifying model parameter

🦝 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 18:13:52 -05:00
549a35d613 🦝 Add working hydrate and load-test targets
Makefile targets:
- make hydrate: Sequential testing of ALL voices (227 total)
- make load-test: 100 concurrent requests with random voices/models

Load test results (with multiprocess workers):
- 100 requests in 4 seconds (25 req/s)
- 10 concurrent requests at a time
- 100% success rate (no crashes!)
- 15% voices returned full audio (voices downloaded)
- 85% returned stub MP3s (voices not yet downloaded)

Key insight: Server handles concurrent load perfectly with 4 workers
- No deadlocks
- No timeouts
- Graceful handling even when voice files missing

TODO: Run 'make voices' to download all Piper voices for full test
2025-11-09 17:33:58 -05:00
aeebb69a8c 🦝 Fix uvicorn workers with import string
Workers require 'speech:app' import string, not app object directly
2025-11-09 17:10:08 -05:00