Compatibility: Current model artifacts require
sopro>=2.2.0or@soprotts/onnx-web>=0.3.0; upgrade withpip install -U soproornpm install @soprotts/onnx-web@latest.
Sopro (from the Portuguese word for "breath/blow") is a lightweight voice-cloning text-to-speech model family. This repo ships sopro-v2-turbo, a 120M-parameter open model that streams, runs comfortably on a laptop CPU or in the browser, and reaches SOTA-level intelligibility against much larger systems. The full story, evaluations, and audio samples are in the blog post.
Main features:
Run the model and open the demo with one command:
uvx --from sopro soprotts serve
If Sopro is already installed:
soprotts serve
Then navigate to http://localhost:7860. The model downloads on first use and stays in the Hugging Face cache. Sopro selects CUDA or CPU automatically and defaults to CPU on macOS (pass --device mps explicitly to use MPS). Use soprotts serve --help for model, device, port, and CPU int8 options.
There is also a fully in-browser demo with no server involved: https://samuel-vitorino.github.io/sopro/. On mobile the model is quantized, so results can be slightly below the local demo, and devices with low memory may crash. The dependency-isolated ONNX runtime and exporter are documented in web/README.md. Both demos use the frontend in demos/web.
pip install -U sopro
git clone https://github.com/samuel-vitorino/sopro
cd sopro
pip install -e .
soprotts "Sopro is a lightweight 120 million parameter text-to-speech model that streams and runs on device." --ref ref.wav --out out.wav
Add --stream for the streaming path. You have the expected --temperature, --top-p, and --top-k parameters, alongside:
--lang (en, pt, fr, de; optional, helps pronunciation on ambiguous text)--int8 (int8 AR weights on CPU)--steps (acoustic solver steps; default 2)--max-seconds (cap per generated segment; long text is split into segments, so total length is unbounded)from sopro import SoproTTS
tts = SoproTTS.from_pretrained("samuel-vitorino/sopro-v2-turbo", device="cpu")
wav = tts.synthesize(
"Hello! This is a non-streaming Sopro TTS example.",
ref_audio_path="ref.wav",
)
tts.save_wav("out.wav", wav)
import torch
from sopro import SoproTTS
tts = SoproTTS.from_pretrained("samuel-vitorino/sopro-v2-turbo", device="cpu")
chunks = []
for chunk in tts.stream(
"Hello! This is a streaming Sopro TTS example.",
ref_audio_path="ref.mp3",
):
chunks.append(chunk.cpu())
wav = torch.cat(chunks, dim=-1)
tts.save_wav("out_stream.wav", wav)
You can also precalculate the reference to reduce time-to-first-audio:
import torch
from sopro import SoproTTS
tts = SoproTTS.from_pretrained("samuel-vitorino/sopro-v2-turbo", device="cpu")
ref = tts.prepare_reference(ref_audio_path="ref.mp3", stream=True)
chunks = []
for chunk in tts.stream(
"Hello! This is a streaming Sopro TTS example.",
ref=ref,
):
chunks.append(chunk.cpu())
wav = torch.cat(chunks, dim=-1)
tts.save_wav("out_stream.wav", wav)
1 + 2 should be written one plus two. That said, Sopro generally reads common abbreviations like "CPU" or "TTS" fine, and you can put a language-specific normalizer in front of it.9 commits
Compatibility: Current model artifacts require
sopro>=2.2.0or@soprotts/onnx-web>=0.3.0; upgrade withpip install -U soproornpm install @soprotts/onnx-web@latest.
Sopro (from the Portuguese word for "breath/blow") is a lightweight voice-cloning text-to-speech model family. This repo ships sopro-v2-turbo, a 120M-parameter open model that streams, runs comfortably on a laptop CPU or in the browser, and reaches SOTA-level intelligibility against much larger systems. The full story, evaluations, and audio samples are in the blog post.
Main features:
Run the model and open the demo with one command:
uvx --from sopro soprotts serve
If Sopro is already installed:
soprotts serve
Then navigate to http://localhost:7860. The model downloads on first use and stays in the Hugging Face cache. Sopro selects CUDA or CPU automatically and defaults to CPU on macOS (pass --device mps explicitly to use MPS). Use soprotts serve --help for model, device, port, and CPU int8 options.
There is also a fully in-browser demo with no server involved: https://samuel-vitorino.github.io/sopro/. On mobile the model is quantized, so results can be slightly below the local demo, and devices with low memory may crash. The dependency-isolated ONNX runtime and exporter are documented in web/README.md. Both demos use the frontend in demos/web.
pip install -U sopro
git clone https://github.com/samuel-vitorino/sopro
cd sopro
pip install -e .
soprotts "Sopro is a lightweight 120 million parameter text-to-speech model that streams and runs on device." --ref ref.wav --out out.wav
Add --stream for the streaming path. You have the expected --temperature, --top-p, and --top-k parameters, alongside:
--lang (en, pt, fr, de; optional, helps pronunciation on ambiguous text)--int8 (int8 AR weights on CPU)--steps (acoustic solver steps; default 2)--max-seconds (cap per generated segment; long text is split into segments, so total length is unbounded)from sopro import SoproTTS
tts = SoproTTS.from_pretrained("samuel-vitorino/sopro-v2-turbo", device="cpu")
wav = tts.synthesize(
"Hello! This is a non-streaming Sopro TTS example.",
ref_audio_path="ref.wav",
)
tts.save_wav("out.wav", wav)
import torch
from sopro import SoproTTS
tts = SoproTTS.from_pretrained("samuel-vitorino/sopro-v2-turbo", device="cpu")
chunks = []
for chunk in tts.stream(
"Hello! This is a streaming Sopro TTS example.",
ref_audio_path="ref.mp3",
):
chunks.append(chunk.cpu())
wav = torch.cat(chunks, dim=-1)
tts.save_wav("out_stream.wav", wav)
You can also precalculate the reference to reduce time-to-first-audio:
import torch
from sopro import SoproTTS
tts = SoproTTS.from_pretrained("samuel-vitorino/sopro-v2-turbo", device="cpu")
ref = tts.prepare_reference(ref_audio_path="ref.mp3", stream=True)
chunks = []
for chunk in tts.stream(
"Hello! This is a streaming Sopro TTS example.",
ref=ref,
):
chunks.append(chunk.cpu())
wav = torch.cat(chunks, dim=-1)
tts.save_wav("out_stream.wav", wav)
1 + 2 should be written one plus two. That said, Sopro generally reads common abbreviations like "CPU" or "TTS" fine, and you can put a language-specific normalizer in front of it.9 commits