Local AI · DGX Spark
AI 聲音工作室
錄一段中文、一段英文,AI 就能用你的聲音朗讀任何講稿。
Qwen3-TTS 地端聲紋 clone,逐句串流播放,讀到哪句亮到哪句。
實際介面・Playwright 實機截圖
為什麼要自己蓋一個
錄旁白、配音很花時間:請人配音要約時間,用現成 TTS 又是罐頭聲音,聽起來一點都不像自己。有沒有可能打字就有「自己」在念稿?
DGX Spark 上跑 Qwen3-TTS,錄中文、英文各一段當範例,就能萃取出自己的聲紋。之後不管講稿多長,都是用你的音色念出來。
難的有兩件事:長講稿的等待感,還有聲紋資料要怎麼收才安全。
原理:一段語音的旅程
從錄一句話到逐句高亮播放,中間發生五件事。
建立聲紋
錄中文、英文各一段,本地 Qwen3-TTS-12Hz-1.7B-Base 從中萃取聲紋特徵存成 profile,clone 功能只支援這顆 Base 模型。
講稿輸入
貼上要唸的文字,或直接請內建的本地 LLM 產文案、做翻譯,得到完整講稿。
前端分句
依標點把講稿切成句子,過短的句子自動合併,每段控制在 200 字以內,避免單次合成拖太久。
逐句串流合成
用你的聲紋逐句送進 TTS 合成,第一句回來就先播,同時 lookahead-1 預先抓下一句,把開口前的等待壓到最低。
逐句高亮播放
前端邊播邊把正在念的句子高亮,方便對照文字;播完可以合併下載成一份完整音檔。
原理深掘:分句與串流合成引擎
長講稿不能等整段合成完才播——關鍵是把文字切成穩定的短句,並在使用者聽第一句時就把後面幾句準備好。以下是工具實際跑的分句與預取邏輯。
錄音樣本
中文+英文各一段
MediaRecorder
POST /tts/embed
聲紋抽取
Qwen3-TTS-12Hz-1.7B-Base
embedding 2048 維
約 11KB,無狀態即丟
splitScriptIntoSentences()
分句器
標點斷句 。..!?!?
單句 >190 字再切・<10 字合併
/tts/speak_stateless ×N
逐句合成
bf16 CUDA・RTF≈0.75
PREFETCH_DEPTH=3 句預排
attachReadHighlight()
逐句高亮播放
<span data-seg> 逐句上色
對齊當前播放句
AudioContext 合併
匯出下載
逐句 Blob 串接
輸出單一 WAV
模型與延遲
Qwen3-TTS-12Hz-1.7B-Base・3.4GB・bf16 CUDA
首句約 2–4 秒開口・單句合成 4.6–6.2 秒・300 字長文近似 1.5× 實時
RTF≈0.75(合成速度快於播放速度,預取才追得上)・embedding 只落地瀏覽器 IndexedDB
3.4GB
Qwen3-TTS-12Hz-1.7B-Base 模型大小
~1.5×
300 字長文分段串接近似實時倍數
4.6–6.2s
單句合成耗時
關鍵設計決策
隱私 local-first
聲紋預設只存在瀏覽器 IndexedDB,伺服器端用完即丟;要跨裝置使用才需要明確同意存到伺服器,且隨時可以刪除。
lookahead-1 預取,壓開口延遲
分句串流時提前合成下一句,使用者聽完第一句時,下一句幾乎已經備好,長講稿也不會卡在開頭乾等。
短句合併 + 200 字上限
標點切句避免斷在奇怪的地方,過短的片段自動合併,讓每次合成的長度落在穩定的甜蜜點。
本地 ASR 往返驗證合成品質
用本地語音辨識回頭檢查 TTS 產出是否清楚可辨,抓出合成失真,不用光靠耳朵盲聽把關。
技術架構
Frontend
三步流程(建聲/講稿/朗讀)
逐句高亮播放
合併下載整份音檔
Voice Clone
Qwen3-TTS-12Hz-1.7B-Base
中英各一段建立聲紋
3.4GB 模型
Streaming
分句 + lookahead-1
短句合併 <200 字
AbortController 中止在途請求
Privacy
預設存瀏覽器 IndexedDB
明確同意才存伺服器
隨時可刪
線上工具已上鎖(Basic Auth)・本頁分享架構與設計