Local AI · DGX Spark
AI Voice Studio
Record one Chinese sample and one English sample, and AI reads any script in your own voice.
Qwen3-TTS voice cloning, running locally, streamed sentence by sentence with live highlight.
The live interface — captured with Playwright
Why build one
Recording narration takes real time — hiring a voice actor means scheduling, and off-the-shelf TTS gives you a canned voice that sounds nothing like you. What if typing text was enough to have "you" reading it out loud?
Qwen3-TTS runs on the DGX Spark at home. Record one Chinese sample and one English sample, and it extracts your voice profile. From then on, any script — however long — comes out in your own voice.
There are two real challenges: the wait on long scripts, and how safely the voice data itself is handled.
How it works: the journey of one reading
From recording one sample to sentence-by-sentence highlighted playback — five things happen in between.
Build a voice profile
Record one sample in Chinese and one in English; the local Qwen3-TTS-12Hz-1.7B-Base model extracts a voice profile from them — cloning is only supported on this Base model.
Enter the script
Paste the text to read, or ask the built-in local LLM to draft copy or translate it, and you have a complete script.
The frontend splits it into sentences
The script is split on punctuation, short fragments are merged, and each chunk stays under 200 characters so no single synthesis call drags on.
Sentence-by-sentence streaming synthesis
Each sentence is synthesized in your voice; the first one plays as soon as it's ready, while a lookahead-1 buffer pre-fetches the next sentence, keeping time-to-first-sound to a minimum.
Sentence-by-sentence highlighted playback
The frontend highlights the sentence currently playing so it's easy to follow along; once finished, everything can be merged into a single downloadable audio file.
Deep dive: the sentence-splitting and streaming synthesis engine
A long script can't wait for the whole thing to synthesize before it plays — the trick is splitting text into stable short sentences and having the next few ready before the listener finishes the first one. Here's the actual splitting and prefetch logic the tool runs.
Recording samples
One Chinese + one English sample
MediaRecorder
POST /tts/embed
Voice profile extraction
Qwen3-TTS-12Hz-1.7B-Base
Embedding, 2048-dim
~11KB, stateless, discarded after
splitScriptIntoSentences()
Sentence splitter
Splits on 。..!?!?
>190 chars re-cut・<10 chars merged
/tts/speak_stateless ×N
Per-sentence synthesis
bf16 CUDA・RTF≈0.75
PREFETCH_DEPTH=3 sentences queued ahead
attachReadHighlight()
Sentence-by-sentence highlight
<span data-seg> per sentence
synced to current playback
AudioContext merge
Export & download
Per-sentence blobs concatenated
exported as one WAV
Model & latency
Qwen3-TTS-12Hz-1.7B-Base・3.4GB・bf16 CUDA
First sentence in ~2–4s・per-sentence synthesis 4.6–6.2s・~1.5× near-realtime for a 300-char script
RTF≈0.75 (synthesis outruns playback, which is what makes prefetch work)・embeddings never leave the browser's IndexedDB
3.4GB
Qwen3-TTS-12Hz-1.7B-Base model size
~1.5×
near-realtime multiplier for a 300-char script
4.6–6.2s
per-sentence synthesis time
Key design decisions
Privacy, local-first
Voice profiles default to the browser's IndexedDB only, discarded server-side right after use. Cross-device use requires explicit opt-in to store on the server, and it can be deleted at any time.
Lookahead-1 pre-fetch cuts time-to-first-sound
The next sentence is synthesized ahead of time during streaming, so by the time the first sentence finishes playing, the next one is nearly ready — even long scripts don't stall at the start.
Short-sentence merging + a 200-character cap
Splitting on punctuation avoids awkward cut points, and merging short fragments keeps every synthesis call within a stable sweet spot.
Local ASR round-trip verifies synthesis quality
A local speech recognizer checks the TTS output for intelligibility, catching synthesis artifacts instead of relying purely on ear-checking.
Architecture
Frontend
Three-step flow (voice / script / read)
sentence-by-sentence highlight
merged audio download
Voice Clone
Qwen3-TTS-12Hz-1.7B-Base
one Chinese + one English sample
3.4GB model
Streaming
Sentence splitting + lookahead-1
short-sentence merge <200 chars
AbortController cancels in-flight requests
Privacy
Defaults to browser IndexedDB
server storage requires explicit consent
deletable anytime
The live tool is locked behind Basic Auth — this page shares the architecture and design.