Day 05,我把 STT、LLM 和 TTS 串成第一版語音對話流程:
STT
↓
LLM
↓
TTS
現在使用者已經可以對著麥克風說話,系統會辨識語音、產生回答,再透過 TTS 播放出來。
但實際使用後,我發現:
可以對話,不代表對話起來自然。
使用者說完一句話後,AI 還是會停頓一下才開始回答。
所以 Day 06 我沒有繼續增加新功能,而是先拆解整條 Pipeline,看看到底是哪個階段造成等待。
實際流程比單純的 STT → LLM → TTS 更完整:
User Speaking
↓
VAD
↓
Speech End
↓
Final STT
↓
LLM
↓
TTS
↓
First Audio
主要延遲可以拆成:
VAD / Speech End
Final STT
LLM
TTS
Playback
每一段可能都只有幾百毫秒,但全部累積起來,就會變成使用者明顯感受到的等待時間。
原本我以為最大的延遲應該來自 LLM 或 TTS,但實際拆開後發現,VAD 本身就會影響體感。
使用者停止說話後,系統不能立刻判定這句話已經結束,因為有可能只是暫時停頓。
所以通常會設定一段靜音時間,例如 700 ms,確認這段時間都沒有再出現語音後,才判定:
Speech End
門檻太長,AI 回應會變慢;門檻太短,又可能把正常停頓誤判成句尾。
因此 VAD 本身就是反應速度與穩定度之間的取捨。
Day 02 我做過 Rolling Transcription,每隔一段時間重新辨識目前累積的音訊。
例如:
0 ~ 2 秒 → STT
0 ~ 4 秒 → STT
0 ~ 6 秒 → STT
這可以讓文字看起來接近即時更新,但本質上還是反覆重新辨識整段音訊,並不是真正的 Streaming ASR。
目前 Day 05 的流程仍然是等到 Speech End 後,再產生 Final STT 丟給 LLM。
Speech End
↓
Final STT
↓
LLM
所以 Final STT 仍然會算在使用者等待的時間裡。
目前 LLM 產生完整回答後,才會把整段文字送給 TTS。
流程是:
Final STT
↓
LLM 完整回答
↓
TTS
↓
Playback
這代表每個模組都必須等待上一個模組完成。
也就是目前的 Sequential Pipeline。
STT → LLM → TTS → Playback
如果 LLM 花 1 秒、TTS 又花 1 秒,這些延遲就會直接累加。
為了之後知道 Streaming 優化到底有沒有變快,我先定義主要指標:
Speech End → First Audio
也就是從系統判定使用者講完,到 AI 第一段聲音真正播放出來的時間。
Speech End
↓
Final STT
↓
LLM
↓
TTS
↓
First Audio
另外也分別記錄:
Final STT Latency
LLM Latency
TTS Latency
這樣才能知道真正的瓶頸在哪裡。
今天最重要的目的,不是把速度做到最快,而是先建立目前 Sequential Pipeline 的 Baseline。
如果沒有優化前的數據,之後就算換成 Streaming,也只能覺得:
好像變快了。
卻沒辦法回答:
到底快多少?
哪一個階段改善最多?
Speech End → First Audio 少了多少?
因此 Day 06 先把目前的延遲量清楚,作為之後比較的基準。
今天最大的發現是:
語音對話的延遲,不只是模型推論速度的問題。
除了 STT、LLM 和 TTS 之外,VAD 的停頓門檻,以及整條 Pipeline 是否需要等待上一個模組完成,都會直接影響使用者的體感。
目前最大的問題就是:
Speech End
↓
Final STT
↓
LLM Complete
↓
TTS Complete
↓
Playback
所有步驟都是一個接一個執行。
Day 05:
先讓整條語音對話流程跑起來。
Day 06:
先量清楚它到底慢在哪裡。
下一步 Day 07,我會開始把整條流程改成 Streaming Voice Pipeline。
除了比較 Day 02 的 Rolling Transcription 和真正的 Streaming ASR,也會加入 LLM Token Streaming、文字 Chunk、Streaming TTS 與 Playback Queue。
目標就是:
不要等全部完成,AI 就能更早開始回答。