AI 工程從零開始|Phase 6 Part 1:自動語音辨識 — 讓機器聽懂人類

大多數人以為語音辨識就是「把錄音丟給 API 拿文字」。 但真正的工程挑戰是:如何在 300ms 內完成辨識、處理口音與噪音、控制串流延遲? 不懂聲學特徵與解碼策略,你只是在呼叫別人的黑盒子。 理解 ASR 架構,才能在延遲、準確率、成本之間做出有根據的取捨。


面試情境

你正在設計一個線上教育平台的即時字幕系統,需要支援 10,000 位同時在線的學生。系統要求:辨識延遲 < 500ms、WER < 10%、支援中英文混合語音。請說明你的 ASR 架構選擇,以及如何在 POC 到 Scale 的過程中演進這個系統。


一、核心問題:語音辨識的工程挑戰

語音辨識(Automatic Speech Recognition,ASR)聽起來簡單:輸入聲音、輸出文字。但工程上的挑戰遠比想像中複雜。

三大核心張力

  1. 準確率 vs 延遲:離線 batch 辨識可以拿到最好的準確率(Whisper large-v3 WER 4.2%),但需要等音訊結束後才能處理。串流辨識要求 < 300ms 的 partial result,但準確率可能下降 15–30%。

  2. 通用性 vs 領域適應:預訓練模型在 clean speech 上表現優秀,但在特定領域(醫療術語、程式碼朗讀、帶口音的中文)WER 可能飆升至 30%+。Fine-tune 需要標注資料,成本每小時約 $50–200。

  3. 成本 vs 自建:呼叫雲端 ASR API 每分鐘約 $0.006–0.024,自建 Whisper 在 GPU 上每分鐘約 $0.001–0.003,但需要維運成本。

語音訊號的本質困難

時間 (秒)  0.0   0.1   0.2   0.3   0.4   0.5
           ┌─────┬─────┬─────┬─────┬─────┐
波形振幅   │~~~~~│~^~^~│^^^^^│~^~^~│~~~~~│
           └─────┴─────┴─────┴─────┴─────┘
問題:                │
  ├─ 共同發音(Co-articulation):「你好」的「你」受「好」影響
  ├─ 說話速度變異:同一句話 0.5x 到 2x 速度
  ├─ 背景噪音:SNR 從 -5dB 到 40dB
  └─ 口音與方言:同樣的字,頻率分佈完全不同

WER(Word Error Rate)是核心指標:

WER = (Substitutions + Deletions + Insertions) / Total Reference Words × 100%

業界基準:LibriSpeech test-clean 上,Whisper large-v3 = 2.7%、Conformer-CTC = 3.1%、商業 API 平均 = 4–8%。


二、三個演進階段

Phase 1:POC(< 1,000 用戶,延遲容忍 2s)

目標:驗證語音辨識可行性,快速上線,不需要自建模型。

╔══════════════════════════════════════════════════════╗
║  Phase 1:雲端 API 直連架構                           ║
╚══════════════════════════════════════════════════════╝

用戶端瀏覽器
     │  WebRTC / MediaRecorder
     ▼
┌────────────────┐
│  API Gateway   │  (REST,最大 25MB 音訊)
└───────┬────────┘
        │  整段音訊上傳
        ▼
┌────────────────┐
│  雲端 ASR API  │  OpenAI Whisper API / AWS Transcribe
│  (無狀態呼叫)  │  回應時間:1–5 秒
└───────┬────────┘
        │  JSON 文字結果
        ▼
┌────────────────┐
│  應用伺服器    │  存入 DB,回傳前端
└────────────────┘

成本:$0.006/min × 1,000 用戶 × 平均 10 min = $60/日
延遲:2–5 秒(等待上傳 + API 處理)
WER:5–8%(通用模型)

Phase 1 的可接受捷徑

  • 不做串流,整段錄音後上傳
  • 不做降噪前處理
  • 不支援自訂詞彙表(Vocabulary)
  • 音訊格式由前端決定(mp3/wav 混用)

Phase 1 剩餘問題:延遲太高、成本隨用戶線性增長、無法做即時字幕。


