square-zero-labs/Supertonic-TTS-ONNX
By square-zero-labs · ↓ 7 · ♥ 0 · Updated 2026-02-13
What's in this repo
This page lists the files in square-zero-labs/Supertonic-TTS-ONNX, including latent_denoiser.onnx, text_encoder.onnx, voice_decoder.onnx.
- 3 ONNX models (.onnx files)
- 21 files, including 10 .bin, 3 .json, 3 .onnx, 3 .onnx_data, 1 .md
- Last updated 2026-02-13
ONNX files
| File | Size | Download |
|---|---|---|
| onnx/latent_denoiser.onnx | — | Download |
| onnx/text_encoder.onnx | — | Download |
| onnx/voice_decoder.onnx | — | Download |
How to use
These ONNX files can be loaded with ONNX Runtime. To inspect a model graph, upload the file to the Netron viewer. Download links point to the original files on Hugging Face.
README
Usage
Transformers.js
If you haven't already, you can install the Transformers.js JavaScript library from NPM using:
npm i @huggingface/transformers
You can then generate audio as follows:
import { pipeline } from '@huggingface/transformers';
const tts = await pipeline('text-to-speech', 'onnx-community/Supertonic-TTS-ONNX');
const input_text = 'This is really cool!';
const audio = await tts(input_text, {
speaker_embeddings: 'https://huggingface.co/onnx-community/Supertonic-TTS-ONNX/resolve/main/voices/F1.bin',
num_inference_steps: 5, // Higher = better quality (typically 1-50)
speed: 1.05, // Higher = faster speech (typically 0.8-1.2)
});
await audio.save('output.wav'); // or `audio.toBlob()`;
ONNXRuntime
First, let's create a helper class, SupertonicTTS:
import os
import numpy as np
import onnxruntime as ort
from transformers import AutoTokenizer
class SupertonicTTS:
SAMPLE_RATE = 44100
CHUNK_COMPRESS_FACTOR = 6
BASE_CHUNK_SIZE = 512
LATENT_DIM = 24
STYLE_DIM = 128
LATENT_SIZE = BASE_CHUNK_SIZE * CHUNK_COMPRESS_FACTOR
def __init__(self, model_path):
self.model_path = model_path
self.tokenizer = AutoTokenizer.from_pretrained(self.model_path)
# Load ONNX sessions
self.text_encoder = ort.InferenceSession(os.path.join(self.model_path, "onnx", "text_encoder.onnx"))
self.latent_denoiser = ort.InferenceSession(os.path.join(self.model_path, "onnx", "latent_denoiser.onnx"))
self.voice_decoder = ort.InferenceSession(os.path.join(self.model_path, "onnx", "voice_decoder.onnx"))
def _load_style(self, voice: str) -> np.ndarray:
voice_path = os.path.join(self.model_path, "voices", f"{voice}.bin")
if not os.path.exists(voice_path):
raise ValueError(f"Voice '{voice}' not found.")
style_vec = np.fromfile(voice_path, dtype=np.float32)
return style_vec.reshape(1, -1, self.STYLE_DIM)
def generate(self, text: list[str], *, voice: str = "M1", speed: float = 1.0, steps: int = 5) -> list[np.ndarray]:
# 1. Prepare Text Inputs
inputs = self.tokenizer(text, return_tensors="np", padding=True, truncation=True)
input_ids = inputs["input_ids"]
attn_mask = inputs["attention_mask"]
batch_size = input_ids.shape[0]
# 2. Prepare Style
style = self._load_style(voice).repeat(batch_size, axis=0)
# 3. Text Encoding
last_hidden_state, raw_durations = self.text_encoder.run(
None,
{"input_ids": input_ids, "attention_mask": attn_mask, "style": style}
)
durations = (raw_durations / speed * self.SAMPLE_RATE).astype(np.int64)
# 4. Latent Preparation
latent_lengths = (durations + self.LATENT_SIZE - 1) // self.LATENT_SIZE
max_len = latent_lengths.max()
latent_mask = (np.arange(max_len) < latent_lengths[:, None]).astype(np.int64)
latents = np.random.randn(batch_size, self.LATENT_DIM * self.CHUNK_COMPRESS_FACTOR, max_len).astype(np.float32)
latents *= latent_mask[:, None, :]
# 5. Denoising Loop
num_inference_steps = np.full(batch_size, steps, dtype=np.float32)
for step in range(steps):
timestep = np.full(batch_size, step, dtype=np.float32)
latents = self.latent_denoiser.run(
None,
{
"noisy_latents": latents,
"latent_mask": latent_mask,
"style": style,
"encoder_outputs": last_hidden_state,
"attention_mask": attn_mask,
"timestep": timestep,
"num_inference_steps": num_inference_steps,
},
)[0]
# 6. Decode Latents to Audio
waveforms = self.voice_decoder.run(None, {"latents": latents})[0]
# 7. Post-process: Trim padding and return list of arrays
results = []
for i, length in enumerate(latent_mask.sum(axis=1) * self.LATENT_SIZE):
results.append(waveforms[i, :length])
return results
Next, we clone this repository (using whichever way you want, git clone, huggingface_hub, etc.)
# (Optional) Download model files (or use existing local directory)
from huggingface_hub import snapshot_download
model_id = "onnx-community/Supertonic-TTS-ONNX"
local_dir = "supertonic"
snapshot_download(model_id, local_dir=local_dir)
We can then use the model as follows:
# Initialize TTS
tts = SupertonicTTS(local_dir)
# Generate audio
prompts = [
"Once upon a time, there was a brave knight.",
"Refactoring code makes it much easier to read!",
"I love this!"
]
audio_data = tts.generate(prompts, voice="M1", speed=1.0, steps=10)
# (Optional) Save to files
import soundfile as sf
for i, audio in enumerate(audio_data):
filename = f"output_{i}.wav"
sf.write(filename, audio, tts.SAMPLE_RATE)
print(f"Saved {filename}")
Model info
Created: 2026-02-13
Updated: 2026-02-13
View on Hugging Face