既然要做的是台語發音檢測,那第一個問題就是現在到底有沒有現成的台語 AI 可以用?
結果第一個發現就是有資料,但不是我想下載就能直接下載的。 😔
先說說目前有哪些資源。
Taiwanese Across Taiwan Corpus,也就是 TAT,是一套由臺北科技大學團隊建立的大型台語多通道朗讀語音語料庫。官方資料顯示,完整 TAT 有 600 位語者、300 小時、六軌同步錄音,使用 6 支不同麥克風同步錄製;其中 TAT-Vol1 與 TAT-Vol2 合計約 100 小時,已完成轉錄。
但是 TAT 並不是全部都能免費下載。
去年我在準備專題、查詢 TAT 資料時,在 ACLCLP 的學術研究授權頁面看到:

如果四套 TAT-TTS 全部申請,光 TAT-TTS 就要 NT$80,000;如果連 TAT-Vol1、TAT-Vol2 一起申請,六套合計則是 NT$84,000。商業授權則更貴。
當時看到這個價格,我的第一個反應就是:
我的存款根本沒這麼多。
(大學生很窮啊。)
所以我當時便開始往其他公開資料與現成模型找。
結果最近重新整理這個專題時,我才發現一件去年沒有注意到的事情:
原來學生有學生的方案。
ACLCLP 目前另外提供 TAT-Edu 教育版,限定全職在學學生申請。它的價格和一般學術研究授權差非常多:

如果六套全部申請,總共是 NT$3,000。
從 NT$84,000 變成 NT$3,000。
我不確定當時是我忽略學生版方案還是當時根本還沒出學生版方案,假如有人知道可以留言告訴我。
不過 TAT-Edu 也不是免費公開資料集。它是提供給全職在學學生的教育版授權,有自己的使用條件;例如,資料只能在符合授權規範的情況下使用,依授權規範,畢業後有資料刪除與停止使用的要求。
所以現在回頭看,我覺得「台語語料很貴」其實不是一個很精確的說法。
更準確地說,台語語料不是沒有,而是資料的取得方式會受到資料版本、授權身分與使用目的的影響。
而這也是我在做台語 AI 時遇到的第一個問題:
不是有沒有資料,而是我拿不拿得到這些資料?
所以我後來開始尋找自己實際拿得到、也能合法拿來做實驗的台語資源。其中一個很重要的資源,就是教育部《臺灣台語常用詞辭典》。
我的專題需要讓模型處理台語與台羅之間的關係,所以我需要大量的台語詞彙、讀音,以及相對應的台羅資料。而教育部辭典已經替我整理好一部分我需要的語言資料。 更重要的是,這些資料不能只在網頁上一筆一筆查。
在辭典的「相關資源」頁面裡,教育部直接提供了辭典文字資料,以及詞條、例句的 WAV 和 MP3 音檔下載。
我下載的方式其實很單純:先下載 kautian.ods,取得詞目與音讀等文字資料;再下載詞條的 WAV 音檔,讓每個詞彙可以和實際語音對應起來。
而且我最後選 WAV,而不是直接拿 MP3 當訓練資料,是因為後續還會進行取樣率、聲道、靜音、變調等語音前處理,所以我希望從比較原始的音訊格式開始處理。
確定資料來源後,接下來就是把「詞典資料」和「音檔」整理成模型真正能使用的 Dataset。整體流程大致如下:

