Featherlabs commited on
Commit
a091db0
ยท
verified ยท
1 Parent(s): 8cb6543

Create README.md

Browse files
Files changed (1) hide show
  1. README.md +298 -0
README.md ADDED
@@ -0,0 +1,298 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ language:
3
+ - en
4
+ license: apache-2.0
5
+ base_model: SparkAudio/Spark-TTS-0.5B
6
+ datasets:
7
+ - MrDragonFox/Elise
8
+ tags:
9
+ - tts
10
+ - text-to-speech
11
+ - spark-tts
12
+ - voice-cloning
13
+ - emotion-tags
14
+ - unsloth
15
+ - trl
16
+ - sft
17
+ - featherlabs
18
+ - audio
19
+ - amd-mi300x
20
+ library_name: transformers
21
+ pipeline_tag: text-to-speech
22
+ ---
23
+
24
+ <div align="center">
25
+
26
+ # ๐Ÿ”Š Finatts Enhanced
27
+
28
+ ### *High-fidelity voice cloning โ€” fine-tuned Spark-TTS v2*
29
+
30
+ **Text-to-Speech ยท Voice Cloning ยท Emotion Tags ยท Portable Voice Profile**
31
+
32
+ [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
33
+ [![Base Model](https://img.shields.io/badge/Base-Spark--TTS--0.5B-purple)](https://huggingface.co/SparkAudio/Spark-TTS-0.5B)
34
+ [![Dataset](https://img.shields.io/badge/Dataset-MrDragonFox%2FElise-green)](https://huggingface.co/datasets/MrDragonFox/Elise)
35
+ [![Parameters](https://img.shields.io/badge/Params-507M-orange)](https://huggingface.co/Featherlabs/Finatts-enhanced)
36
+
37
+ *Built by [Featherlabs](https://huggingface.co/Featherlabs) ยท Operated by Owlkun*
38
+
39
+ </div>
40
+
41
+ ---
42
+
43
+ ## โœจ What is Finatts Enhanced?
44
+
45
+ Finatts Enhanced is an improved **507M-parameter text-to-speech model** built on [Spark-TTS-0.5B](https://huggingface.co/SparkAudio/Spark-TTS-0.5B), fine-tuned for **high-fidelity single-speaker voice cloning** with emotion tag support.
46
+
47
+ Compared to the original [Finatts](https://huggingface.co/Featherlabs/Finatts), this version features **3ร— the training**, a more stable learning rate, and a portable voice profile (`elise_voice.safetensors`) โ€” no reference audio needed at inference time.
48
+
49
+ ### Improvements over v1
50
+
51
+ | Setting | Finatts v1 | Finatts Enhanced |
52
+ |:---|:---:|:---:|
53
+ | Epochs | 2 | **6** |
54
+ | Learning rate | 1e-4 | **5e-5** |
55
+ | Warmup steps | 20 | **50** |
56
+ | Weight decay | 0.001 | **0.01** |
57
+ | Emotion tags | โŒ | **โœ…** |
58
+ | Voice profile | โŒ | **โœ… `elise_voice.safetensors`** |
59
+ | Final loss | 5.827 | **5.806** |
60
+
61
+ ### ๐ŸŽฏ Built For
62
+
63
+ | Capability | Description |
64
+ |:---:|---|
65
+ | ๐ŸŽ™๏ธ **Voice Cloning** | Clone Elise's voice โ€” no reference audio required |
66
+ | ๐ŸŽญ **Emotion Tags** | `<laughs>` `<giggles>` `<whispers>` `<sighs>` `<chuckles>` `<long pause>` |
67
+ | ๐Ÿ“ **Text-to-Speech** | Convert text to natural, expressive speech |
68
+ | ๐Ÿ“ฆ **Portable Profile** | Load `elise_voice.safetensors` โ€” deploy anywhere |
69
+
70
+ ---
71
+
72
+ ## ๐Ÿ‹๏ธ Training Details
73
+
74
+ <table>
75
+ <tr><td><b>Property</b></td><td><b>Value</b></td></tr>
76
+ <tr><td>Base model</td><td><a href="https://huggingface.co/SparkAudio/Spark-TTS-0.5B">SparkAudio/Spark-TTS-0.5B</a></td></tr>
77
+ <tr><td>LLM backbone</td><td>Qwen2-0.5B (507M params)</td></tr>
78
+ <tr><td>Dataset</td><td><a href="https://huggingface.co/datasets/MrDragonFox/Elise">MrDragonFox/Elise</a> (1,195 samples, ~3h)</td></tr>
79
+ <tr><td>Training type</td><td>Full Supervised Fine-Tuning (SFT)</td></tr>
80
+ <tr><td>Epochs</td><td>6</td></tr>
81
+ <tr><td>Batch size</td><td>8 (effective 16 with grad accum)</td></tr>
82
+ <tr><td>Learning rate</td><td>5e-5</td></tr>
83
+ <tr><td>Warmup steps</td><td>50</td></tr>
84
+ <tr><td>Weight decay</td><td>0.01</td></tr>
85
+ <tr><td>Context length</td><td>4,096 tokens</td></tr>
86
+ <tr><td>Precision</td><td>BF16</td></tr>
87
+ <tr><td>Optimizer</td><td>AdamW (torch fused)</td></tr>
88
+ <tr><td>LR scheduler</td><td>Cosine</td></tr>
89
+ <tr><td>Framework</td><td>Unsloth + TRL (SFTTrainer)</td></tr>
90
+ <tr><td>Hardware</td><td>AMD MI300X (192GB HBM3)</td></tr>
91
+ </table>
92
+
93
+ ### ๐Ÿ“Š Training Metrics
94
+
95
+ | Metric | Value |
96
+ |:---|:---:|
97
+ | **Final loss** | 5.806 |
98
+ | **Training time** | 144s (2.4 min) |
99
+ | **Peak VRAM** | 22.5 GB (11.7% of 192GB) |
100
+ | **Trainable params** | 506,634,112 (100%) |
101
+ | **Total steps** | 450 |
102
+
103
+ ### Training Loss Curve
104
+
105
+ Model converges from **~6.9 โ†’ ~5.8** over 450 steps โ€” 3ร— more convergence than v1:
106
+
107
+ | Step | Loss | Step | Loss | Step | Loss |
108
+ |:---:|:---:|:---:|:---:|:---:|:---:|
109
+ | 1 | 6.90 | 150 | 5.79 | 300 | 5.74 |
110
+ | 50 | 5.82 | 200 | 5.76 | 400 | 5.77 |
111
+ | 100 | 5.77 | 250 | 5.73 | 450 | 5.81 |
112
+
113
+ ---
114
+
115
+ ## ๐Ÿš€ Quick Start
116
+
117
+ ### Prerequisites
118
+
119
+ ```bash
120
+ pip install "unsloth[amd] @ git+https://github.com/unslothai/unsloth"
121
+ pip install "transformers<=5.2.0,>=4.51.3" "trl<=0.24.0,>=0.18.2"
122
+ pip install omegaconf einx "datasets>=3.4.1,<4.4.0" soundfile safetensors
123
+
124
+ # Clone Spark-TTS for BiCodec tokenizer
125
+ git clone https://github.com/SparkAudio/Spark-TTS
126
+ ```
127
+
128
+ ### Inference with Elise Voice Profile
129
+
130
+ ```python
131
+ import torch, re, sys
132
+ import soundfile as sf
133
+ from transformers import AutoTokenizer, AutoModelForCausalLM
134
+ from huggingface_hub import snapshot_download, hf_hub_download
135
+ from safetensors.torch import load_file
136
+ import json
137
+
138
+ sys.path.append("Spark-TTS")
139
+ from sparktts.models.audio_tokenizer import BiCodecTokenizer
140
+
141
+ MODEL_ID = "Featherlabs/Finatts-enhanced"
142
+
143
+ # Load LLM
144
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
145
+ model = AutoModelForCausalLM.from_pretrained(
146
+ MODEL_ID, torch_dtype=torch.bfloat16, device_map="auto"
147
+ )
148
+ model.eval()
149
+
150
+ # Load BiCodec
151
+ snapshot_download("unsloth/Spark-TTS-0.5B", local_dir="Spark-TTS-0.5B")
152
+ audio_tokenizer = BiCodecTokenizer("Spark-TTS-0.5B", "cuda")
153
+
154
+ # Load Elise voice profile (global token IDs โ€” no reference audio needed)
155
+ profile_path = hf_hub_download(MODEL_ID, "elise_voice_profile.json")
156
+ with open(profile_path) as f:
157
+ profile = json.load(f)
158
+ elise_global_ids = profile["global_token_ids"]
159
+ elise_global_token_str = profile["global_token_str"]
160
+
161
+
162
+ @torch.inference_mode()
163
+ def generate_speech(text, temperature=0.8, top_k=40, top_p=0.92):
164
+ prompt = "".join([
165
+ "<|task_tts|>",
166
+ "<|start_content|>", text, "<|end_content|>",
167
+ "<|start_global_token|>",
168
+ elise_global_token_str, # Elise's voice injected here
169
+ "<|end_global_token|>",
170
+ "<|start_semantic_token|>",
171
+ ])
172
+ inputs = tokenizer([prompt], return_tensors="pt").to("cuda")
173
+ generated = model.generate(
174
+ **inputs, max_new_tokens=2048,
175
+ do_sample=True, temperature=temperature,
176
+ top_k=top_k, top_p=top_p,
177
+ eos_token_id=tokenizer.eos_token_id,
178
+ )
179
+ out = tokenizer.batch_decode(
180
+ generated[:, inputs.input_ids.shape[1]:], skip_special_tokens=False
181
+ )[0]
182
+ sem = [int(t) for t in re.findall(r"bicodec_semantic_(\d+)", out)]
183
+ if not sem:
184
+ return None
185
+ pred_sem = torch.tensor(sem, dtype=torch.long).unsqueeze(0).to("cuda")
186
+ pred_global = torch.tensor(elise_global_ids, dtype=torch.long).unsqueeze(0).to("cuda")
187
+ audio_tokenizer.model.to("cuda")
188
+ return audio_tokenizer.detokenize(pred_global, pred_sem).squeeze().cpu().numpy()
189
+
190
+
191
+ # Try emotion tags!
192
+ texts = [
193
+ "Hey there! My name is Elise, nice to meet you.",
194
+ "<laughs> Oh my gosh, I can't believe that actually worked!",
195
+ "<whispers> Come closer... I have a secret to tell you.",
196
+ "<sighs> Some days just feel heavier than others.",
197
+ ]
198
+ for i, text in enumerate(texts):
199
+ wav = generate_speech(text)
200
+ if wav is not None:
201
+ sf.write(f"output_{i+1}.wav", wav, 16000)
202
+ print(f"โœ… output_{i+1}.wav")
203
+ ```
204
+
205
+ ---
206
+
207
+ ## ๐ŸŽญ Emotion Tags
208
+
209
+ The Elise dataset includes inline emotion tags captured from real speech. Place them anywhere in your text:
210
+
211
+ | Tag | Effect |
212
+ |:---|:---|
213
+ | `<laughs>` | Lighter, brighter intonation |
214
+ | `<giggles>` | Playful, uptick in pitch |
215
+ | `<whispers>` | Softer, breathier delivery |
216
+ | `<sighs>` | Drawn-out, melancholic tone |
217
+ | `<chuckles>` | Gentle amusement |
218
+ | `<long pause>` | Extended pause in speech |
219
+
220
+ **Note:** Tags produce **intonation variation** rather than literal acoustic sounds (e.g., actual giggling audio). For acoustic emotion effects, see [Orpheus-TTS](https://huggingface.co/canopylabs/orpheus-3b-0.1-ft).
221
+
222
+ ---
223
+
224
+ ## ๐Ÿ—๏ธ Architecture
225
+
226
+ ```
227
+ Text + Emotion Tags
228
+ โ†“
229
+ [LLM: Qwen2-0.5B]
230
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”
231
+ Global tokens Semantic tokens
232
+ (speaker ID) (content + prosody)
233
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
234
+ [BiCodec Decoder]
235
+ โ†“
236
+ Waveform 16kHz
237
+ ```
238
+
239
+ | Component | Details |
240
+ |:---|:---|
241
+ | **LLM** | Qwen2-0.5B (507M params) |
242
+ | **BiCodec** | Neural audio codec โ€” global + semantic tokenization |
243
+ | **Wav2Vec2** | `wav2vec2-large-xlsr-53` โ€” feature extraction |
244
+ | **Sample rate** | 16kHz |
245
+ | **Voice profile** | `elise_voice.safetensors` โ€” 1024-dim d-vector |
246
+
247
+ ---
248
+
249
+ ## ๐Ÿ“ฆ Repository Files
250
+
251
+ | File | Description |
252
+ |:---|:---|
253
+ | `model.safetensors` | Fine-tuned LLM weights (966MB, 16-bit merged) |
254
+ | `elise_voice.safetensors` | Elise speaker d-vector (1024-dim, avg of 10 clips) |
255
+ | `tokenizer.json` | Tokenizer including BiCodec special tokens |
256
+ | `config.json` | Model configuration |
257
+
258
+ For inference you also need:
259
+
260
+ | File | Source |
261
+ |:---|:---|
262
+ | BiCodec model | [`unsloth/Spark-TTS-0.5B`](https://huggingface.co/unsloth/Spark-TTS-0.5B) |
263
+ | Spark-TTS code | [SparkAudio/Spark-TTS](https://github.com/SparkAudio/Spark-TTS) |
264
+
265
+ ---
266
+
267
+ ## โš ๏ธ Limitations
268
+
269
+ - **English only** โ€” only tested with English text inputs
270
+ - **Single speaker** โ€” optimized for Elise; base model multi-speaker may be degraded
271
+ - **16kHz output** โ€” use [audiosr](https://github.com/haoheliu/versatile_audio_super_resolution) for upsampling to 44.1kHz
272
+ - **Emotion intensity** โ€” tags produce subtle intonation changes, not acoustic emotion sounds
273
+ - **ROCm-trained** โ€” tested on AMD MI300X; CUDA users may need minor env adjustments
274
+
275
+ ---
276
+
277
+ ## ๐Ÿ”ฎ What's Next
278
+
279
+ - ๐Ÿ”Š **Super-resolution** โ€” integrate audiosr for 44.1kHz HD output
280
+ - ๐Ÿ—ฃ๏ธ **Multi-speaker** โ€” train on multiple voices
281
+ - ๐Ÿ“ˆ **Larger dataset** โ€” more hours of Elise audio for stronger emotion control
282
+ - ๐ŸŽญ **Acoustic emotions** โ€” explore Orpheus-style explicit emotion tokens
283
+
284
+ ---
285
+
286
+ ## ๐Ÿ“œ License
287
+
288
+ Apache 2.0 โ€” consistent with [Spark-TTS-0.5B](https://huggingface.co/SparkAudio/Spark-TTS-0.5B).
289
+
290
+ ---
291
+
292
+ <div align="center">
293
+
294
+ **Built with โค๏ธ by [Featherlabs](https://huggingface.co/Featherlabs)**
295
+
296
+ *Operated by Owlkun*
297
+
298
+ </div>