Metadata-Version: 2.4
Name: inno-kokoro
Version: 0.2.0
Summary: Zero-shot voice tuner for Kokoro-82M: one pass from a reference clip to a stock-shaped voice pack
License-Expression: Apache-2.0
Project-URL: Weights, https://huggingface.co/remsky/kokoro-inno-clone-tuner
Project-URL: Source, https://github.com/remsky/inno-kokoro
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
Requires-Python: <3.13,>=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: torch
Requires-Dist: scipy
Requires-Dist: soundfile
Requires-Dist: safetensors
Requires-Dist: huggingface_hub
Requires-Dist: kokoro==0.9.4
Requires-Dist: praat-parselmouth>=0.4.7
Dynamic: license-file

![Inno Clone Tuner](https://raw.githubusercontent.com/remsky/inno-kokoro/main/docs/banner.png)

[![CI](https://github.com/remsky/inno-kokoro/actions/workflows/ci.yml/badge.svg)](https://github.com/remsky/inno-kokoro/actions/workflows/ci.yml)
[![codecov](https://codecov.io/gh/remsky/inno-kokoro/graph/badge.svg)](https://codecov.io/gh/remsky/inno-kokoro)
[![PyPI](https://img.shields.io/pypi/v/inno-kokoro)](https://pypi.org/project/inno-kokoro/)

[![Python](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12-blue)](https://pypi.org/project/inno-kokoro/)
[![License](https://img.shields.io/badge/license-Apache--2.0-blue)](https://github.com/remsky/inno-kokoro/blob/main/LICENSE)
[![Weights](https://img.shields.io/badge/%F0%9F%A4%97%20Model-v0.2.0-blue)](https://huggingface.co/remsky/kokoro-inno-clone-tuner)

Zero-shot voice tuner for [Kokoro-82M](https://huggingface.co/hexgrad/Kokoro-82M). 

A 5-30 second reference clip in, a stock-shaped `[510, 1, 256]` voice pack out in about 0.3 seconds.

## Usage
```bash
pip install inno-kokoro
inno-kokoro --fetch /models # -> /models/model.safetensors, e.g. in a Dockerfile; skips if present
inno-kokoro my_ref.wav am_me # -> voices/am_me.pt + voices/am_me_test.wav
inno-kokoro my_ref.wav am_me --fmax 300 # override pitch ceiling
```

Currently only available for English; prefixes work like the stock packs e.g: `af_`, `am_`, `bf_`, `bm_`.

```python
from inno_kokoro.enroll import Tuner, enroll, read
from kokoro import KPipeline

tuner = Tuner()  # huggingface cache; or Tuner("/models/model.safetensors") for a path of your own
pack, _ = enroll(*read("my_ref.wav"), tuner)
pipe = KPipeline(lang_code="a")
wav = next(pipe("Hello from a tuned voice.", voice=pack)).audio
```

---

For best results, the reference audio should be:
- 3-second minimum, up to the first 30-seconds
- Single speaker (english). 
- Reasonably clear of audio artifacts

Voice pack generation time:
- about 0.05 s per second of reference on CPU
- 0.1 to 0.3 s total on a GPU (after the model is loaded).


## Identity benchmarking

LibriSpeech test-clean, F5-TTS cross-sentence split: 1127 utterances, 39 held-out speakers. 

Reference in, new sentence out, scored against the speaker's real recording. Normalized scores compare the render between sounding like a stranger (0) and a second sample of the same benchmark speaker (1). 

RTF on an RTX 4060 Ti.

| system | SIM-o | normalized | UTMOS | RTF |
|---|---|---|---|---|
| ground truth (second recording) | 0.695 | 1.00 | 4.10 | |
| F5-TTS v1 base | 0.650 | 0.94 | 3.86 | 0.48 |
| StyleTTS2 (LibriTTS zero-shot) | 0.386 | 0.46 | 4.40 | 0.06 |
| **Inno v0.2** | 0.288 | 0.32 | 4.45 | 0.07 |
| OpenVoice v2 | 0.227 | 0.23 | 3.80 | 0.12 |
| Kokoro, nearest stock pack | 0.167 | 0.15 | 4.25 | 0.06 |

---

UTMOS scoring stays high which reflects the priority placed on maintaining Kokoro's voice quality. 

Inno can match about a third of the way to most identities, and avoids copying recording artifacts etc. 

## License and Attributions

Apache-2.0. The speaker encoder is CC BY-SA 3.0. 

Full model card available on HuggingFace: [remsky/kokoro-inno-clone-tuner](https://huggingface.co/remsky/kokoro-inno-clone-tuner). 

**Only clone voices you have permission to clone, even the shallow cloning provided by this model and technique.** 