整理詞彙與讀音資料,再處理臺羅拼音格式,讓文字標籤能和後續模型使用的格式一致。完成標籤整理後,再將每個 WAV 與對應的臺羅標籤配對,最後依照實驗需求整理成訓練集與測試集。
這裡還有一個我後來才注意到的細節,教育部辭典的音讀欄本身就是採用教育部公告的臺灣台語羅馬字拼音方案,也就是臺羅;而且辭典的詞目音檔主要依主音讀與通行腔錄製。
我可以從辭典取得資料,再經過自己的整理與處理,最後把它變成訓練流程需要的標籤。但即使有了資料,我還是遇到另一個問題 —— 模型。
我目前專題主要使用的模型是 emlinking/wav2vec2-large-xls-r-300m-tsm-asr-v6。
它是以 Wav2Vec2 XLS-R 300M 為基礎進行微調的台語 ASR。它並不是以大規模語音資料訓練的模型,而是利用公開資料與免費運算資源完成 fine-tuning 的模型。我的測試則是使用教育部辭典整理出的單音節音檔,在我的測試條件下,Exact Match Accuracy 為 56.78%。
但我選它的最重要的原因,其實不是它的辨識率,而是它直接輸出台羅。
對一般 ASR 來說,輸出文字可能就已經是終點;但對我的專題來說,台羅反而只是中間表示。因為我的目標不是只知道這段語音是哪一個詞,而是要進一步分析這個詞裡面的發音。如果 ASR 輸出台羅,我就可以比較容易地把辨識結果解析成音節結構、聲母、韻母、韻尾與聲調,再和標準台羅進行比對。
假如模型輸出 kám,我可以進一步解析成聲母 k、韻母核心 a、韻尾以及聲調資訊,再拿這些資訊和標準發音比較。
不過有趣的是,我送出國科會企劃之後,台語 AI 的生態又繼續往前發展。
其中一個很值得注意的例子,就是 Taiwan Tongues ASR-CE。
它不只是提供一個 ASR 模型,也把模型、資料集與不同推論方式一起公開。v2.0 以 Whisper-large-v2 為基礎,目前支援華語、台語、客語、英語與印尼語,其中台語使用的語言代碼是 nan。
更有意思的是,它也把台語相關資料集公開到 Hugging Face。例如目前的 Hokkien dataset 有約 31,805 筆資料、740 MB。
除了開源社群之外,企業也開始投入更大規模的台語語音模型。例如 MediaTek Research 的 Breeze ASR 26。這個模型同樣從 Whisper-large-v2 出發,但使用約 10,000 小時的台語合成語音進行微調。
這跟我手上的模型已經不是同一個量級了,v6 fine-tuning 語音資料約 9.57 小時。
Breeze ASR 26 呢?
約 10,000 小時。
Breeze ASR 26 目前也以 Apache 2.0 授權公開。看到這些資源的時候,我其實也會想,我要不要換?畢竟模型比較新,資料規模也更大。但最後我沒有。原因不是 Taiwan Tongues 或 Breeze ASR 26 不好,而是它們目前提供的資訊形式和我的研究需求不完全一樣。

例如 Breeze ASR 26 雖然規模大很多,但目前主要輸出的是國語漢字,而不是臺羅。對一般語音轉文字任務來說,這完全可以接受;但對我的專題而言,這代表我還需要額外處理台語文字與音系資訊之間的轉換。
Breeze ASR 26 和其他 Whisper 類模型並不是不能做音素層級分析,而是需要另外設計 alignment、phoneme mapping 或其他後處理流程。
相較之下,v6 採用 CTC 架構,除了最後解碼出的臺羅之外,還可以取得不同 frame 的 logits,進一步計算 token probability,並研究 token 與時間之間的關係。
有了模型介紹,也知道我為什麼選 v6,接下來就真的來跑一次。
Breeze ASR 26 的 Hugging Face 模型同樣可以透過 Transformers 的 pipeline() 快速執行。如果只是想先確認模型能不能吃進 WAV、產生台語語音辨識結果,不需要自己處理 Whisper 的 processor、tokenizer 和 decoding。
from transformers import pipeline
asr = pipeline(
"automatic-speech-recognition",
model="MediaTek-Research/Breeze-ASR-26"
)
result = asr("mystery_box.wav")
print(result["text"])
這樣就可以直接把 WAV 音檔交給模型,最後取得辨識結果。
和前面的 v6 不同,Breeze ASR 26 的辨識結果主要以漢字呈現,而不是直接輸出臺羅。這對一般的語音轉文字任務來說沒有問題,但對我的專題而言,這也代表辨識結果還不能直接拿來做後面的臺羅音系分析。
所以這裡我其實不是要測Breeze 能不能比 v6 辨識得好,而是先看看同一個台語 WAV,交給一個大規模台語 ASR,最後會把什麼資訊交給我?
這個結果也會成為後面比較 Breeze ASR 26 和 v6 的基準。
Hugging Face 上的 Wav2Vec2 模型同樣可以透過 transformers 載入,不需要自己把模型檔案一個一個下載下來。只要提供模型名稱,from_pretrained() 就會自動找到對應的模型與處理器。
以我目前使用的 v6 為例:
from transformers import AutoProcessor, AutoModelForCTC
model_name = "emlinking/wav2vec2-large-xls-r-300m-tsm-asr-v6"
processor = AutoProcessor.from_pretrained(model_name)
model = AutoModelForCTC.from_pretrained(model_name)
這裡的 model_name 就是 Hugging Face 上的模型名稱。
AutoProcessor 負責把輸入的語音整理成模型可以處理的格式;AutoModelForCTC 則負責載入這個 Wav2Vec2 CTC 模型。如果只是把模型載入成功,還不能證明它真的能辨識台語。所以接下來直接拿一個 WAV 音檔測試。
import torch
import torchaudio
waveform, sample_rate = torchaudio.load("mystery_box.wav") # 讀入 WAV 音檔,取得語音波形與取樣率。
inputs = processor( # 轉換成模型需要的輸入格式
waveform.squeeze(),
sampling_rate=sample_rate,
return_tensors="pt"
)
with torch.no_grad():
outputs = model(**inputs)
predicted_ids = torch.argmax(outputs.logits, dim=-1) # 找出每個位置機率最高的 token
result = processor.batch_decode(predicted_ids) # 解碼成文字
print(result)
這段程式做的事情其實可以拆成幾個步驟:
torchaudio.load() 讀入 WAV 音檔,取得語音波形與取樣率。argmax() 找出每個位置機率最高的 token。batch_decode() 解碼成文字。這次我故意不先公布 mystery_box.wav 裡面到底錄了什麼音。
WAV 盲盒開箱:自己下載、自己跑。
你可以分別把同一個音檔丟進 Breeze 和 v6,看看兩個模型最後會交給你什麼結果。一個可能比較接近一般語音轉寫的結果,一個則會直接給你臺羅。
至於這個 WAV 到底是什麼音……去 GitHub 跑看看就知道了。畢竟是盲盒嘛。
前面比較不同模型時,我已經確定自己需要的不只是最後的辨識文字,而是臺羅以及模型保留下來的中間資訊。
接下來我想進一步看看這些資訊到底能不能真的拿來做發音分析?
從語音輸入開始,我會取得模型的 CTC frame-level output 與 token probability,再進行時間對齊,最後將辨識結果轉換成臺羅音節,交給後續的發音分析。
整個流程可以簡化成下面這張圖:

