File size: 11,373 Bytes
ea6c32b
 
 
 
 
 
 
 
 
 
34bf7bf
 
ea6c32b
34bf7bf
ea6c32b
 
 
34bf7bf
 
 
 
 
 
 
 
 
 
 
 
 
ea6c32b
 
 
 
34bf7bf
ea6c32b
34bf7bf
ea6c32b
 
 
 
 
34bf7bf
 
 
 
 
 
 
 
 
ea6c32b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76b660a
ea6c32b
 
 
76b660a
ea6c32b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34bf7bf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ea6c32b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34bf7bf
 
 
 
 
 
ea6c32b
 
 
 
76b660a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
---
license: apache-2.0
language:
  - en
library_name: onnx
pipeline_tag: text-to-speech
tags:
  - text-to-speech
  - tts
  - speech-synthesis
  - neural-tts
  - offline-tts
  - on-device
  - edge-ai
  - edge
  - offline
  - cpu
  - onnx
  - onnxruntime
  - lightweight
  - small-model
  - flow-matching
  - vocos
  - english
  - raspberry-pi
  - flockspeech
  - accessibility
  - screen-reader
  - voice-assistant
  - narration
datasets:
  - keithito/lj_speech
---

# Junco v0.1: tiny offline text-to-speech (TTS) for CPU

**A small, natural English text-to-speech model that runs offline on any CPU. 44 MB, no GPU, no cloud.**

