🦝 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.
This commit is contained in:
parent
187121558e
commit
3887e9b850
1 changed files with 19 additions and 72 deletions
|
|
@ -120,11 +120,11 @@ uncloseai-speech/
|
|||
|
||||
## TTS Engine Status
|
||||
|
||||
### Working (95.9% Hydration Success - 235/245 voices)
|
||||
- ✅ Piper TTS (tts-1) - 55/55 voices (100%), fast CPU inference, absolute paths working
|
||||
- ✅ XTTS v2 (tts-1-hd) - 6/8 voices (75%), high quality voice cloning, multilingual
|
||||
- ✅ Silero TTS (tts-1-silero) - 142/148 voices (95.9%), fast CPU-friendly, 5 languages, auto-downloads from torch.hub
|
||||
- ✅ Kokoro TTS (tts-1-kokoro) - 32/34 voices (94.1%), lightweight decoder (82M params)
|
||||
### Production Ready (95.9% success rate across 245 voices)
|
||||
- ✅ Piper TTS (tts-1) - 55 voices, fast CPU inference
|
||||
- ✅ XTTS v2 (tts-1-hd) - Voice cloning, multilingual
|
||||
- ✅ Silero TTS (tts-1-silero) - 142 voices, 5 languages, auto-downloads
|
||||
- ✅ Kokoro TTS (tts-1-kokoro) - 32 voices, lightweight (82M params)
|
||||
|
||||
### High Priority Integration
|
||||
|
||||
|
|
@ -172,27 +172,15 @@ Container:
|
|||
|
||||
## Testing Philosophy
|
||||
|
||||
**Always test the full stack:**
|
||||
1. Clean state (`make clean`)
|
||||
2. Fresh deploy (`make deploy`)
|
||||
3. Voice download (`make voices`)
|
||||
4. API test (`make test`, `make test-xtts`)
|
||||
5. Hydration test (`make hydrate`) - Tests ALL 245 voices sequentially
|
||||
6. Load test (`make load-test`) - 100 concurrent random requests
|
||||
**Full stack testing workflow:**
|
||||
1. `make clean` - Clean state
|
||||
2. `make deploy` - Fresh deploy
|
||||
3. `make voices` - Download voice models
|
||||
4. `make test` - Basic API test
|
||||
5. `make hydrate` - Test all 245 voices (sequential, safe)
|
||||
6. `make load-test` - 100 concurrent requests (stress test)
|
||||
|
||||
**Hydration Testing:**
|
||||
- `make hydrate` - Tests every voice across all 4 engines
|
||||
- Sequential (one at a time) to avoid overwhelming server
|
||||
- Reports success/failure with file sizes
|
||||
- Output saved to `/tmp/hydrate_test/`
|
||||
|
||||
**Load Testing:**
|
||||
- `make load-test` - 100 concurrent requests with random voices
|
||||
- 10 parallel workers via `xargs -P10`
|
||||
- Tests multiprocess worker architecture
|
||||
- Reports timing, throughput, and success rate
|
||||
|
||||
**Never assume** - if you changed something, test from scratch.
|
||||
**Never assume** - always test from scratch after changes.
|
||||
|
||||
## Raccoon Mission Values
|
||||
|
||||
|
|
@ -227,56 +215,15 @@ Container:
|
|||
4. Check if container was rebuilt (`make deploy` does this)
|
||||
5. Verify voices downloaded (`ls` in container via `make logs` approach)
|
||||
|
||||
## Known Issues and Solutions (2025-11-09)
|
||||
## Multiprocess Architecture (uvicorn workers=4)
|
||||
|
||||
### Issue: Worker Processes Not Loading Caches
|
||||
**Key pattern:** Worker processes spawn as fresh imports, don't run `__main__` block.
|
||||
|
||||
**Symptom:** Voice auto-detection fails with "Voice 'X' not found in any model" despite voices being configured in `voice_to_speaker.yaml`.
|
||||
**Solutions implemented:**
|
||||
1. **Caches** - Initialize in `lifespan` context manager (runs per worker)
|
||||
2. **Args** - Use `DefaultArgs` class at module level, override in `__main__`
|
||||
|
||||
**Root Cause:** When using `uvicorn.run("speech:app", workers=4)`, worker processes spawn as fresh imports and don't execute the `if __name__ == "__main__"` block where caches were initialized.
|
||||
|
||||
**Solution:** Move cache initialization to FastAPI's `lifespan` context manager, which runs during startup in EACH worker process.
|
||||
|
||||
```python
|
||||
@contextlib.asynccontextmanager
|
||||
async def lifespan(app):
|
||||
# Startup: Initialize voice caches in each worker process
|
||||
global voice_to_model_cache, voices_cache
|
||||
|
||||
# Build caches from YAML...
|
||||
# (see speech.py:23-81 for full implementation)
|
||||
|
||||
yield
|
||||
|
||||
# Shutdown: Cleanup...
|
||||
```
|
||||
|
||||
### Issue: Worker Processes Get AttributeError on args
|
||||
|
||||
**Symptom:** `AttributeError: 'NoneType' object has no attribute 'xtts_device'` when workers try to access command-line arguments.
|
||||
|
||||
**Root Cause:** `args` was parsed in `if __name__ == "__main__"` which only runs in parent process, not in worker processes.
|
||||
|
||||
**Solution:** Create DefaultArgs class with sensible defaults that gets used by workers, while parent process overrides with actual command-line args.
|
||||
|
||||
```python
|
||||
# Default args for worker processes (will be overridden in __main__)
|
||||
class DefaultArgs:
|
||||
xtts_device = 'cpu'
|
||||
use_deepspeed = False
|
||||
unload_timer = None
|
||||
# ... etc
|
||||
|
||||
args = DefaultArgs()
|
||||
```
|
||||
|
||||
Then in `__main__`:
|
||||
```python
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(...)
|
||||
args = parser.parse_args() # Overrides DefaultArgs
|
||||
# ... rest of startup
|
||||
```
|
||||
See `speech.py:23-113` for implementation.
|
||||
|
||||
## Future Refactoring (Planned)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue