引言:為什麼官方分數不夠用
我把演講錄影變成筆記的流程是這樣一條線:逐字稿 → 對應投影片 → 總整理。
這條線的地基是語音轉文字(automatic speech recognition,ASR)。它聽錯多少,後面每一層筆記就跟著錯多少。原本我用的是 OpenAI 的 Whisper large-v3。
這件事的起點,其實是我滑手機看到聯發科(MediaTek Research)發表台語模型 Breeze-ASR-26。 台語模型本身就夠讓人好奇了,但點進去才知道,原來他們去年就出過 Breeze-ASR-25,從 Whisper-large-v2 微調,專門針對台灣華語和中英夾雜優化,Apache 2.0 開源。醫學演講正好是中英夾雜的重災區,我居然錯過了一整年。
於是我同時面對兩顆模型,而它們的官方資料是完全不對稱的。
Breeze-ASR-25 給了一整張成績單,字錯率(word error rate,WER,越低越好):
| 資料集 | Breeze-ASR-25 | Whisper-large-v3 | Whisper-large-v2 |
|---|---|---|---|
| CSZS-zh-en(中英夾雜) | 13.01 | 26.43 | 29.49 |
| ASCEND-MIX(中英夾雜) | 16.38 | 25.13 | 21.01 |
| ASCEND-ZH(華語) | 16.04 | 17.41 | 17.49 |
| CommonVoice16-zh-TW(台灣華語) | 7.97 | 8.95 | 9.84 |
| ML-lecture-2021-long(長音檔演講) | 4.98 | 6.41 | 6.13 |
(官方欄位寫的是 WLV3-Auto/WLV2-Auto,也就是開啟自動語言偵測的 Whisper。)
它連我當時在用的 large-v3 都贏,中英夾雜那兩列更是壓倒性。這部分我沒有必要再證明一次。
而 Breeze-ASR-26 呢?它只有台語一項成績——但那一項做得很紮實。 官方拿它跟四個系統比台語字元錯誤率(character error rate,CER,越低越好):
| 系統 | 台語 CER |
|---|---|
| Breeze-ASR-26 | 30.13 |
| 教育部台灣台語輸入法 | 30.70 |
| 雅婷逐字稿 | 32.11 |
| Google Gemini 3 Flash | 32.52 |
| Breeze-ASR-25 | 49.99 |
它在台語上贏了 Gemini 3 Flash,也贏了雅婷。 這是真本事,不該被忽略。
但它的成績單也就到這裡為止了:
- 沒有中文 benchmark
- 沒有英文 benchmark
- 沒有中英夾雜 benchmark
- 沒有任何時間戳/對齊的資料
也就是說,除了台語,它在其他任何情境的表現,官方一個字都沒說。 而它偏偏是從同一個 Whisper 家族微調出來的,跟 25 是兄弟。那它是「25 加上台語」,還是「為了台語犧牲了別的東西」?沒有人知道,因為沒有人測過。
(先講清楚:它從來沒有宣稱過台語以外的能力,所以底下不是在打臉它,是在補上官方沒說的那一塊。)
這就是我要自己動手的原因。三個問題,官方 benchmark 一個都答不了:
- 它抓不抓得到我的領域術語? 官方考的是 ASCEND、CommonVoice 這類日常對話語料,不是塞滿
nucleus pulposus、piriformis、spondylolisthesis的復健科演講。 - 時間戳對不對得上投影片? 我的筆記要靠時間戳把每句話貼到對應的那張投影片上。逐字稿再準,切不出段落就沒用。而這件事兩份 model card 都沒提。
- 那顆台語模型,拿到台語以外的情境會怎樣? 官方沒測,那我測。
官方 benchmark 是官方的考卷。它考的是它在乎的東西,不是你在乎的東西——而它沒考的那些,往往才是會弄壞你系統的東西。
方法
沒有黃金標準,就自己造一把尺
最理想的參考標準(reference standard)是人工精修過的逐字稿。我沒有,也不想為了測試去精雕一份。所以改成兩把可以程式化計算的尺。
尺一:領域詞彙字典(量詞彙品質)
- 從上百本復健科教科書自動抽出 18 萬多個英文詞彙(在這些書裡出現過三次以上的字就收)
- 每個模型的輸出跟字典比對,算兩個數字:capture(抓到多少真的存在的詞)與 garbage(生出多少字典裡沒有的假詞)
- 兩個數字一定要一起看:一個乾脆聽不出英文的模型,precision 會是完美的 100%,但它什麼也沒抓到
這把尺量的不是「醫學名詞的正確率」,而是更基本的一件事:模型吐出來的這個字,在復健科文獻裡真的存在,還是它自己掰的。像 motibra、grutius、idioma 這種憑空發明的字,字典一比就現形。
尺二:段落粒度(量時間戳可用性)
- 投影片大約 1 到 2 分鐘換一張,所以逐字稿必須切得夠細才對得上
- 門檻:每分鐘至少 10 段,且段落間隔中位數不超過 8 秒
- 這把尺後來刷掉了一個模型,而且是唯一一個只有它才抓得出來的問題
一個模型必須兩關都過。 只量詞彙,你會把一個「字字聽對、但整段糊成一塊」的模型放進流水線。
測試紀律
三條,都是有代價換來的:
- n ≥ 3,變因分開測。 單一樣本的測量會同時中三種偏誤:儀器誤差、確認偏誤,以及「文件沒寫」被當成「模型不會」的缺席證據推論。我第一輪只拿一段音檔試水溫,三個結論後來全部被推翻(其中「Breeze 慢兩倍」根本是兩個模型載進同一個程序、在 8GB 顯卡上互搶記憶體的儀器誤差)。這跟臨床上讀一篇診斷性研究要小心的坑一模一樣。
- 一個模型一個程序。 承上,這是儀器誤差的來源,也是 8GB 顯卡的硬限制。
- 計分交給程式,不交給模型。 讓大型語言模型(large language model,LLM)自己挑例子來比,它注意到的點天生偏向支持新模型,確認偏誤就這樣被帶進來。全量統計要寫死在腳本裡。
語料
15 段 × 每段 8 分鐘(6 段課堂演講 + 9 段案例討論),另有 6 段英文演講;段落粒度的複測是 4 段。全部是真實的復健科演講錄音,不是朗讀語料。
結果
一、模型:Breeze-ASR-25 完勝,而且更快
| 設定 | 真實詞彙捕獲 | 假詞 | 精確度 | 段/分鐘 | GPU 時間/每小時音訊 |
|---|---|---|---|---|---|
| Whisper large-v3(舊預設) | 435 | 51 | 89.2% | 24.4 | 3.4 分鐘 |
| Breeze-ASR-25(純換模型) | 587 | 29 | 94.5% | 18.2 | 3.4 分鐘 |
| Breeze-ASR-25+設定調校(新預設) | 649 | 37 | 93.7% | 19.4 | 3.0 分鐘 |
| Breeze-ASR-26(台語版,同設定,供對照) | 182 | 8 | 81.6% | 2.2 | 3.0 分鐘 |
真實詞彙捕獲多了 49%,速度還更快。 官方 benchmark 說它在通用語料上比較好,我的資料證實這個優勢延伸到了醫學領域術語,而這是官方沒測、也不可能替我測的部分。
值得注意的是,增益有一部分來自設定。換模型不是唯一的變因。
最後一列是台語版的 Breeze-ASR-26,放進來是為了回答「那 26 呢」這個必然會被問到的問題:它在華語醫學演講上只抓到 182 個真實詞彙,不到 Breeze-ASR-25 的三成。
但這個數字不能照字面讀,我一開始就讀錯了。
182 是怎麼來的:它沒聽懂,還是我的尺看不見?
有人(很好的質疑)問我:Breeze-ASR-26 會不會是把英文講成中文了,所以我的英文字典抓不到?
去看原始輸出,答案是對,很大一部分是。同一段音檔:
| 講者說的 | Breeze-ASR-25 | Breeze-ASR-26 | Whisper large-v3 |
|---|---|---|---|
| interlamina | interlamina | 印特拉蜜拉 | 英特拉米拉 |
| facet | phase(聽錯) | 防震、法西 | 發射 |
它把英文術語音譯成漢字了。這其實正是它 model card 寫的設計:輸出漢字,而不是台語正字。
量化之後更清楚(同一批 15 段):
| 總字元 | 漢字 | 英文詞 | |
|---|---|---|---|
| Breeze-ASR-25 | 31,537 | 18,514 | 1,293 |
| Breeze-ASR-26 | 27,579 | 19,617 | 313 |
| Whisper large-v3 | 28,593 | 18,038 | 985 |
它的輸出量沒有崩,漢字甚至是三者最多的,塌掉的只有英文。 它不是沒在講話,是改用漢字講。(順帶一提,漢字最多也不代表它中文比較好——「印特拉蜜拉」本身就佔了 5 個漢字。)
所以那個 182 混合了兩件事:真的沒聽到,以及聽到了但寫成漢字。我的英文字典只看得見後者的失敗,看不見它到底有沒有聽懂。
那結論變了嗎?沒有,但理由完全不同。
對我的用途來說,這仍然是失敗:我的筆記需要的是 interlamina,不是「印特拉蜜拉」;查文獻、對投影片、給同事看,音譯的漢字一律沒用。所以華語醫學演講不要用 Breeze-ASR-26 這個結論不變。
但正確的說法不是「它聽不懂英文術語」,而是 「它會把英文術語音譯成漢字,而那不是我要的輸出形式」。這兩句話對它的評價差很多,而我一開始寫成了前者。
順帶一提,Whisper large-v3 也會音譯(英特拉米拉、發射),只是頻率低得多。這是 Whisper 家族的通病,26 把它放大了。
二、設定:兩個開關都是「關掉」
| Breeze-ASR-25 設定 | 真實詞彙捕獲 | 假詞 | 精確度 | GPU 時間/每小時音訊 |
|---|---|---|---|---|
| 預設(VAD 開、condition 開) | 587 | 29 | 94.5% | 3.4 分鐘 |
| 關 VAD + 關 condition(採用) | 649 | 37 | 93.7% | 3.0 分鐘 |
| 關 VAD + beam size 10 | 604 | 21 | 96.4% | 5.1 分鐘 |
- 語音活動偵測(voice activity detection,VAD)→ 關。 它的本意是切掉靜音、只把有聲音的片段餵進去。但演講裡的停頓、換氣、翻投影片的空檔,常常被它連著前後半個字一起吃掉。關掉之後模型從頭聽到尾,邊界不會被切爛。
condition_on_previous_text→ 關。 這個參數讓模型把上一段的輸出當成下一段的上下文。理論上讓行文連貫,實務上一旦某段聽錯,錯誤會被當成「前文」餵下去,後面就順著錯,嚴重時整段卡在同一句話裡無限重複。關掉之後每段獨立解碼,錯誤不會傳染。
實測 2,236 行輸出裡,靜音幻覺(沒人講話時自己生出「謝謝觀看」)和重複迴圈各 0 次。
第三行的 beam size 10 很有意思:精確度全場最高(96.4%),但慢了將近一倍,捕獲還少 45 個詞。多花的算力換來的是更保守的輸出,不是更好的輸出,所以沒採用。
另外,關掉 VAD 有個副作用:faster-whisper 的批次模式不支援 VAD 關閉,會自動退回循序解碼。結果反而更快(3.0 對 3.4 分鐘),因為省下了切割與拼接的開銷。
三、負結果:兩個看起來很聰明的做法,都輸了
負結果也是結果,寫出來省得別人再踩一次。以下都是同一組 15 段、同一把尺量出來的。
餵術語提示(hotwords/initial_prompt):沒有好處,只有代價
我準備了 25 個復健科術語(prolotherapy、nucleus pulposus、piriformis、sacroiliac 那類),用 faster-whisper 的 hotwords 餵進去:
| 設定 | 真實詞彙捕獲 | 假詞 | 精確度 |
|---|---|---|---|
| Breeze-ASR-25(不餵) | 587 | 29 | 94.5% |
| Breeze-ASR-25 + hotwords | 580 | 36 | 91.6% |
| Whisper large-v3(不餵) | 435 | 51 | 89.2% |
| Whisper large-v3 + hotwords | 446 | 56 | 88.2% |
先看它沒做到的事:真實詞彙捕獲幾乎沒動(587→580、435→446)。餵術語表最主要的賣點——讓模型更容易抓到你在乎的專有名詞——根本沒有發生。
再看它做到的事:兩個模型的假詞都變多(29→36、51→56),精確度都下降。
失敗機制比分數更值得記:提示詞不是字典,是「拉力」。它把模型聽到的音往你給的詞硬拉,拉不到就生出四不像的新錯字——而且新增的假詞正是這樣來的:Breeze 開始吐 sacroilar、buteroli,large-v3 吐出 paravertibone。這些字在不餵提示的版本裡都不存在。
最諷刺的是,我最想救的 nucleus pulposus 和 prolotherapy,明明一字不差寫在提示裡,照樣沒被抓出來。
它是弱引導,不是查字典。 真的想要領域詞彙,該做的是微調模型,不是在推論時遞小抄。
兩個模型取聯集:輸在每一項
| n=15 | 真實詞彙捕獲 | 假詞 | 精確度 | GPU 時間/每小時音訊 |
|---|---|---|---|---|
| 只用 Breeze-ASR-25 | 587 | 29 | 94.5% | 3.0 分鐘 |
| large-v3 + Breeze 取聯集 | 571 | 147 | 80.5% | 6.0 分鐘 |
真實詞彙沒有變多,假詞卻變成 5 倍,算力兩倍。原因很簡單:聯集會把另一個模型憑空發明的字一起吸進來。合併邏輯已刪除。
不過這裡撿到一個副產品:兩個模型逐字比對的一致率是很好的信心指標。正常段落的字元一致率落在 88 到 91%;有一段掉到 57%,回去聽是麥克風外的閒聊,兩個模型都在幻覺。現在低於 75% 就標記人工複核,不直接寫進筆記。
英文演講:打平,所以統一
英文段落(6 段)Breeze 跟 large-v3 幾乎完全打平(1535 對 1537 個詞),精確度略好(98.6% 對 97.8%),而且沒有中文幻覺。既然不輸,就全部統一用 Breeze,少維護一條路徑。
四、Breeze-ASR-26 的時間對齊退化(本文最主要的新發現)