Junco is an 11.4M-parameter flow-matching TTS model from [Flock Speech](https://huggingface.co/flockspeech). It turns
English text into natural 24 kHz speech on an ordinary CPU, faster than real time. It has no GPU, network or PyTorch
dependency, and the full model is a 44 MB download.

Junco is the clear, neutral **reading voice** of the Flock Speech family: a good fit for voice assistants, screen
readers, notifications, narration and other on-device or edge AI speech output. Install it with
`pip install flockspeech`.

| Flock Speech voices | Style | Model card |
|---|---|---|
| **Junco** | clear, neutral reading voice | this page |
| **Goldfinch** | conversational voice that laughs and breathes on cue with `[laugh]` tags | [flockspeech/goldfinch](https://huggingface.co/flockspeech/goldfinch) |

| | |
|---|---|
| **Developed by** | Flock Speech |
| **Model type** | Non-autoregressive TTS: transformer encoder, duration predictor, conditional flow-matching decoder, Vocos vocoder |
| **Language** | English (US) |
| **Voices** | 1 (female, read-aloud style) |
| **Output** | 24 kHz mono audio |
| **Parameters** | 11.4M acoustic model + 13.5M vocoder |
| **Download** | 44 MB (ONNX; int8 decoder, fp16 encoder and vocoder) |
| **Runtime** | ONNX Runtime on CPU (Linux, macOS, Windows; x86-64 and ARM64) |
| **License** | Apache-2.0 (vocoder weights MIT) |
| **Version** | v0.1, November 2026 |

## Samples

All samples were made with the files in this repository at default settings (8 steps, seed 0), with no editing.

| Use | Text | Audio |
|---|---|---|
| Greeting | *Hello! I'm Junco, a tiny voice that runs entirely on your own device.* | <audio controls src="https://huggingface.co/flockspeech/junco/resolve/main/samples/greeting.wav"></audio> |
| Assistant | *Your next meeting starts in fifteen minutes. Would you like me to read the agenda?* | <audio controls src="https://huggingface.co/flockspeech/junco/resolve/main/samples/assistant.wav"></audio> |
| Narration | *The old lighthouse keeper climbed the spiral stairs one last time, and watched the ships come home through the fog.* | <audio controls src="https://huggingface.co/flockspeech/junco/resolve/main/samples/story.wav"></audio> |
| News | *Researchers announced on Tuesday that the new battery can be charged in under ten minutes, and lasts twice as long.* | <audio controls src="https://huggingface.co/flockspeech/junco/resolve/main/samples/news.wav"></audio> |

## Quick start

The [`flockspeech`](https://pypi.org/project/flockspeech/) Python package bundles these weights, so nothing is downloaded
at run time.

```sh
pip install flockspeech
flockspeech "Hello! I'm Junco." -o hello.wav --play
```

```python
from flockspeech import Junco

tts = Junco()                        # loads in under a second
audio = tts("Hello there.")          # float32 numpy array, 24 kHz mono
tts.save("Hello there.", "hello.wav")

# Low latency: audio is produced sentence by sentence
for chunk in tts.stream(long_text):
    play(chunk)
```

To use the files in this repository directly:

```python
from huggingface_hub import snapshot_download
from flockspeech import Junco

path = snapshot_download("flockspeech/junco", allow_patterns=["onnx/*"])
tts = Junco(model_dir=f"{path}/onnx")
```

### Options

| Parameter | Default | Effect |
|---|---|---|
| `speed` | 1.0 | Speaking rate; 1.2 is 20% faster |
| `steps` | 8 | Flow-matching steps; 4 is about 1.5× faster with slightly lower quality |
| `seed` | 0 | Fixes the small random variation in delivery, so output is reproducible |
| `threads` | up to 4 | CPU threads for ONNX Runtime |

## Intended use

**Suitable for:**
- Voice output on devices and in apps that must work offline or keep text private: assistants, accessibility and
  screen-reading tools, kiosks, robotics, games and embedded products.
- CPU-only servers where cost or latency matters.
- Prototyping and research on small TTS models.

**Out of scope:**
- Languages other than English, or speaker voices other than the one provided. Junco has no voice cloning.
- Expressive, emotional or conversational styles. The voice reads in a neutral, read-aloud style.
- Impersonating a real person, or producing audio meant to deceive listeners about who is speaking or whether the
  speech is synthetic.

## Limitations

- **No text normalisation.** Write numbers, currency, dates and abbreviations in words: "five dollars", not "$5";
  "Doctor", not "Dr.". Raw digits and symbols are read by espeak-ng's rules, which may not be what you want.
- **Pronunciation comes from espeak-ng.** Rare names, brands and some homographs, such as *read* and *lead*, can be
  mispronounced.
- **One voice, one accent.** The model learned from a single US English speaker.
- **Long-form audio.** Text is synthesised sentence by sentence. Prosody does not carry across sentences.
- **Bright high frequencies.** About 14% of Junco's energy lies above 4 kHz, against 2% for real recordings. On some
  playback systems this may sound slightly bright or hissy.

## Risks and responsible use

Synthetic speech can be misused for deception. Junco produces a single fixed voice and cannot clone speakers, which
limits impersonation risk. We still ask that you:
- tell listeners when speech is synthetic, where that matters;
- not use the model for fraud, harassment or deceptive impersonation;
- review output before you use it in safety-critical or high-stakes settings.

## Model details

### Architecture

The model runs in four stages:
1. **Text front end:** espeak-ng converts text to IPA phonemes (en-us, with stress marks). A blank token is inserted
   between phonemes.
2. **Text encoder (3.2M parameters):** 3 ConvNeXt pre-net blocks, then 6 transformer layers (width 192, RoPE, SwiGLU,
   RMSNorm). It predicts a per-phoneme mel prior.
3. **Duration predictor (0.3M parameters):** a convolutional regressor of log-durations. It was trained on alignments from Monotonic
   Alignment Search, so no external aligner is needed.
4. **Decoder (7.9M parameters):** a flow-matching U-Net hybrid.
   - ConvNeXt blocks run at the full frame rate, and four adaLN transformer blocks run at half the frame rate.
   - It uses classifier-free guidance (weight 1.0) and 8 Euler steps with a sway-sampling schedule.
   - It outputs a 100-band log-mel spectrogram (hop 256, 24 kHz).

The vocoder is [Vocos](https://huggingface.co/charactr/vocos-mel-24khz) (charactr/vocos-mel-24khz, MIT). In ONNX it
predicts the STFT magnitude and phase, and the inverse STFT runs in numpy.

### Files

| File | Contents | Size |
|---|---|---:|
| `onnx/encoder.onnx` | Text encoder and duration predictor (fp16 weights, fp32 compute) | 7.2 MB |
| `onnx/decoder-int8.onnx` | One guided flow-matching step (int8 dynamic quantisation) | 9.9 MB |
| `onnx/vocoder.onnx` | Vocos backbone and spectral head (fp16 weights, fp32 compute) | 27.1 MB |
| `onnx/junco.json` | Mel normalisation statistics and default inference settings | <1 kB |
| `samples/` | The audio samples above | |

### Training

| | |
|---|---|
| **Data** | [LJ Speech](https://keithito.com/LJ-Speech-Dataset/): 13,100 clips, about 24 hours, one speaker, public domain |
| **Objective** | Conditional flow matching (logit-normal time sampling, σ_min 1e-4), MAS prior loss, duration MSE |
| **Guidance** | Condition dropped for 10% of training examples, for classifier-free guidance |
| **Optimiser** | AdamW (lr 2e-4, β 0.9/0.98, weight decay 0.01), 1,000 warm-up steps, EMA 0.999 |
| **Batching** | Dynamic batches of up to 20,000 mel frames |
| **Compute** | 44,485 steps in 3 hours on one NVIDIA T4 GPU |
| **Released weights** | EMA weights |

**Environmental impact.** The final training run used about 3 GPU-hours on one NVIDIA T4 (70 W TDP), or about
0.2 kWh. Architecture experiments before it used more.

## FAQ

**Does Junco need a GPU or an internet connection?**
No. It runs on an ordinary CPU with ONNX Runtime. Once installed, speech is generated fully offline and your text
never leaves the machine.

**How big is it?**
44.2 MB in total: a 17.1 MB acoustic model plus the 27.1 MB Vocos vocoder. Junco and Goldfinch share the vocoder, so
both voices together take 61.3 MB.

**Can it run on a Raspberry Pi or other ARM boards?**
It runs on 64-bit ARM Linux wherever `onnxruntime` and `espeakng-loader` publish wheels, including 64-bit Raspberry
Pi OS.

**Can I stream audio for low latency?**
Yes. `tts.stream(text)` yields audio sentence by sentence, so playback can start before the whole text is done.

**Can I use it without Python?**
The ONNX files run in any ONNX Runtime binding. The text front end (espeak-ng phonemes) and the small loop around the
three models live in the [`flockspeech`](https://github.com/flockspeech/flockspeech) package, which you can port.

**Does it support voice cloning or other languages?**
No. Junco is one English (US) voice. For a casual, conversational voice, use
[Goldfinch](https://huggingface.co/flockspeech/goldfinch).

**Can I use it commercially?**
Yes. The weights are Apache-2.0 and the vocoder is MIT. The phonemiser (espeak-ng, phonemizer) is GPL-3.0 and is
installed separately; see the License section below.

## License

- **Junco weights and configuration:** [Apache License 2.0](LICENSE). Commercial use, modification and redistribution
  are allowed.
- **Vocos vocoder weights** (`onnx/vocoder.onnx`): MIT, © 2023 Charactr Inc. See `onnx/LICENSE-vocos`.
- **Training data:** LJ Speech, public domain.

**Run-time dependency.** Text-to-phoneme conversion uses espeak-ng and phonemizer. Both are GPL-3.0 and are **not**
included in this repository. The `flockspeech` package installs them as separate dependencies. If you plan to ship
Junco inside a closed-source product, review their licence terms, or replace the phonemiser with one under a licence
that suits you. See [NOTICE](NOTICE).

## Citation

```bibtex
@misc{flockspeech2026junco,
  title        = {Junco: a small flow-matching text-to-speech model for on-device use},
  author       = {{Flock Speech}},
  year         = {2026},
  howpublished = {\url{https://huggingface.co/flockspeech/junco}},
  note         = {Version 0.1}
}
```

## Links

- Python package: [pypi.org/project/flockspeech](https://pypi.org/project/flockspeech/)
- Source code: [github.com/flockspeech/flockspeech](https://github.com/flockspeech/flockspeech)
- Conversational voice: [flockspeech/goldfinch](https://huggingface.co/flockspeech/goldfinch)

## Acknowledgements

Junco builds on ideas from Matcha-TTS (conditional flow matching for TTS), Glow-TTS (Monotonic Alignment Search),
F5-TTS (sway sampling), ZipVoice and SupertonicTTS (efficient decoder design), and Vocos (vocoder). We thank the authors
of these works and of LJ Speech.