Phase 2:MVP(1,000–50,000 用戶,延遲 < 500ms)

目標:支援即時字幕,降低 API 成本,引入語音前處理管線。

╔══════════════════════════════════════════════════════╗
║  Phase 2:自建前處理 + 混合推理架構                   ║
╚══════════════════════════════════════════════════════╝

用戶端瀏覽器
     │  WebSocket(每 200ms 送一個音訊 chunk)
     ▼
┌─────────────────────────────────────────────────────┐
│  WebSocket 閘道(Nginx / FastAPI)                   │
└──────────────┬──────────────────────────────────────┘
               │
       ┌───────┴──────────┐
       ▼                  ▼
┌─────────────┐    ┌──────────────────┐
│  音訊前處理  │    │  VAD 端點偵測    │
│  - 降噪     │    │  WebRTC VAD      │
│  - 正規化   │    │  silence = skip  │
│  - 格式轉換 │    └──────────────────┘
└──────┬──────┘
       │  PCM 16kHz mono
       ▼
┌─────────────────────────────────────────────────────┐
│  推理服務(Triton Inference Server)                 │
│  ┌─────────────────┐  ┌──────────────────────────┐  │
│  │  Whisper small  │  │  Whisper medium (fallback)│  │
│  │  GPU: T4        │  │  GPU: A10G                │  │
│  │  latency: 80ms  │  │  latency: 180ms           │  │
│  └─────────────────┘  └──────────────────────────┘  │
└──────────────────────────────────────────────────────┘
       │
       ▼
┌─────────────┐
│  結果後處理  │  標點符號預測、大小寫修正
└──────┬──────┘
       │  WebSocket 推送 partial/final result
       ▼
    用戶端

成本:GPU 雲端實例 $0.38/h,10 並發 = $0.038/h
     vs 雲端 API $0.006/min × 50K 用戶 = $3,000+/日
延遲:150–300ms(端到端)
WER:6–10%(small model,噪音環境)

Phase 2 新增元件

  • VAD(Voice Activity Detection):靜音跳過,減少 40% 無效推理
  • 音訊正規化:統一採樣率 16kHz、單聲道、振幅正規化
  • 結果快取:相同音訊 hash 直接回傳(適用錄播場景)

Phase 2 剩餘問題:高並發時 GPU 排隊延遲、無法做領域微調、中英混合辨識差。


Phase 3:Scale(50,000–500,000 用戶,P99 延遲 < 300ms)

目標:多模型路由、自動擴縮、領域微調、成本最佳化。

╔══════════════════════════════════════════════════════╗
║  Phase 3:企業級多模型串流 ASR 架構                   ║
╚══════════════════════════════════════════════════════╝

用戶端
  │ WebRTC DataChannel(OPUS 編碼,16kHz)
  ▼
┌──────────────────────────────────────────────────────┐
│  全球 CDN 邊緣節點(就近接入)                        │
│  音訊 chunk → Kafka topic: audio-stream-{region}     │
└──────────────────────────────────────────────────────┘
          │
          ▼
┌──────────────────────────────────────────────────────┐
│  串流處理層(Flink / Kafka Streams)                 │
│  ┌──────────────┐  ┌────────────────┐               │
│  │  音訊拼接器  │  │  語言偵測模組  │               │
│  │  滑動視窗    │  │  中/英/日 分流 │               │
│  │  30s buffer  │  └────────────────┘               │
│  └──────────────┘                                   │
└──────────────────────────────────────────────────────┘
          │
          ▼
┌──────────────────────────────────────────────────────┐
│  模型路由器(依語言、SNR、領域分流)                 │
│  ┌──────────┐ ┌───────────┐ ┌──────────────────────┐ │
│  │ Whisper  │ │ Fine-tune │ │  領域專用模型         │ │
│  │ large-v3 │ │ 中文教育  │ │  (醫療/法律/程式碼)  │ │
│  │ WER 4.2% │ │ WER 6.8% │ │  WER 3.1–5.5%        │ │
│  └──────────┘ └───────────┘ └──────────────────────┘ │
│  GPU 自動擴縮:A100 × 2–32,P99 佇列時間 < 50ms     │
└──────────────────────────────────────────────────────┘
          │
          ▼