這一節是官方 model card 上找不到的東西。
先看兩份官方文件怎麼寫。Breeze-ASR-25 的 model card 把時間對齊當成賣點:
Enhanced time alignment, suitable for automatic captioning.(強化時間對齊,適合自動字幕)
而台語版 Breeze-ASR-26 的 model card 裡,timestamp、alignment、captioning 一個字都沒提。它只講一件事:用約 10,000 小時的合成台語語音訓練,在台語 benchmark 上把字元錯誤率(character error rate,CER)從 Breeze-ASR-25 的 49.99% 降到 30.13%。
用尺二一量,這個「沒提到」是有原因的:
| 模型(預設解碼) | 段/分鐘 | 段長中位數 | 對得上投影片嗎 |
|---|---|---|---|
| Whisper large-v3 | 24.4 | 2 秒級 | ✅ |
| Breeze-ASR-25 | 18.2 | 2 秒級 | ✅ |
| Breeze-ASR-26 | 1.8 ~ 2.2 | 30.0 秒 | ❌ |
注意那個段長中位數:平平的 30.0 秒,最大值也是 30.0 秒。 那不是它的斷句習慣,那正好是 Whisper 的解碼視窗長度。
換句話說,它根本沒有在預測段落邊界。Whisper 靠一種特殊的「時間戳 token」來決定一句話在哪裡結束,而 Breeze-ASR-26 在合成台語語料上微調之後,這個能力退化了,於是每個 30 秒的視窗就整塊吐出來。舉一段 10 分鐘的音檔為例:Breeze-ASR-25 切成 253 段,Breeze-ASR-26 只切出 20 段。
到這裡我本來的結論是:不能用。但這個結論也不對。
因為時間戳 token 只是 Whisper 產生時間戳的其中一條路。另一條路叫字級時間戳(word timestamps),走的是模型內部的注意力對齊(cross-attention),完全不經過時間戳 token。而這個開關,我從頭到尾沒開過。
打開之後,同樣的音檔、同樣的模型(n=4 段):
| Breeze-ASR-26 | 段/分鐘 | 過得了 ≥10 的門檻嗎 |
|---|---|---|
| 預設解碼 | 1.8 ~ 2.2 | ❌ 全部不過 |
| 開字級時間戳,依停頓重新切段 | 10.0 ~ 10.7 | 🟡 4 段裡過 3 段 |
字級時間戳本身是健康的:時間單調遞增、覆蓋率接近 100%、幾乎沒有零長度的字。代價是解碼慢 1.29 倍。
所以正確的說法不是「Breeze-ASR-26 不能對時間戳」,而是「用預設設定的它不能」。 這是設定問題,不是模型的能力上限。
討論
這對想用 Breeze-ASR-26 的人代表什麼
如果你打算拿 Breeze-ASR-26 做任何需要時間戳的事(台語字幕、逐字稿對齊、對投影片、剪輯定位),請注意:它預設的段落切分是壞的,必須開 word_timestamps 才能用。 這是本文最實用的一句話,而且它沒有寫在任何官方文件裡。
至於要不要為了華語內容換成 26:不用。它會把英文術語音譯成漢字(interlamina → 印特拉蜜拉),我的筆記需要的是能查、能對投影片的英文原字;而且就算開了字級時間戳把粒度救回來,也只是勉強擦過每分鐘 10 段的門檻,Breeze-ASR-25 原生就有 18 段以上。「技術上可行」跟「值得換」是兩件事。
但請注意這句話的範圍:我說的是「不適合我這種中英夾雜、需要英文術語的醫學演講」。它在自己的主場(台語)贏過 Gemini 3 Flash,那是它的成績,不是我能否定的。
限制(請不要過度解讀我的結果)
- 我沒有測台語。 我的語料裡一段台語音檔都沒有。Breeze-ASR-26 的 CER 30.13% 是聯發科的數字,不是我量出來的,我不會替它背書,也不會唱衰它。
- 我是拿華語音檔測一顆台語模型的段落粒度。 時間戳 token 的退化來自模型權重,理論上在台語音檔上也會一樣發生,但這是推論,不是我測到的結果。真要用在台語,還是得自己錄一段來測。
- 我的尺看不見「音譯」。 這是這次學到最重要的一課。英文字典只能判斷「模型有沒有用英文寫出這個術語」,它無法判斷「模型到底有沒有聽懂」。Breeze-ASR-26 把
interlamina寫成「印特拉蜜拉」的時候,我的尺記它 0 分——可是它其實聽對了音。對我的用途(筆記要能查、能對投影片)記 0 分是對的;但如果你要的是「聽懂了沒有」,這把尺會系統性低估任何傾向輸出漢字的模型。用之前先確認:你量的是「聽懂沒」,還是「寫成你要的形式沒」?我量的是後者。 - 字典不是完美的參考標準。 它收的是「文獻裡出現過的字」,所以裡面也混著一般英文字,不是一份純醫學術語表。但它直接對應我在乎的結果:關鍵資訊有沒有被聽出來、模型有沒有在亂編。
- 我的尺不一定是你的尺。 如果你在乎的是延遲、標點、語者分離或情緒,那就要換一把對應的尺。
官方 benchmark 到底該怎麼用
它不是沒有用,它答的是「這個模型好不好」;它答不了的是「這個模型對我的任務好不好」。這次它替我省下了「25 到底有沒有比 Whisper 強」的驗證工作,但也漏掉了兩件對我來說攸關成敗的事:領域術語,以及時間對齊。
而其中一件,連 model card 沒寫的部分都藏著資訊。Breeze-ASR-25 特地寫了「強化時間對齊、適合自動字幕」,Breeze-ASR-26 一個字都沒提。當時我沒讀出這個訊號,是尺替我讀出來的。
流程說穿了很簡單:明確定義你要的成果 → 找到能量它的尺(可能不只一把)→ 多個樣本、變因分開測 → 連負結果一起記下來。
還有一句要補:尺量出「不及格」的時候,先問一句 是這個模型不行,還是我沒設定好? Breeze-ASR-26 那一關,答案是後者。分數會告訴你有問題,不會告訴你問題出在誰身上,那一步得自己拆開看。
這把尺我開源了
整套測法整理成一個 repo,你可以拿去測自己的錄音:
👉 github.com/drpwchen/asr-benchmark
裡面有建字典的腳本(指向你自己的語料就好)、兩把尺的評分腳本,以及跑「模型 × 設定」矩陣的腳本,包括那些我試過沒用的變體,你可以自己重現負結果,不用相信我。
我也把自己那份 18.7 萬字的字典附進去當範例,讓你不用先準備語料就能跑跑看,復健科的同行可以直接用。但如果你是別的領域,請用腳本建自己的字典。拿復健科的尺去量心臟科的演講,本來就是不對的尺,這正是這整篇想講的事。
—
模型連結:Breeze-ASR-25、Breeze-ASR-26。同一套「拿自己的資料測」的做法,我之前也用在 graph RAG 和讀論文的 skill 上,有興趣可以一起看。
—
