iT邦幫忙

2026 iThome 鐵人賽

DAY 18
0
AI 自動化

我以為我保留了五道閘門系列 第 18

Day 18|逐字稿說那裡沒東西,於是我砍掉了六分半

  • 分享至 

  • xImage
  •  

模組四|剪輯管線(Day 17–22)

昨天講 ASR 的參數,留了一個伏筆:condition_on_previous_text=False 壓下了模型的幻聽,但沒有消滅它。

今天講那次事故。

事故

某一集的剪輯,v1 版本砍掉了 6.9 分鐘。

砍的依據是逐字稿:那一段的辨識結果在狂跳針,同一句話重複了很多次,看起來像是一段沒有內容的空白。

於是那段被判定為「無內容」,切掉。

v2 重新檢查之後,只砍了 98.2 秒,其中 61.7 秒是真的靜音。

找回了約 5 分鐘的真內容。 成品從約 47 分鐘變成約 51 分鐘。

那五分鐘裡有什麼

有講話。

那段音訊的實際狀況是:音量偏低的語音,疊在微弱的背景音樂上。 對 ASR 來說信噪比很差。

而它沒有輸出「辨識不出來」,它輸出了前面那句話的重複。

這正是昨天那個參數想防的行為:模型把自己的輸出當成上下文,在一段辨識困難的區間,它繼續生成「應該會出現」的東西。

我關掉了那個參數,所以最嚴重的無限重複沒有發生。但在信噪比很差的區間,它還是產生了不對應任何真實語音的文字。

錯誤真正的位置

我垂下測繩讀到「這裡沒東西」,其實下面整整好幾分鐘的內容都還在。

事故的成因不是 ASR 出錯。ASR 在那種音訊條件下辨識不好,這是預期內的。

錯的是我把它的輸出拿來回答一個它答不了的問題。

我用逐字稿判斷「這一段有沒有內容」。

而 ASR 的能力是「這句話說了什麼」。這兩件事看起來很像,實際上不是同一件事:當它辨識不出來的時候,它不會回報空白,它會回報一段它猜的文字。

於是「跳針」被我讀成「沒有實質內容」,而它實際上是「模型在這裡失去了訊號」。

**跳針不是空白的信號,是失敗的信號。**而我把它當成前者。

修正的方法:換一個訊號源

我把兩個問題分別投進不同的孔,因為它們本來就不該由同一個東西回答。

v2 的做法不是換模型、不是調參數,是換一個東西來回答那個問題:

「這裡有沒有聲音?」  → 用音訊訊號回答(silencedetect / RMS 包絡)
「這裡說了什麼?」    → 用 ASR 回答

兩個問題,兩個工具。而它們有明確的分工:

  • silencedetect 直接量音量,它不知道那是人聲還是音樂還是雜訊,但它不會憑空生出聲音
  • ASR 知道那是什麼字,但它在沒訊號的時候會編

用音訊訊號決定「哪裡可以切」,用 ASR 決定「切在哪個字之間」。

SRT 本身也不能直接用

修完這個之後,我又發現三個獨立的問題,全部都是「逐字稿的時間碼不能直接當剪點」。

問題一:時間碼被量化成整 2 秒。

某一集的 SRT,所有時間碼都落在偶數秒上。實測:SRT 標某個聲音在 10.3 秒,音檔裡它實際在 12.80 秒。

差 2.5 秒。切下去會切在句子中間。

問題二:系統性早於語音約 0.7 秒。

另一集的 SRT 在 1 秒網格上,而且不是隨機誤差,每一句都早了大約 0.7 秒。

這種系統性偏移最陰險,因為它看起來很一致,讓人以為時間碼是準的。

問題三:跨軌的時鐘漂移。

這個明天整篇講,它比前兩個嚴重得多。

修法:不要相信整數

短影片的出點修法是這一段最實用的部分:

1. 拿 SRT 標的句尾時間,當作「大概在這附近」
2. 在那個位置前後找一段窗口
3. 用 50ms 的 RMS 包絡找出語音結束後的停頓
4. 取那個停頓的「中點」當出點

第 4 步是關鍵。取停頓的中點,而不是停頓的開始或結束。

取開始,會在字音的殘響還沒衰減完就切,聽起來像被掐斷;取結束,會切到下一句的起音。取中點,兩邊都有餘裕。

而這個修正值可以精確到小數點後兩位,因為它是量出來的,不是算出來的。

Day 24 會講一個一模一樣的道理,只是在圖片上:量測比計算可靠。

這一段裡,AI 錯了一次,而它是被授權的

Day 22 我會說「AI 在剪輯這一章幾乎沒有判斷權」。今天這件事是那句話的例外。

它唯一一次被授權判斷「內容存不存在」,而它錯了。

而且錯的方式很典型:它沒有拒答,它給了一個看起來合理的答案。跳針的逐字稿讀起來就像「這裡在講廢話」,而不是「這裡我不知道」。

模型不會告訴你它在猜。 這是把模型輸出接進自動判斷時最該記住的一件事:它的輸出格式在確定跟不確定的時候一模一樣。

那五道閘門一條都沒有攔到這件事,因為剪輯是可逆的(重跑就好)。可逆確實限制了損害,我確實重剪了。但可逆不代表無害,只代表可以修。 而如果我沒有重聽那一段,那五分鐘就永遠不見了。

代價

這個修法讓剪輯變慢了。

現在每個剪點要跑 RMS 包絡分析,而不是直接讀 SRT 的數字。多了一步計算,多了一些程式碼。

而它的收益是不出事,這種收益永遠看起來不划算,直到出事那次。

第二個代價:我沒有做「跳針偵測」。

那次事故之後,正確的做法應該是加一個檢查:當逐字稿裡出現連續重複的句子,標記那一段為「ASR 可能失效」,要求人工確認。這是一個很好寫的規則(連續 N 句相同即標記),而我沒寫。

所以同樣的事情如果再發生一次,我還是只能靠重聽發現。

帶走什麼

不要用一個模型的輸出,去回答它能力範圍外的問題。

ASR 擅長「這句話是什麼」,不擅長「這裡有沒有話」。這兩個問題聽起來很近,而在辨識失敗的區間,它們的答案會分岔,因為模型失敗的時候不會回報失敗,它會回報一個猜測。

判斷方法:對每一個「我拿模型輸出來做決定」的地方,問一句——如果模型在這裡完全失效,它的輸出會長什麼樣?

如果答案是「空的」,那還好處理。如果答案是「看起來正常但內容是編的」,那你就需要第二個訊號源。

第二條,很具體、可以直接抄:

「有沒有」用訊號量,「是什麼」用模型判。

聲音的有無用音量偵測,內容用 ASR;檔案的存在用 stat,內容用解析器;服務的存活用 health check,行為正確性用測試。這兩類問題永遠應該用不同的工具回答。

第三條:量測比計算可靠。 SRT 的時間碼是模型算出來的,音量包絡是量出來的。前者會有系統性偏移,後者不會。

明天講整條組裝鏈的參數,以及一個從頭到尾零漂移的數字。


上一篇
Day 17|95 個字元的提示詞,和 13% 的 commit
下一篇
Day 19|一條組裝鏈,只有一個參數從頭到尾沒漂過
系列文
我以為我保留了五道閘門19
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言