┌──────────────────────────────────────────────────────┐
│  後處理管線                                          │
│  標點 → 大小寫 → 敏感詞過濾 → 段落分割              │
└──────────────────────────────────────────────────────┘
          │
          ▼
    WebSocket 推送 + 結果存入 Elasticsearch

成本:A100 spot instance $1.8/h,動態擴縮
     平均 0.8× 使用率 = $1.44/h per A100
     50K 並發 ≈ 50 張 GPU = $72/h = $1,728/日
     vs 雲端 API = $43,200/日(節省 96%)
延遲:P50 120ms,P99 280ms
WER:4.2–6.8%(依模型與場景)

三、聲學特徵:波形 → MFCC → Mel Spectrogram

語音辨識的第一步:把時域波形轉換為神經網路可以處理的特徵表示。

波形到頻譜的轉換流程

原始波形(PCM)
  │  採樣率:16,000 Hz
  │  每秒 16,000 個振幅數值
  ▼
┌────────────────────────────────────────────┐
│  預強調(Pre-emphasis)                    │
│  y[t] = x[t] - 0.97 × x[t-1]             │
│  目的:補償高頻衰減,增強輔音清晰度        │
└────────────────┬───────────────────────────┘
                 │
                 ▼
┌────────────────────────────────────────────┐
│  分幀(Framing)                           │
│  幀長:25ms = 400 個取樣點                 │
│  幀移:10ms = 160 個取樣點(75% 重疊)     │
│  1 秒音訊 → 約 100 幀                      │
└────────────────┬───────────────────────────┘
                 │
                 ▼
┌────────────────────────────────────────────┐
│  加窗(Hamming Window)                    │
│  消除幀邊界的頻譜洩漏                      │
└────────────────┬───────────────────────────┘
                 │
                 ▼
┌────────────────────────────────────────────┐
│  FFT(快速傅立葉轉換)                     │
│  400 點 → 201 個頻率 bin(0–8000 Hz)      │
└────────────────┬───────────────────────────┘
                 │
         ┌───────┴────────┐
         ▼                ▼
┌────────────────┐  ┌─────────────────────────┐
│  MFCC 路徑     │  │  Mel Spectrogram 路徑    │
│                │  │                         │
│  Mel Filterbank│  │  Mel Filterbank(80 維)│
│  → Log         │  │  → Log                  │
│  → DCT(13維) │  │  直接輸出 80×T 矩陣     │
│  傳統 ASR 首選 │  │  現代深度學習首選        │
└────────────────┘  └─────────────────────────┘

為什麼用 Mel Scale?

人耳對頻率的感知是非線性的:1000Hz 到 2000Hz 感覺差不多是一個八度,但 8000Hz 到 16000Hz 也是一個八度。Mel Scale 模仿人耳特性:

Mel(f) = 2595 × log10(1 + f/700)

頻率(Hz):  100  500  1000  2000  4000  8000
Mel 值:       150  607  1000  1474  2146  2840
線性間距→非線性壓縮,低頻細緻、高頻粗粒

Mel Spectrogram 形狀

  • 輸入:30 秒音訊
  • 輸出:80 × 3,000 的矩陣(80 個 Mel bin,每 10ms 一幀,共 3,000 幀)
  • Whisper 使用:80 Mel bin,固定填充到 30 秒 = 80 × 3,000

四、傳統 ASR:GMM-HMM 到 DNN-HMM

理解傳統方法有助於掌握現代端對端模型解決了什麼問題。

GMM-HMM 架構(1990–2010 年代主流)

音訊幀序列 x₁, x₂, ..., xₜ
     │
     ▼  GMM(高斯混合模型)
P(xₜ | 音素狀態 qₜ)   ← 聲學模型
     │
     ▼  HMM(隱馬可夫模型)
P(q₁, q₂, ..., qₜ)    ← 時序模型
     │
     ▼  語言模型(N-gram)
P(w₁, w₂, ..., wₙ)    ← 語言約束
     │
     ▼
文字序列