我也把這次實際使用的程式碼與測試 WAV 整理成獨立的 day2 資料夾,大家可以直接下載下來跑跑看,也可以猜猜 WAV 盲盒裡面裝的是什麼音。
→ GitHub: https://github.com/yifyu1122/taiwanese-asr-lab
完整安裝方式與 requirements.txt 我放在 GitHub 的 day2 資料夾。
如果把我開始做專題時看到的台語 AI,和現在放在一起比較,我覺得最大的變化不是以前沒有台語 AI,而是現在開始有一條比較完整的技術鏈可以接上去了。
我剛開始做專題時,看到的比較多是語料庫、論文,以及各研究團隊自行訓練的模型。這些資源當然很重要,但對一個想實際做專案的開發者來說,還需要自己花很多力氣去找資料、找模型、確認格式,甚至重新拼出一套可以工作的流程。
但現在開始出現不太一樣的情況:語料庫逐漸被整理成公開資料集,模型開始上架 Hugging Face,開源 ASR 可以直接下載使用,也開始有 Benchmark 可以拿來比較不同系統的表現。甚至在公開模型釋出後,已經可以看到其他開發者進一步微調、量化或衍生模型。
如果把這些變化串起來,我看到的其實不只是一個個獨立的模型,而是一條逐漸成形的生態鏈:

對我來說,這個變化最大的意義,不只是現在有更多台語模型可以用了,而是開發者開始可以站在既有的資料、模型與工具上繼續往前做。
現在這些公開資料、模型與工具逐漸出現,也讓這件事情變得更容易實作。我可以把重心放在模型輸出之後的處理:怎麼取得 token probability、怎麼做時間對齊、怎麼解析臺羅音節,以及這些資訊最後能不能真的拿來做發音分析。
今天的分享就到這裡。下面是我的一些碎碎念。
我的文章會提前放在medium分享,怕我後面開學會沒時間寫,先存稿。其實我有個偷吃步,就是圖片直接放medium的連結。哪天圖片沒顯示不要太意外,可能是medium掛了。還有用medium要重新排版,其實有點累。
我這次在準備github時也出現一些意外。Chrome瀏覽器上傳不了資料大當機、C槽空間不足、原本要用Taiwan Tongues ASR-CE示範結果好像是因為他剛更新結果暫時用不了。還有環境問題。我想說寫文章很容易,結果反而快被上面那些搞死。(懷疑人生)
先念到這裡,我是微微,一個在準備畢專的可憐大四生,明天見!