Joseph Chen
我的碩士論文研究 Transformer-based TTS,那時候每天都在看 attention map, 試圖理解為什麼模型能把文字的韻律資訊捕捉得如此精準。 現在回頭看,這段研究讓我對深度學習架構有了截然不同的理解。
TTS 是什麼
TTS(Text-to-Speech)是把文字轉換為語音波形的技術。現代 TTS 系統通常分為兩個獨立模型:聲學模型(文字 → Mel Spectrogram)和聲碼器(Mel Spectrogram → 音訊波形)。
TTS 完整 Pipeline
文字
Text
前處理 / G2P
Grapheme-to-Phoneme
聲學模型
Acoustic Model
Mel Spectrogram
頻譜圖
聲碼器
Vocoder
音訊波形
Waveform
傳統方法
- •拼接式合成(Concatenative):把錄製音節拼接
- •參數式合成(Parametric):統計模型預測聲學特徵
- •問題:音質受限、缺乏韻律自然感
深度學習方法
- •端對端學習(End-to-End):直接從文字學語音
- •Transformer 捕捉長距韻律依賴
- •音質接近人聲,韻律更自然
Transformer 架構核心
為什麼 Transformer 取代 RNN?
RNN 的問題
- ✗必須逐步處理序列,無法並行
- ✗序列過長時梯度消失,遺忘早期資訊
- ✗訓練慢,GPU 利用率低
Transformer 的解法
- ✓Self-Attention 同時計算所有位置關係
- ✓任意兩位置距離 O(1),長距依賴直接建模
- ✓高度可並行,充分利用 GPU
Self-Attention 直覺解釋
Self-Attention 讓序列中的每個詞都去問:「我和其他每個詞的相關性有多高?」 這個「相關性」就是 attention score,再用它對 Value 向量做加權平均,得到這個詞的新表示。
// 範例:"The cat sat on the mat"
// "cat" 對 "sat" 的 attention score 高(主詞→動詞關係)
Query (Q)
當前詞在「問」什麼:我在找哪種相關的詞?
Key (K)
每個詞「宣傳」自己的特徵:我是什麼樣的詞?
Value (V)
實際攜帶的語意資訊,attention score 高就多取這個詞的 Value。
Multi-Head Attention
與其只跑一個 Attention,不如並行跑多個(例如 8 個 head),每個 head 學到序列中不同類型的關係 (句法結構、語意相似性、指代關係等),最後把所有 head 的結果 concat 起來,表達能力更豐富。
Transformer-based TTS:FastSpeech2
FastSpeech2 是微軟研究院在 2021 年提出的非自回歸 TTS 架構, 解決了前代 Tacotron2 推論速度慢、需要逐幀生成的瓶頸。 它是我碩士論文的核心研究對象之一。
FastSpeech2 架構
Text
Encoder
Duration Predictor
Length Regulator
Decoder
Mel Spectrogram
Pitch Predictor 和 Energy Predictor 並行接在 Encoder 後,提供韻律控制
Duration Predictor 是什麼?
每個音素(Phoneme)在語音中佔據不同時間長度,例如「A」可能對應 8 個 Mel frame,「T」可能只有 3 個。 Duration Predictor 預測每個音素要「拉長」成幾個 frame,Length Regulator 再據此複製對應次數, 使 Encoder 輸出的音素序列長度對齊 Mel Spectrogram 的時間步長——這是韻律節奏控制的核心機制。
| 特性 | Tacotron2 | FastSpeech2 |
|---|---|---|
| 推論方式 | 自回歸(逐幀生成) | 非自回歸(一次生成全部) |
| 推論速度 | 慢(速度與序列長度成正比) | 快(約 10x 加速) |
| 韻律控制 | 隱式(Attention 自動學習) | 顯式(Pitch / Energy / Duration Predictor) |
| 訓練複雜度 | 較簡單(不需 Duration Aligner) | 需要 Duration Aligner(MFA 對齊工具) |
| 音質穩定性 | 偶有 skipping / repeating 現象 | 穩定,無自回歸累積誤差 |
聲碼器(Vocoder)
聲學模型輸出的是 Mel Spectrogram——一種壓縮過的頻譜表示,人耳無法直接聆聽。 聲碼器負責把它還原成 24kHz 或 44.1kHz 的音訊波形。
WaveNet
自回歸- •Google 2016 年提出,里程碑式成果
- •音質極高,接近人聲
- •逐樣本自回歸生成,24kHz 音訊需要 24000 次推論/秒
- •實時因子(RTF)遠大於 1,無法即時推論
HiFi-GAN
GAN-based- •Jungil Kong 等人 2020 年提出
- •GAN 架構:Generator 生成波形,Discriminator 判別真偽
- •RTF < 0.1,比實時快 10 倍以上
- •音質比 WaveNet 稍低,但工程實用性高得多
嵌入式部署挑戰
在 Raspberry Pi 或工廠邊緣設備上跑 TTS,比在伺服器上難一個數量級。 以下是我在研究嵌入式推論時遇到的主要挑戰與解法:
模型大小 vs 推論速度取捨
FastSpeech2 + HiFi-GAN 合計可能超過 150MB。嵌入式儲存有限,但壓縮模型會影響音質。實務上先砍 HiFi-GAN 的 channel 數(從 512 降到 128),音質可接受,模型縮小 4x。
量化(Quantization):FP32 → INT8
把模型權重從 32-bit 浮點數壓縮到 8-bit 整數,模型大小減少 4x,推論速度在 CPU 上可提升 2–3x。代價是音質輕微下降(MCD 分數約增加 0.3–0.8dB)。PyTorch 的 torch.quantization 模組可處理靜態量化。
ONNX 匯出(Framework Agnostic 推論)
把 PyTorch 模型匯出為 ONNX 格式,使用 ONNX Runtime 推論,消除 PyTorch 的 overhead,並支援各種硬體加速後端(ARM CPU、Intel OpenVINO、NVIDIA TensorRT)。嵌入式環境通常比 PyTorch 快 20–40%。
Raspberry Pi 上跑 TTS 的瓶頸
Raspberry Pi 4(4GB RAM)的 CPU 是 ARM Cortex-A72,跑 FastSpeech2 + HiFi-GAN(量化後)的 RTF 約 0.8–1.2,勉強接近實時但不穩定。主要瓶頸是 HiFi-GAN 的上採樣卷積層。解法之一是把聲碼器部分移到邊緣伺服器,設備只跑聲學模型。
PyTorch 模型推論基本流程
以下是 FastSpeech2 + Vocoder 推論的核心程式碼結構。torch.no_grad() 確保推論時不計算梯度,節省記憶體;map_location='cpu' 讓在 GPU 訓練的模型可以在無 GPU 環境載入。
面試常考題
Transformer 相較 RNN 的優勢是什麼?
兩個核心優勢:① 並行計算——RNN 必須一步步順序處理序列,無法並行;Transformer 的 Self-Attention 可以同時計算序列中所有位置的關係,訓練速度大幅提升。② 長距依賴——RNN 在序列很長時容易「遺忘」早期資訊(梯度消失問題);Self-Attention 讓任意兩個位置的距離都是 O(1),長距依賴建模更直接。
Self-Attention 的計算複雜度是多少?
O(n²d),其中 n 是序列長度,d 是 embedding 維度。每個位置需要和其他所有 n 個位置計算 attention score,所以複雜度是 n² 級別。這是 Transformer 的主要瓶頸:序列長度一倍,計算量四倍。這也是為什麼後續出現了 Linear Attention、Sparse Attention 等變體,試圖把複雜度降到 O(n log n) 甚至 O(n)。
什麼是 Non-autoregressive TTS?優勢是?
傳統自回歸(Autoregressive)TTS 如 Tacotron2,每次只生成一個 frame 的 Mel Spectrogram,需要用前一個 frame 的輸出來預測下一個,無法並行。Non-autoregressive 如 FastSpeech2,一次把整個序列的 Mel Spectrogram 都生成出來,速度提升可達 10x 以上。代價是需要額外的 Duration Predictor 來決定每個音素對應幾個 frame,以及 Teacher Forcing 訓練策略。
如何評估 TTS 系統的品質?
主觀評估用 MOS(Mean Opinion Score):讓真人聽多段音訊並評分(1–5 分),取平均,是最接近使用者體驗的指標,但費時費力。客觀評估用 MCD(Mel Cepstral Distortion):計算生成 Mel Spectrogram 和參考音訊之間的距離,數值越低越好,可自動化計算。實務上通常兩者並用:客觀指標用於快速迭代,MOS 用於最終發布前的人工驗證。
嵌入式部署 TTS 時主要的挑戰是什麼?
三個核心挑戰:① 模型大小——聲學模型 + 聲碼器合計可能超過 100MB,嵌入式儲存有限;② 推論速度——即時 TTS 要求每句話在 200ms 內開始出聲,CPU-only 環境達到這個目標非常難;③ 記憶體——FP32 模型推論時的 activation memory 可能超過設備 RAM。常見解法:量化到 INT8(模型縮小 4x,但音質有損)、ONNX 匯出(消除 PyTorch overhead)、分離聲碼器(只把聲學模型跑在設備上,聲碼器跑在伺服器)。
這篇學到什麼
上一篇
EP.03 — Dify 工作流程設計
在本地 LLM 前加 Orchestration 層
下一篇
EP.05 — 即將推出
Coming Soon