GMM-HMM 的核心問題

  1. 每個音素需要手工標注對齊(Forced Alignment),成本極高
  2. GMM 假設特徵獨立,無法捕捉長距離依賴
  3. 管線各模組獨立訓練,無法聯合最佳化

DNN-HMM(2012–2018):用深度神經網路替換 GMM,準確率提升 20–30%,但仍需要音素對齊資料。

瓶頸:端對端訓練需要解決「輸入序列(音訊幀)和輸出序列(文字)長度不對齊」的問題。這正是 CTC 和 Attention 機制的切入點。


五、端對端 ASR:CTC vs Attention-based

CTC(Connectionist Temporal Classification)

CTC 引入特殊 blank token,允許神經網路輸出與輸入等長的序列,再通過 marginalization 折疊重複和 blank。

輸入幀:  [h] [h] [e] [_] [l] [l] [_] [o]
                      ↑ blank token
CTC 路徑一:  h  h  e  _  l  l  _  o  → "hello"
CTC 路徑二:  _  h  e  e  l  _  l  o  → "hello"(等效)
CTC 路徑三:  h  _  e  l  l  l  _  o  → "hello"(等效)

CTC Loss = -log Σ(所有等效路徑的機率)

優點:
  ✓ 不需要音素對齊標注,只需要 (音訊, 文字) pair
  ✓ 解碼速度快,適合串流(左到右,無需看未來幀)
  ✓ 可以做 beam search + 語言模型整合

缺點:
  ✗ 條件獨立假設:每幀輸出獨立,無法捕捉輸出 token 之間的依賴
  ✗ 對長文本準確率不如 Attention

Attention-based Seq2Seq(2016–今)

編碼器(Encoder)                解碼器(Decoder)
                                      │
音訊幀序列                       自回歸生成
[f₁][f₂][f₃]...[fₜ]            「你」→「好」→「世」→「界」
      │                               │
      ▼  BiLSTM / Conformer            ▼  LSTM / Transformer
[h₁][h₂][h₃]...[hₜ]  ──Attention──▶  [c₁][c₂][c₃]...

優點:
  ✓ Decoder 可以看到之前生成的所有 token(語言建模能力強)
  ✓ Attention 對齊可視化,可解釋性好
  ✓ WER 通常優於 CTC 10–20%(clean speech 上)

缺點:
  ✗ 自回歸解碼,無法並行,串流延遲高
  ✗ 需要等音訊結束才能開始解碼(offline)

混合策略(CTC/Attention Joint Training):現代最佳實踐。

Loss = λ × CTC_Loss + (1-λ) × Attention_Loss,λ = 0.3

推理時:
  ├─ 串流場景 → 純 CTC decode(即時輸出)
  └─ 批次場景 → Attention rescore(準確率最佳化)

六、Whisper 架構:OpenAI 的工程選擇

Whisper 是目前最廣泛使用的開源 ASR 模型,理解其架構選擇是面試的核心考點。

訓練資料:680,000 小時弱監督標注音訊(網路爬取字幕),覆蓋 99 種語言。

模型規模

模型參數量VRAM推理時間/分鐘音訊LibriSpeech WER
tiny39M1GB0.8s (CPU)8.7%
base74M1GB1.2s (CPU)6.4%
small244M2GB4s (CPU)4.8%
medium769M5GB12s (CPU)3.8%
large-v31550M10GB30s (CPU)2.7%

Whisper 架構設計

