Commit graph

21 commits

Author SHA1 Message Date
timehexon
468cd1dfc0 Makefile: fold sox into apt-deps (now a required dep) 2026-06-05 12:33:10 -04:00
timehexon
5e41ab6779 Makefile: add apt-deps + apt-deps-sox targets for venv path 2026-06-05 12:04:24 -04:00
f25731ca08
Add make whisper-refs — re-transcribe cloned-voices/*.wav with whisper-large-v3
F5-TTS cloning quality depends on ref_text matching the prosody of ref_audio
(commas, periods, casing). Previous ref_texts were LibriSpeech ground-truth
labels: ALL CAPS, no punctuation — wrong signal for a flow-matching TTS
conditioned on text. Whisper hears what F5 will hear.

- scripts/whisper_refs.py — transcribe all wavs, rewrite
  voice_to_speaker.default.yaml + cloned-voices/voices_metadata.json
  in place. Also writes cloned-voices/whisper_refs.json sidecar.
- Makefile: whisper-refs target. Idempotent, rerun whenever
  cloned-voices/ changes.

Run on a GPU host (4090/3090). ~30s for 40 short clips on a 4090.
2026-05-24 11:56:15 -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
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
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
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
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
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
459e8d5896 🦝 Fix concurrency with multiprocess workers + semaphores
ROOT CAUSE: Python GIL prevents true concurrent execution
- asyncio.to_thread() still bound by GIL and limited thread pool
- Under load: 115+ threads exhausted default pool, server deadlocked
- ML models loading concurrently overwhelmed single-process server

SOLUTION:
1. Added uvicorn workers=4 for true multiprocess concurrency
   - Each worker = separate Python process with own GIL
   - Models loaded independently per worker
   - 4x capacity for concurrent requests

2. Added semaphores for model loading safety
   - silero_load_semaphore: Only 1 Silero load at a time per worker
   - kokoro_load_semaphore: Only 1 Kokoro load at a time per worker
   - Double-check pattern prevents race conditions

3. Increased timeout_keep_alive=300s for long model loads

IMPACT:
- Can now handle 100+ concurrent requests without deadlock
- Each worker independently serves requests during model loads
- Graceful degradation under extreme load
- Ready for production traffic

Alternative considered: Elixir/Phoenix with BEAM VM
- Would give millions of lightweight processes
- Better for massive scale (1000+ concurrent)
- Keep on roadmap for future if needed

Raccoon wisdom: Sometimes the solution is more processes, not more threads!
2025-11-09 16:44:06 -05:00
a8865564ae Map all available Piper voices and expand Makefile downloads
- Added 40+ Piper voice mappings to voice_to_speaker.default.yaml
  * 20 English US voices (libritts_r speakers + single-speaker models)
  * 9 English GB voices
  * All voices use proper naming convention (en_us_*, en_gb_*)
  * Kept OpenAI-compatible aliases (alloy, echo, fable, onyx, nova, shimmer)

- Updated Makefile voices-piper target to download ALL voices:
  * 20 English US models (amy, arctic, bryce, danny, hfc_female, hfc_male, joe, john, kathleen, kristin, kusal, l2arctic, lessac, libritts, libritts_r, ljspeech, norman, reza_ibrahim, ryan, sam)
  * 9 English GB models (alan, alba, aru, cori, jenny_dioco, northern_english_male, semaine, southern_english_female, vctk)
  * Download function with error handling

- Updated main 'voices' target to include Silero downloads

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 13:16:22 -05:00
Claude
848c2c6cb5 Integrate Silero TTS and add infrastructure for Chatterbox/Kokoro
INTEGRATED: Silero TTS (tts-1-silero)
- Added silero_wrapper class to speech.py for PyTorch Hub integration
- CPU-friendly, no GPU required (48kHz sample rate)
- Supports 5 languages: English (117 speakers), Russian, German, Spanish, French
- Loads on-demand via torch.hub from snakers4/silero-models
- Added 6 OpenAI-compatible voice mappings (alloy, echo, fable, etc.)

PREPARED: Chatterbox & Kokoro TTS
- Added dependencies to requirements.txt:
  * git+https://github.com/resemble-ai/chatterbox.git
  * transformers>=4.35.0 (for Kokoro)
  * huggingface-hub[cli] (for model downloads)
- Created Makefile targets for downloading models
- Created test targets for all three new engines

Makefile Enhancements:
- make voices-silero: Download Silero models (en, ru, de, es, fr)
- make test-silero: Test Silero TTS endpoint
- make voices-chatterbox: Download Chatterbox models via HF CLI
- make test-chatterbox: Test Chatterbox with emotion control
- make voices-kokoro: Download Kokoro models via HF CLI
- make test-kokoro: Test Kokoro fast synthesis

speech.py Changes:
- Added silero_wrapper class with tts() method
- Added tts-1-silero model handler in generate_speech()
- Registered tts-1-silero model in app
- Added PCM media type for Silero (48000 Hz)
- Global state: silero_model, silero_speakers dict

Configuration:
- Updated voice_to_speaker.default.yaml with tts-1-silero section
- Mapped all 6 OpenAI voices to Silero speakers (en_0 through en_5)

Documentation:
- Updated docs/MODELS.md: Silero marked as  INTEGRATED
- Updated roadmap: Phase 1 task 3 completed
- Updated status footer: 3 models rescued
- Added integration examples and Makefile commands

Next Steps:
- Test Silero integration in Docker
- Implement Chatterbox emotion control engine
- Implement Kokoro fast decoder engine
2025-11-09 10:48:44 -05:00
7b11e4c336 Add GitHub remote and push-all Makefile target
- Add github remote: git@github.com:russellballestrini/openedai-speech.git
- Add 'make push-all' to push to both origin and github
- Document in make help

This ensures the raccoon mission code is mirrored on GitHub
for visibility and resilience.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 09:55:42 -05:00
2c6c1ad577 Add XTTS support to Makefile and create CLAUDE.md guide
Makefile improvements:
- Add voices-xtts target to download speaker samples
- Add test-xtts target for testing HD model
- Split voices into voices-piper and voices-xtts
- Update help text with all new targets

speech.py:
- Fix threading import scope issue for XTTS
- Remove redundant 'import threading' inside Piper block

docs/CLAUDE.md:
- Complete guide for Claude Code contributors
- Makefile-first development philosophy
- Never create dirs manually, always use Makefile
- Documentation requirements and testing philosophy
- Common mistakes to avoid
- Raccoon mission values and principles

This ensures consistent, repeatable deployments and makes it easy
to add new TTS engines following the same pattern.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 09:52:13 -05:00
0ff5f0f09a Fix Makefile to create speech.env automatically
- Add step in sync target to copy sample.env to speech.env if missing
- Ensures Makefile works from scratch without manual intervention
- Tested full deployment cycle: deploy -> voices -> test
- Successfully creates ~/uncloseai-speech directory
- Downloads voices with absolute paths
- Generates working TTS audio

Raccoon mission: Makefile is now fully self-sufficient!

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 09:37:33 -05:00
91862d4f82 Clean up deployment paths to use uncloseai-speech without -fresh suffix
🦝 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 09:12:06 -05:00
4aebcc037f Rebrand project to UncloseAI Speech
Renamed all references from openedai-speech to uncloseai-speech across
the entire codebase, including:
- Project name in README and documentation
- Docker image names in compose files
- Makefile deployment paths and container names
- Configuration examples in vars.sh.example

This establishes our raccoon mission fork as UncloseAI Speech, a unified
TTS system supporting multiple engines (Piper, XTTS, etc.) with OpenAI
API compatibility.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 09:11:09 -05:00
eb899deca2 Fix Piper TTS absolute path resolution and improve deployment workflow
This commit resolves the "download entire voices" issue by properly handling
absolute paths in Piper model configuration and improves the deployment system.

Key changes:
- speech.py: Detect absolute paths and omit --data-dir/--download-dir flags
  when using absolute model paths, allowing Piper to load models directly
- speech.py: Add debug logging and stderr capture for Piper subprocess
- voice_to_speaker.default.yaml: Use absolute paths for all Piper models
- Makefile: Load deployment config from vars.sh for better security
- Makefile: Change restart to rebuild container ensuring code updates apply
- Add vars.sh.example template for deployment configuration
- .gitignore: Add vars.sh to prevent committing deployment secrets

Tested successfully with en_US-libritts_r-medium model using absolute path:
/app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 09:05:13 -05:00
d015dd044b 🦝 Fix: Use absolute paths for Piper models
SOLUTION FOUND! Piper requires ABSOLUTE paths to model files, not relative paths.

Changes:
- Update voice_to_speaker.default.yaml to use /app/voices/... absolute paths
- Update Makefile voices target to set absolute paths via sed
- Tested: Piper works with /app/voices/en/en_US/libritts_r/medium/en_US-libritts_r-medium.onnx

Root cause: PyPI piper-tts package doesn't auto-download voices or support
voice name resolution. Must use full absolute file paths.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 08:24:00 -05:00
5564d3fc6f 🦝 Raccoon Mission: Add Makefile and upgrade to Piper v1.3.0 from OHF-Voice
- Add comprehensive Makefile for deployment to ai.foxhop.net
- Switch from abandoned rhasspy/piper to OHF-Voice/piper1-gpl v1.3.0
- Add voice download automation with correct directory structure
- Includes deploy, sync, test, logs, and voice management commands

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 08:19:02 -05:00