現在大家都覺得用 AI 上字幕,產生影片或音檔的摘要非常簡單,不是工程師也知道把檔案直接丟給 ChatGPT 和 Gemini,稍微有點概念的會用 AI 語音辨識(ASR),把音檔送進 Whisper、ElevenLabs 或 Gemini 等 API,等待模型回傳文字與時間軸,然後再做一個精美的介面去呈現即可。
但在實際測試各類日常訪談、教學影片與純音效短片時,往往會遇到幾種不符合預期的狀況:
- 說話內容整段消失:前面辨識正常,中間明明有說話卻完全空白,直到下一個時間區間才恢復。
- 無人聲短片出現虛構對白:只有配樂或環境音的動畫,模型卻生成整串對話或字幕組謝詞。
- 在安靜處吐出提示詞:遇到純音樂片段,模型把輸入的 prompt 當成字幕輸出。
- 真實口播被過濾器刪除:主持人親口說的「記得訂閱」被誤判為模型幻覺而移除。
- 時間戳錯位與塌陷:前一句結束於 30 秒,下一句開始卻標記為 28.9 秒;或是 0.06 秒內塞入十幾個字。
- 正常口語重複被誤判為跳針:講話者連續講兩次相同的詞,被過濾器當成死循環清空。
本文從模型推論機制出發,整理音訊前處理切段、提示詞設計以及後處理過濾演算法的實務做法。
痛點一:30 秒解碼視窗與長時間停頓造成的語音遺漏
實務中最容易遇到的問題,是影片中途說話內容被整段略過。
例如一段 60 秒的影片:
- 0s ~ 7.4s:主持人說:「以前常常用到,現在比較少用,因為有替代的方式。」
- 7.5s ~ 15s:主持人停頓喝水。
- 15s ~ 29s:主持人繼續說:「那另外一邊要怎麼操作呢?其實很簡單……」
- 30s 之後:主持人說:「然後你還可以怎樣?」
模型回傳的結果卻只有 0~7.4 秒和 30 秒之後的內容,中間 15~29 秒完全沒有辨識出來。
發生原因:30 秒上下文解碼與靜音判定的交互作用
這並非單純後處理誤刪,而是音訊特徵與解碼排程交互作用的結果:
Whisper 並不是把整支音訊一次交給模型,而是以最多 30 秒的音訊區塊(chunk)作為解碼上下文。當音訊中出現較長的靜音、背景噪音或其他非語音內容時,模型的 no_speech_prob、avg_logprob、時間戳預測與後續的尋道指針(seek)推進會互相影響。
在特定測試案例中,如果前段語音結束後存在較長停頓,模型可能將後續區間判定為無語音,或讓 seek 推進機制直接移動到下一個段落邊界,導致中間原本存在的語音沒有被正確解碼與輸出。
因此,問題的核心在於長時間停頓與 30 秒 chunking、seek 推進及無語音偵測(no-speech detection)機制的交互作用,可能造成語音區段遺漏。
解法:前端能量式靜音偵測切段與適度緩衝
要降低長音訊中停頓造成的遺漏風險,可在前端抽取音訊後進行能量偵測與預先切段:
- 計算音訊能量曲線(RMS Energy):以 100ms 為一幀計算均方根能量,作為簡單的能量式靜音偵測依據(若需更嚴格的人聲判斷,可進一步搭配專門的 VAD 模型如 Silero VAD)。
- 合併與預留緩衝(經驗法則):
- 停頓在 2.0 秒內的說話區塊自動合併,保持語意連貫。
- 前後各預留 400ms 緩衝(
paddingSec = 0.4s),避免字首子音與字尾被裁切。
(註:2.0 秒與 400ms 均為實務調校出的經驗值 heuristic,需依錄音環境調整。)
- 分段送交辨識:將語音區段切成較短的獨立 clip,可以避免長時間停頓與 30 秒固定視窗互相干擾,並讓每個語音片段重新開始解碼。
前處理切段的權衡(Trade-off):
音訊切得太短雖然能避免靜音干擾,但也會破壞上下文連貫性。例如「這個功能叫做」與「自動字幕」若被硬生生切開,後者可能失去前文語境而導致辨識品質下降,因此切段長度與停頓合併閥值需要取得平衡。
痛點二:無人聲與純音效影片的幻覺對白
把只有配樂、腳步聲與環境音的短片(例如知名的開源動畫《Big Buck Bunny》)丟進 Whisper 時,模型有時會憑空產生台詞:
「由 某某字幕組 榮譽出品」、「請勿用於商業用途」「哈哈哈哈……啦啦啦……」(將背景旋律解碼為重複文字)「感謝收看,歡迎下次再來」(將片尾空白腦補為口播)
純音樂引發幻覺的原因
自回歸語音模型在解碼時,依賴聲學特徵與語言模型先驗的結合。當輸入聲音只有音樂或環境噪音、缺乏足夠的人聲特徵時:
- 聲學資訊對解碼的約束變弱。
- 模型容易受到語言模型先驗機率、上下文 prompt 與既有解碼狀態的影響,進而沿著自回歸路徑生成與實際音訊無關的文字。
解法:全域與單段的分層過濾
防止無人聲片段產生多餘字幕,後處理需進行分層過濾:
- 全域無語音判定(Global No-Speech Decision):
計算整支影片所有片段的 no_speech_prob 與 avg_logprob 中位數。若多數段落無語音機率偏高且文字信心偏低(例如本工具在特定測試集採用的經驗閾值 no_speech_prob >= 0.7 && avg_logprob <= -0.8),可直接判定整支影片為純音樂或環境音,不輸出字幕並提示使用者。
(注意:此數值並非 Whisper 官方標準,而是工程測試中的 heuristic;不同模型大小、語言與音訊品質需重新校準。)
- 單段聲學門檻檢驗:
結合 no_speech_prob、avg_logprob 與 compression_ratio 交叉比對,剔除純環境音觸發的片段。其中 compression_ratio 本質為 gzip 壓縮比,可作為文字重複或異常解碼的輔助訊號,但不宜單獨作為幻覺的唯一判據。
痛點三:Prompt 設計與上下文條件的雙面刃
串接 Whisper API 時,常利用 prompt(或 initial_prompt)參數引導標點或專有名詞(詳見 OpenAI API 官方文件:Create Transcription)。常見寫法如下:
// 不建議的完整敘事型 Prompt
"你好,歡迎收看今天的影片。這是一段繁體中文的影音內容,我們會根據說話停頓,在適當的位置加上標點符號與斷句。"
這種寫法的潛在風險在於:若使用完整敘述句子作為 Prompt,會為模型注入大量與實際音訊無關的語言上下文。在微弱背景音樂或無人聲片段,模型因缺乏足夠的聲學約束,容易直接引用 Prompt 中的文字片段輸出為字幕(Prompt 反芻)。
解法一:開放式詞彙引導
提示詞應避免使用完整敘事句子,改用開放式詞彙與標點引導:
// 建議的 Prompt 格式
let basePrompt = "繁體中文,臺灣用語,標準標點符號,請保持完整對白與說話內容。";
if (customVocab.length > 0) {
basePrompt += " 常用詞彙:" + customVocab.join("、") + "。";
}
這樣能引導模型偏好繁體中文與台灣常見標點(,、。?!),同時降低安靜處反芻提示詞的風險。
解法二:善用 condition_on_previous_text 控制上下文污染
Whisper 預設會將前一個 30 秒視窗的解碼文字作為下一個視窗的上下文輸入(condition_on_previous_text=True)。
但在容易出現重複幻覺、背景音樂干擾或時間軸失步的影音中,這個設定可能讓模型陷入錯誤循環(failure loop),將上一段的幻聽一路帶到下一段。
Whisper 官方指出,在遇到重複循環或時間戳脫節時,將 condition_on_previous_text 設為 False,能讓每個解碼視窗獨立進行,有效阻斷上一視窗的幻覺污染後續內容。
痛點四:時間戳倒流、塌陷與邊界孤兒字
除了文字錯誤,模型回傳的時間軸也常出現幾何錯位:
1. 時間戳倒流(Reversed Boundary)
前一段字幕結束於 30.0s,下一段開始時間卻標記為 28.98s,甚至單一段落出現 start: 30.0, end: 28.98。
解法:過濾結束早於開始的段落(end < start),並比對相鄰段落重疊區間進行平滑對齊。
2. 時間塌陷(Collapsed Timestamps)
長達 15 字的句子,模型標註時間僅 0.06s(start: 0.0, end: 0.06)。
Whisper 原始時間戳 token 的時間解析度約為 20ms,而逐字時間戳是透過 cross-attention 與動態時間規整(DTW)估算,並非精確的物理聲學 forced alignment。對一般中文口語而言,15 字只對應 60ms 屬於高度可疑的時間軸異常,可視為時間塌陷(timestamp collapse)的候選案例。
解法:計算文字密度(charsPerSecond)。若密度超過每秒 18 字(此數值為實務測試採用的 heuristic threshold)且時長極短,可視為疑似塌陷;若全片多處時間軸失真,應按字元比例重新分配時間軸。
3. 邊界孤兒字(Orphan Fragments)
人名在切段邊界被切碎,例如:
- 段落 1(0~3.1s):「……總統候選人朱」
- 段落 2(3.1~3.3s):「立」
- 段落 3(3.3~3.5s):「倫」
- 段落 4(3.5~6.0s):「表示今天非常高興……」
若後處理直接依「時長短且字數少」將段落 2、3 視為雜音刪除,會造成人名殘缺。
解法:檢查語意與時間連續性後進行合併
對於短片段(例如時長小於 0.4 秒且少於 3 字的經驗門檻),不應無條件刪除或盲目合併。應先檢查前後段落是否存在時間連續或重疊、文字是否為詞彙或句意的延續(如專有名詞被切斷)。確認為斷裂片段後再向前或向後合併,避免將單字完整回答(如「好」、「對」)誤判合併。
痛點五:後處理如何避免誤刪真實對白
Whisper 在片尾空白或音樂處常出現制式口播幻覺,例如:
「請記得按讚、訂閱我們的頻道並開啟小鈴鐺」「感謝大家收看」
若僅用正則表達式比對「訂閱」或「按讚」並搭配單一信心值過濾,容易發生誤刪。
聲學機率與 Logprob 的解讀方式
Whisper 模型(參考 OpenAI Whisper GitHub 專案)在回傳片段中提供兩個關鍵數值:
avg_logprob:生成 Token 的平均對數機率(數值越接近 0 代表信心越高)。no_speech_prob:模型對<|nospeech|>token 的預測機率;數值越高,代表模型越傾向認為該區段沒有語音(需注意它並非外接物理聲學儀器的絕對測量值)。
在實務中,avg_logprob 不宜單獨當作字幕真偽的絕對判斷標準。它的數值會受到模型參數量、語言種類、解碼策略(如 temperature)、Prompt、音訊品質與 tokenization 方式等多重因素影響,並沒有一個通用的「正常數值區間」。若直接設定硬性 logprob 門檻進行過濾,很容易誤殺發音清晰但因語言或詞彙特徵導致數值偏低的正常對白。
例如以下容易誤刪的過濾邏輯:
// 容易誤刪的條件寫法
if (textMatchesSubscribePattern && (noSpeechProb > 0.35 || avgLogprob < -0.8)) {
dropSegment(); // 容易誤刪
}
當講話者在片尾親口說出「記得訂閱頻道」時,雖然 no_speech_prob 只有 0.03(模型高度傾向判定存在語音),但若此時 avg_logprob 剛好落在較低區間(如 -1.12),便會誤觸條件導致真實對白被刪除。
解法:多訊號交叉比對的過濾邏輯
判斷是否為幻聽的核心在於音訊中是否存在足夠的語音特徵,因此過濾規則應以無語音機率為主要依據,並搭配多個訊號交叉比對:
const looksLikeSubscribeAd = SUBSCRIBE_PATTERNS.some(p => p.test(text));
if (looksLikeSubscribeAd) {
// 僅在無語音傾向偏高 (noSpeechProb >= 0.6) 且信心低落時判定為幻聽
// 若 noSpeechProb < 0.35 (模型高度傾向判定有人聲),保留內容
// (以下門檻值均為特定測試集下的工程 heuristic,非官方絕對標準)
if (noSpeechProb >= 0.6 || (noSpeechProb >= 0.35 && (avgLogprob < -1.5 || compressionRatio > 2.4))) {
return false; // 移除幻聽
}
}
return true; // 保留真實對白
痛點六:區分真人口語重複與模型跳針
另一種常見情況是講話者在短時間內重複相同詞彙:
0.38s ~ 1.74s:「無所不能」
1.74s ~ 5.74s:「有那個無所不能嗎?」
5.74s ~ 10.74s:「對,無所不能,真的是無所不能」
12.74s ~ 14.70s:「有那個無所不能」
14 秒內出現 5 次「無所不能」。若單靠字串重複度過濾,容易將口吃、強調或問答對話誤刪。
判定依據:逐詞時間戳與多訊號綜合評估
區分真人重複與模型跳針需結合時間軸與多項聲學/解碼特徵:
- 時間軸均勻展開:真人重複講述時,每次發音都有明確起訖時間(如 0.38~1.28s、3.24~4.36s、7.5~8.44s),詞與詞之間有呼吸與停頓。
- 模型跳針的多元樣態:模型的 repetition loop 可能表現為極短時間內塞入大量文字(時間戳塌陷)、壓縮比(
compression_ratio)異常偏高(例如高於 3.0),或是時間軸看似前進但輸出無限循環字串。 - 無語音機率:真人發音的
no_speech_prob通常極低(如0.0028)。
因此,後處理不應僅憑「文字重複」就執行刪除,而是應在文字重複度高、壓縮比異常、時間軸幾何失真以及無語音傾向偏高等多個訊號同時異常時,才提高模型跳針的判定分數,避免抹去講話者真實的情緒與語調。
進階後處理:利用 LLM 二次潤飾的優缺點
除了基於規則與聲學數值的過濾,實務上常見的另一種後處理手法,是將 ASR 初步辨識的文字送進大型語言模型(LLM,如 GPT-4o、Claude 或 Gemini)進行二次潤飾。
這套做法有明確的效益,但也伴隨實務限制:
優點
- 修正上下文同音錯字:LLM 具備完整的語意理解能力,能根據前後文自動校正專有名詞、成語或同音字(如將「自媒體」誤聽為「自媒替」)。
- 清理口語贅字與標點修飾:能有效過濾講話者的口癖(如「那個」、「然後」、「就是說」)與結巴,並重新規劃符合閱讀長度的自然標點與斷句。
缺點與隱患
- 時間戳脫節風險:影片字幕極度依賴音畫同步。LLM 在刪減口贅字、重組句構或替換詞彙時,會打亂原始 ASR 產出的字級(Word-level)或句級時間軸。若未搭配強制字數對照或動態時間對齊演算法,容易導致字幕提早或延遲出現。
- 語意漂移與過度修飾:LLM 有時會過度「美化」對白,把說話者刻意保留的口氣、反諷或特定語調改為標準書面語,甚至在理解模糊處腦補出未曾說過的論點。
- 額外成本與延遲:多了一層 LLM 呼叫,處理時間與 API 費用成倍增加,較不適用於講求即時或大批量本機處理的流程。
核心觀點:模型基礎能力決定上限
在工程上投入大量規則修補 ASR 缺陷,往往不如直接選擇更合適的語音模型。而在中文與繁體中文的實務開發中,模型選型更常面臨以下幾種現實困境:
1. 國外開源模型的語系偏向
許多歐美主導的開源語音模型(尤其是參數量較小或專門針對英語設計的架構),中文語料比重極低。面對中文語音時,模型常出現兩種極端反應:
- 將中文音節判定為背景雜訊而直接忽略不輸出;
- 解碼器被英文先驗機率主導,將聽到的中文強行翻譯或幻聽成整串無意義的英文字句。
2. 合規限制與地緣政策考量
社群中有些針對中文訓練的開源模型(例如 Qwen-Audio、SenseVoice 等),雖然在中文發音與斷句上有不錯表現,但在特定商業環境中存在限制:
- 在政府專案、金融機構或有嚴格資安審查的企業場合中,即使採用地端私有化部署(On-Premise),也常因合規要求與供應鏈審查規範而無法採用;
- 這類模型多數以簡體中文與特定用語為主,轉為繁體中文後仍需額外的詞彙校正。
3. 微調模型的特點與局限(以 Breeze-ASR 為例)
針對台灣繁體中文微調的 Breeze-ASR,在全形標點與在地日常詞彙上表現較為自然。但需注意它本質上是基於較舊版本的 Whisper(如 large-v2)訓練而來:
- 若音檔本身收音差、環境噪音大,原版 Whisper 辨識不佳的片段,Breeze-ASR 通常也難有起色;
- 因微調權重偏置,在純音樂或安靜處有時反而更容易強行腦補出特定詞句的幻覺。
4. 現代專用與長上下文模型的進展
像是 ElevenLabs Scribe 或 Gemini 3.5 Transcribe 等現代模型,具備較強的多語上下文感知能力,30 秒視窗跳躍與 Prompt 反芻的情況相對少見。
語音辨識品質很大程度取決於模型本身的能力,前處理與後處理主要用於填補邊界漏洞與格式對齊。
場景思考:依用途選擇轉寫策略
本文的討論核心在於「影片字幕」(Video Subtitling),這類場景對時間戳毫秒級對齊、音畫同步與逐字精準度有極高要求。
但語音轉文字(Speech-to-Text)在不同應用場景下,關注的指標完全不同,作業策略也應有所取捨:
| 應用場景 | 核心目標 | 時間戳要求 | 錯別字容忍度 | 建議作業策略 |
|---|---|---|---|---|
| 影片畫面字幕 | 音畫同步、好讀不擋畫面 | 極高(需精確至單字/單句起訖點) | 低(需忠於原話節奏) | 前端 VAD 切段 + ASR 輸出時間戳 + 聲學後處理過濾 |
| 會議記錄與訪談摘要 | 掌握決議、論點與行動事項 | 低(只需段落或發言者分段) | 一般字詞高、專有名詞極低 | 注入內部專屬詞庫 ➔ ASR 轉出文字 ➔ LLM 生成摘要 |
| 語音指令與客服質檢 | 識別意圖、提取關鍵字與情緒 | 無需時間戳 | 關鍵字低、其餘中等 | 輕量專用 ASR ➔ 關鍵字規則比對或意圖分類器 |
| Podcast 轉長文章 (SEO) | 閱讀流暢、段落分明、消除口語感 | 無需時間戳 | 低(需符合出版品質) | ASR 轉出逐字稿 ➔ 交由 LLM 深度重構為書面文章 |
會議記錄的特殊陷阱:專有名詞引發的「錯上加錯」
不同場景對錯別字的敏感維度並不相同:
- 一般口語錯字:如將「那時候」聽成「納時候」,後續 LLM 透過前後文推理通常能自行修正。
- 內部術語與人名:若涉及與會者姓名、內部專案代號(如「天狼星」聽成「甜涼心」)、跨部門黑話或特定產品型號,ASR 在第一階段辨識失誤,後續的 LLM 就會基於錯誤事實進行歸納與推論,導致產出的決議事項嚴重失真。
因此,會議與訪談場景的關鍵往往不是追求逐毫秒的時間對齊,而是在 ASR 或 Prompt 階段優先建立專用名詞白名單(Domain Glossary),從源頭防範關鍵詞被模型誤判。
先釐清產出目標是「精確掛在畫面上的對白時間軸」,還是「只需提煉資訊的文字記錄」,才能在模型選型、時間戳粒度與後處理流程中做出最平衡的工程決策。
官方技術文件與開源參數對照
若需串接 OpenAI 語音辨識 API 或本機部署開源模型,官方文件與開源專案中的核心參數用途如下:
1. OpenAI Audio Transcriptions API Reference
prompt:傳入風格指引或前文脈絡(最多 224 個 Token)。建議使用開放式標點與專有名詞清單,避免使用完整句子以防安靜處反芻。response_format:支援json、text、srt、verbose_json、vtt。若需取得置信度(avg_logprob)、無語音機率(no_speech_prob)與單字時間戳,需指定為verbose_json。timestamp_granularities[]:可指定word(逐詞時間戳)或segment(逐句時間戳),用於字幕精確對齊。temperature:採樣溫度(0.0 ~ 1.0)。字幕製作建議固定為0.0(貪婪解碼),確保輸出結果穩定。
2. OpenAI Whisper 開源專案 (GitHub)
- 模型架構:提供
tiny、base、small、medium、large-v3與推論加速的large-v3-turbo。中文語境建議採用medium或large等級以上模型。 - 內建解碼閥值與退避機制(Decoding Fallback):
compression_ratio_threshold(預設 2.4):文字經 gzip 壓縮比例過高代表進入跳針迴圈,Whisper 會自動提高 temperature 重新解碼。logprob_threshold(預設 -1.0):平均 token 對數機率低於此值視為低信心輸出。no_speech_threshold(預設 0.6):no_speech_prob超過此門檻且 logprob 偏低時,判定為無語音片段。condition_on_previous_text(預設 True):控制是否將前一視窗的解碼結果作為下一視窗的輸入。設為 False 可阻斷錯誤循環與時間戳失步。
總結
自動字幕並非單純呼叫 API 就能保證完美,穩定的工作流通常包含三部分:
- 基礎模型:依語言場景選用合適的 ASR 模型。
- 音訊前處理:以能量偵測切段與適當緩衝避免長時間停頓干擾。
- 提示與後處理:使用開放式詞彙引導並適度控制上下文條件,結合多項聲學機率與時間軸幾何檢驗修正錯誤。