┌─────────────────────────────────────────────────────────────┐
│                     Whisper 架構                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  音訊輸入(30秒,填充到固定長度)                           │
│       │                                                     │
│       ▼                                                     │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  音訊編碼器(Transformer Encoder)                  │   │
│  │  80 Mel × 3000 幀                                   │   │
│  │  → 2 × Conv1D(stride=2,下採樣 4×)                │   │
│  │  → Sinusoidal Position Embedding                   │   │
│  │  → N × Transformer Blocks(Self-Attention)         │   │
│  │  輸出:1500 × d_model 的上下文向量                  │   │
│  └────────────────────────┬────────────────────────────┘   │
│                           │ Cross-Attention                  │
│       ┌───────────────────┘                                 │
│       ▼                                                     │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  文字解碼器(Transformer Decoder)                  │   │
│  │  自回歸生成,每次生成一個 token                      │   │
│  │  特殊 token:                                        │   │
│  │  <|startoftranscript|> → 開始                       │   │
│  │  <|zh|> / <|en|> → 語言標記                         │   │
│  │  <|transcribe|> → 轉錄模式(vs 翻譯模式)           │   │
│  │  <|notimestamps|> / <|0.00|> → 時間戳模式           │   │
│  │  <|endoftext|> → 結束                               │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  工程關鍵選擇:                                             │
│  ✓ 固定 30s 輸入 → 簡化批次處理,但串流需要特殊處理        │
│  ✓ Attention 解碼 → WER 優秀,但不原生支援串流             │
│  ✓ 多任務訓練(轉錄+翻譯+語言偵測)→ 一個模型解決多需求   │
└─────────────────────────────────────────────────────────────┘

Whisper 的工程限制

  1. 非串流原生:設計為 30s 完整音訊輸入,串流需要 chunking + overlap 策略
  2. 幻覺問題(Hallucination):靜音或噪音段落可能生成無意義文字,需要 VAD 前過濾
  3. 重複輸出:長文本有時陷入重複循環,需要 repetition penalty 或 no_repeat_ngram_size
  4. 時間戳偏移:在 chunked 串流模式下,時間戳需要手動累積偏移量

串流 Whisper 的實作策略

1# Chunked streaming with overlap
2CHUNK_LENGTH = 30  # 秒
3OVERLAP = 2        # 秒,避免詞語被切斷
4
5for i in range(0, total_duration, CHUNK_LENGTH - OVERLAP):
6    chunk = audio[i : i + CHUNK_LENGTH]
7    result = whisper.transcribe(chunk)
8    # 去重前一個 chunk 的尾部 overlap 部分
9    yield deduplicate_overlap(result, previous_result, OVERLAP)

七、串流 ASR 與即時系統設計

串流 ASR 的核心挑戰

即時字幕系統要求:

  • Partial result(部分結果):每 200–500ms 輸出當前辨識文字,不等待句子結束
  • Final result(最終結果):句子結束後輸出穩定不變的最終文字
  • Latency budget(延遲預算):總延遲 = 網路傳輸 + 音訊緩衝 + 模型推理 + 後處理
串流 ASR 延遲分解:

網路傳輸(邊緣節點接入):  20–50ms
音訊分幀與特徵提取:        5–10ms
VAD 端點偵測:              3–5ms
模型推理(Conformer-CTC):  40–120ms  ← 主要瓶頸
後處理(標點/大小寫):      10–20ms
WebSocket 推送:             5–15ms
                           ──────────
P50 總延遲:               83–220ms
P99 總延遲:               200–400ms(含排隊)

Conformer-CTC:串流的首選架構

對於串流場景,Conformer + CTC 比 Whisper 更適合,原因:

  1. CTC 解碼不需要看未來幀(Whisper Decoder 是自回歸的,必須等待)
  2. Conformer 結合 CNN 的局部特徵 + Self-Attention 的全域依賴
  3. Chunk-wise attention:將輸入切成 chunk,只 attend 到過去幀和有限的未來幀(lookahead = 40ms)
Chunk-wise Conformer 注意力範圍:

過去幀  ←─────────────────┐  當前 chunk  ┌─→  未來幀(lookahead)
...  t-200ms ... t-100ms  │  t ... t+80ms│  t+80ms ... t+120ms
                          └──────────────┘
                          只看這個範圍的注意力 → 因果性保證

VAD(Voice Activity Detection)在串流系統的作用

VAD 是串流 ASR 的「守門員」:

  • 跳過靜音:減少 40–60% 的無效推理呼叫
  • 端點偵測:判斷句子結束,觸發 final result 輸出
  • 噪音濾除:SNR < 5dB 的幀標記為背景噪音

推薦方案:Silero VAD(輕量 1.8MB,延遲 < 1ms/幀)或 WebRTC VAD(內建於瀏覽器)。


八、為什麼選 X 不選 Y

決策選擇選 X 的理由不選 Y 的理由翻轉條件
串流模型Conformer-CTC無需看未來幀,延遲 < 150ms;CTC 可並行 beam searchWhisper:自回歸解碼,串流需 chunking,幻覺問題多離線批次場景且 WER 最優先 → 選 Whisper
特徵表示Mel Spectrogram (80 維)現代神經網路直接學習特徵,資訊保留完整MFCC:DCT 壓縮損失部分資訊,深度學習不需要手工降維計算資源極度受限(嵌入式設備)→ MFCC
解碼策略CTC + 外部 LM解碼速度快(beam search O(B×V)),可熱換語言模型純 Attention Decoder:自回歸,無法並行,串流不友善高準確率離線場景 → Attention rescore
降噪前處理RNNoise / NSNet22–5dB SNR 改善,WER 降低 8–15%,推理前完成讓 ASR 模型自己處理噪音:模型容量浪費在噪音上,訓練資料需求大模型已在高噪音資料上 Fine-tune(如 Whisper v3)→ 跳過
GPU 型號A10G(24GB VRAM)Whisper large 需 10GB,A10G 可同時跑 2 個實例,成本 $1.0/hA100(80GB):過殺,$3.2/h,Utilization < 30% 浪費批次推理且 throughput 優先 → A100 多路並行更划算
API vs 自建自建(> 10K DAU)> 10K 日活時自建 ROI 3–6 個月回收,成本降低 70–90%雲端 ASR API:無需維運,但 $0.006–0.024/min,大量使用成本爆炸< 1K DAU 或需求不確定 → 先用 API,驗證後再自建

九、系統效應:Before / After 對比

指標Phase 1(雲端 API)Phase 2(自建 small)Phase 3(多模型 Scale)
WER(安靜環境)5–8%7–10%4.2–6.8%
WER(噪音環境,SNR 10dB)12–20%15–25%8–14%(+降噪)
P50 端到端延遲2,000ms180ms120ms
P99 端到端延遲5,000ms350ms280ms
成本(50K 並發/日)$43,200$2,400$1,728
串流即時字幕支援✓(partial result)✓(P99 < 300ms)
多語言支援✓(API 提供)有限(single model)✓(語言路由)
領域微調能力△(需重新部署)✓(A/B 路由)
可用性 SLA99.9%(API 保證)99.5%(自維護)99.95%(多區域備援)
GPU 利用率N/A40–60%75–85%(自動擴縮)

關鍵數字總結

  • Whisper large-v3 在 LibriSpeech test-clean WER:2.7%
  • 加入 RNNoise 降噪後,噪音環境 WER 改善:8–15%
  • VAD 過濾靜音後,推理呼叫次數減少:40–60%
  • 從雲端 API 遷移到自建,50K 並發時成本節省:96%
  • Conformer-CTC 串流延遲 vs Whisper chunked:150ms vs 350ms

十、面試答題要點

「設計一個支援 10,000 位同時在線學生、延遲 < 500ms、WER < 10% 的即時字幕系統:我會分三個階段演進。Phase 1 直接呼叫 Whisper API,整段音訊上傳,延遲 2–5 秒,快速驗證需求。Phase 2 自建 Conformer-CTC 模型(Whisper small 或 fine-tuned),引入 WebSocket 串流和 VAD 靜音過濾,端到端延遲降至 150–300ms;關鍵決策是選 CTC 而非 Attention Decoder,因為 CTC 不需要看未來幀,天生支援串流。Phase 3 引入多模型路由:中文教育內容走領域 fine-tuned 模型(WER 6.8%),通用場景走 Whisper large-v3(WER 4.2%);GPU 用 A10G 自動擴縮,50K 並發比雲端 API 節省 96% 成本。整個系統在 RNNoise 降噪後,噪音環境 WER 可從 20% 降至 12% 以下,P99 延遲維持在 280ms,滿足 500ms SLA。」


十一、系列導航

Phase 5 Part 3:向量資料庫與 RAG 系統設計

Phase 6 Part 2:文字轉語音(TTS)系統設計


本文為「AI 工程從零開始」系列的 Phase 6 Part 1,聚焦 ASR 工程架構與生產部署實踐。

Yen

Yen

Yen