iT邦幫忙

2026 iThome 鐵人賽

DAY 11
0
AI 自動化

情報進來,內容發出去:30 天拆一條每天真的在跑的 AI 內容產線系列 第 11

Day 11|時間窗找到了,怎麼確認「這是誰說的」?

  • 分享至 

  • xImage
  •  

我把一份合成測試資料裡兩個人的名字整組對調,再算一次說話者分群的錯誤率。結果是 0。

不是 0.1,不是接近 0,是 0。名字全錯,指標說沒問題。

這不是指標壞掉。後來發現,它本來就不是拿來回答「這個人叫什麼」的。

先接上前兩天

第 10 天把整理後的文字帶回指定字幕片段和影音時間窗。找得到位置,不代表聽得對;聽得對,也不代表知道是誰說的。多人會議或訪談,永遠多這一題。

第 5 天碰過一次,那時只做到不把「說話者可能判錯」藏起來。今天要往前一步,實際檢查:一個像 speaker_0 這樣的匿名標記,要具備哪些證據,才有資格變成名字、具名引言、待辦負責人。

天數 已回答的問題 不在那一天處理的事
Day 5 怎麼保留原始轉錄、說話者標記、不確定性與人工複核點 沒有建立身分綁定與下游放行規則
Day 10 整理後文字能不能回到指定字幕片段與時間窗 沒有確認說話者姓名
Day 11 匿名分群怎麼升級成綁定特定版本的身分,以及哪些具名輸出可以放行 不判斷訊號是否新鮮,也不替來源主張做外部查證

Day 5 守住的是不把未知藏掉。Day 11 要做的,是讓未知真的改變後面能輸出什麼。

全文只回答一個問題:

一個匿名說話者標記,要具備哪些證據、而且綁在哪一份轉錄產物上,才可以升級成姓名、具名引言或待辦負責人?

我把它拆成四個判定。前一層通過,只讓下一層開始檢查,不會連姓名、引言和責任一起放行。下面講。

四盞燈,不能接在同一個開關上

一場會議錄音進來,系統做的第一件事是把聲音分桶:這段和那段聽起來像同一個人,丟同一桶。桶子上只有編號,cluster_0cluster_1,沒有名字。

第二件事,是猜每個桶可能是誰:比對聲紋、看聲道、聽自我介紹。產生的是候選,不是答案。

第三件事,是有人真的確認:這桶就是某某人,而且要記下確認的是哪一版時間軸。錄音重切過,舊的確認不能直接沿用。

第四件事,才是決定可以拿這個名字做什麼。匿名時間軸、姓名標記、具名引言、待辦負責人,需要的證據不一樣。

判定層 回答什麼 最小輸出 不能順便證明
匿名分群 哪些時間段看起來屬於同一個聲音? cluster_id 與時間段 這個人叫什麼名字
身分候選 這個群組可能對應哪個已知人物? 候選、證據參照、匹配狀態 候選已經由人確認
身分綁定 誰核准哪個群組對到哪個人物?核准又綁在哪一版產物? confirmed、對照摘要、來源摘要、核准紀錄 原話聽得正確或可以公開
下游放行 這份證據足以輸出匿名時間軸、姓名、具名引言,還是待辦負責人? allowneeds-humanreject 缺少的文字忠實、公開授權與責任證據

只存一個 confidence 不夠。每一層都要留自己的證據、狀態和失敗原因。不然下游看到一個 0.92,不知道它是在說聲音分對了、名字猜對了,還是有人確認過了。

這四層是我替這條產線畫的分法,不是任何供應商或標準組織的共同規格。但「不同任務要分開評」有先例:NIST 在 2007 年的會議辨識評測(RT-07)就把語音轉文字、回答「誰在何時說話」的說話者分段歸群,以及把兩者結合的具說話者歸屬文字,列成三個不同任務。時間段分群通過,還不能替文字內容和真實身分一起背書。

工具給的欄位,各自只回答一題

這條線在真實工具的文件裡也看得到。

第 5 天講過 ElevenLabs 的 logprob 是字詞的對數機率,不是說話者信心。這裡只補一句:字有沒有聽對、說話者有沒有分對、名字有沒有綁對,是三個問題,logprob 只回答第一個。

今天真正要看的是另外幾個選項。它們各管一件事,沒有一個是姓名證據:

▸ 多聲道模式會關掉說話者分群,直接用聲道編號產生 speaker_0speaker_1,每個聲道各自轉錄。前提是一個聲道只有一個人,最多五個聲道。同一聲道混進兩個人,兩人會共用同一個標記。聲道給的是穩定的聲音來源位置,channel_0 仍然不是誰的身分證。

use_speaker_library 預設是關的。開了分群之後,才會把偵測到的說話者拿去比對工作區登錄過的聲音。這給的是候選,仍要保留設定、來源版本和確認狀態。

detect_speaker_roles 只是把標記換成客服與客戶這類角色,不能和多聲道一起用。

diarization_threshold 調的是「一個人被拆成兩個」和「兩個人被合成一個」之間的取捨。它不是姓名可信度的門檻。

pyannoteAI 的文件把這條線畫得更直接:分群產生 SPEAKER_00 這種通用標記;身分辨識再拿已知聲紋去配對特定人物。官方明說聲紋只用來找人,不會讓分群變準。建立聲紋時要求音訊裡只有目標說話者,最長 30 秒。

所以身分這一層,至少多出兩個來源問題:聲紋從哪來?誰確認它綁到哪個人?

信心分數也是分開給的。pyannoteAI 提供取樣點層級的分群信心、發言段落層級的分群信心,以及聲紋對群組的身分辨識信心。文件特別提醒:身分辨識信心衡量的是聲紋有多相符,不是分群器對這段屬於哪個群組有多確定。

這些分數是 0 到 100 的刻度,文件沒有說它是校準後的機率。所以它適合拿來排順序:先複核哪一段。它不適合當真相的機率。2024 年 Chowdhury 等人的研究就在做這件事:把分段信心交給後續處理,優先挑出可能有問題的片段。這支持一個很窄的結論,信心可以決定先看哪裡;它不能單獨把候選名字升級成已確認。

兩把尺:一把先配對,一把直接比

回到開場那個結果。名字全錯,錯誤率為什麼還是 0?

先講 DER,說話者分段錯誤率。它把三種時間加起來:誤接(沒人說話卻標了)、漏接(有人說話沒標到)、混淆(標到別人)。再除以參考語音的總時間。

差別在算之前那一步。pyannote.metrics 會先用匈牙利演算法(一種標準的最佳配對算法),替參考標記和預測標記找最佳的一對一對應,然後才計算。

用改考卷來比喻:它會先看你的答案卡,幫你把每個選項對到最像的正解,再算你錯幾題。

所以 cluster_0 改叫 cluster_1,它不在意。person_alphaperson_beta 整組對調,它也會跟著把對應對調。時間分群沒變,DER 就是 0。

這是設計,不是 bug。DER 回答的是「時間怎麼切」,本來就不該被匿名標記叫什麼影響。

要看名字對不對,得換一把尺。說話者身分錯誤率 IER 的分子一樣有誤接、漏接和混淆,差別在混淆這一項直接比參考和預測的身分標記,不先重新配對。名字對調,每一秒都算混淆。

這把尺有個前提:參考答案本身要可信。合成資料有標準答案,所以算得出來。真實會議如果沒有獨立核實過的名字,公式算不出真相。

一場 40 秒的受控實驗

先交代輸入。這次沒有拿任何私人會議當測試資料。

測試資料只有四段時間:0 到 10 秒是 person_alpha,10 到 20 秒是 person_beta,接著兩人各再出現一次,總長 40 秒。系統側用 cluster_0cluster_1 表示兩個匿名群組。

這份資料明示為合成:沒有音訊、沒有逐字稿、沒有真實姓名、沒有重疊語音、沒有漏接或誤接。它不是聲學實驗,不能拿來推論任何模型、語言、麥克風或真實會議的準確率。

稽核器只測兩件事:匿名標記換名字時,分群指標會不會改;姓名對照被換掉或沿用到新版產物時,控制層會不會停止具名輸出。

變異 DER IER 控制結果
原始匿名分群 0 不適用 最佳映射找到兩組正確時間
匿名標記交換 0 不適用 指標不受標記字串影響
姓名交換 0 1 有標準答案時可看出身分全錯
核准後只交換姓名表 不適用 不適用 rejectapproved-binding-digest-mismatch
來源產物換版後沿用舊核准 不適用 不適用 stalesource-artifact-mismatch

姓名交換那一列,兩把尺要並排讀:DER 是 0,IER 是 1。40,000 毫秒全部變成身分混淆。

本機程式依 pyannote.metrics 4.1 文件的公式實作受限版本:兩人、無重疊、完整覆蓋。我另外裝固定版 pyannote.metrics 3.2.1,在 collar=0、計入重疊的設定下獨立重算,結果一樣是 0、0、0、1(評分範圍用參考與預測的聯集近似,不是官方 UEM 檔)。這份資料本來就沒有重疊,所以設定不影響結果。

後兩列不是指標題,是控制題。核准之後只把姓名表換掉,判定是 reject;來源產物換了版本卻沿用舊核准,判定是 stale

老實說,這五列擺在一起很像一張成績單。但它們不能合成一個總分。前兩列驗的是分群對標記字串不敏感;第三列需要可信的身分標準答案;後兩列只驗核准內容和來源版本是否仍然一致。

姓名表要帶回程資料

實驗做完,我把「身分綁定」需要的最小資料形狀整理出來。這是本文的提案,不是 ElevenLabs、pyannote、NIST 或任何 RFC 的官方格式,也不是我現行流程已經接上的東西。

{
  "source_artifact_sha256": "…",
  "cluster_id": "cluster_0",
  "person_ref": "person_alpha",
  "identity_status": "confirmed",
  "evidence_refs": ["synthetic-reference-v1"],
  "binding_sha256": "…",
  "approval_record_ref": "…"
}

每個欄位有一個工作:

source_artifact_sha256 鎖定這張姓名表適用哪一版說話者時間軸。

cluster_id 保留供應商或分群器給的匿名標記,不覆蓋。

person_ref 指向另外管理的人物參照,不直接塞真名。

identity_status 不只放「通過」,還要能表示候選、未知、拒收、過期。

binding_sha256 是姓名表的摘要,要存到另一個地方的核准收據裡:不同權限、不同人能改的系統。跟姓名表放在同一個目錄、改完自己重算一次,就不算核准過。

這次跑出來的關係長這樣:說話者時間軸摘要是 1748d313…c6c8,核准姓名表摘要是 2e81dde7…0e58。收據分開保存後,正式對照得到 approved-binding-current。只把兩個 person_ref 對調,姓名表摘要就變了,舊收據拒收。把時間軸改成第二版,姓名表完全不動,也會因為來源摘要不同被標成過期。

真正要保存的是這條鏈:

特定版本的匿名時間軸
  → 姓名對照內容
  → 獨立核准收據
  → 允許的下游輸出

摘要要能重算,得先固定寫法

有個細節容易漏。JSON 物件的鍵順序、空白不同,語意可能一樣,位元卻不同。同一張姓名表,只是換了鍵的順序,就會得到不同的摘要。

RFC 8785 定義的 JSON Canonicalization Scheme 就在解決這件事:固定基本型別的序列化、遞迴排序屬性、用 UTF-8 輸出。這次程式只對受限資料做遞迴鍵排序,沒有宣稱完整通過 JCS 所有邊界。

固定表示只讓摘要可以重算。它不能證明 person_ref 填的是對的人。

雜湊抓得到換表,抓不到一開始就認錯

這裡算了兩個 SHA-256:一個辨認說話者時間軸的版本,一個辨認已核准的姓名表。核准後姓名表被換掉,或來源產物換版卻沿用舊核准,摘要都會不同。

但如果人一開始就認錯人,那張錯的姓名表也能得到一個完全合法的摘要。摘要只認位元有沒有變,不認內容對不對。它不是數位簽章,不是身分證明,不是人工判斷的正確性,也不是公開授權。

要抓「一開始就認錯」,需要獨立的身分證據,或再做一次人工核實。再算一次雜湊沒有用。

名字確認了,引言和待辦還是不能自動過

最後一層,決定這個名字可以拿去做什麼。

輸出 最小條件 本次結果
匿名時間軸 有可用分群結果 allow
具名說話者標記 身分綁定已核准,且來源版本仍相同 allow
具名引言 再加文字忠實確認與公開授權 needs-human
待辦負責人 再加明確的責任指派內容與人工批准 needs-human

「某人說了這句」不等於「這句每個字都聽對」,也不等於「某人接受了這個待辦」。

具名引言要再加文字忠實確認和公開授權。這次沒有人工聽校,也沒有授權紀錄,稽核器給的理由是 transcript-fidelity-uncheckedpublication-permission-unknown,所以停在 needs-human。待辦負責人要再加明確的責任指派內容和人工批准,理由是 responsibility-evidence-missinghuman-assignment-approval-missing

摘要模型如果只看到姓名和句子,很容易把這三個判定壓成同一個肯定句:某某說他會處理。看起來很順,其實一次跨了三層。

放行條件是本文的設計。真實組織要依用途、授權和風險自己調。

這次能抓到什麼,抓不到什麼

小實驗最怕寫大。下面這張表,是今天最重要的誠實邊界。

問題 這次能否抓到 需要什麼
匿名標記只改名字 不視為錯誤 DER 的最佳一對一映射
有可信標準答案時,兩個姓名交換 可以 直接比較身分標記,IER = 1
核准後姓名表遭修改 可以 不同信任邊界保存的核准摘要
舊姓名表套到新版時間軸 可以 目前來源摘要與核准來源摘要
人工一開始就認錯人 不行 獨立身分證據或再次人工核實
重疊語音、漏接、誤接與真實聲學誤差 沒有測 有標註的公開音訊、固定評分條件與正式指標實作

完整性檢查不能冒充身分真實性檢查。

之後真的要測語音模型,AMI Meeting Corpus 是一條可以公開重現的路:約 100 小時會議,有個別頭戴式麥克風、混音與遠場訊號,還有逐位說話者的人工逐字稿。可以固定官方資料切分、交界寬容區、是否計入重疊,同時報 DER 和 IER。今天沒有下載或跑 AMI,只留這條路線。它是英文語料,部分參與者非母語,公開模型也可能看過這些資料,不能直接外推到臺灣華語的私人會議。

今天刻意不寫的六件事

1/ 不做 ElevenLabs、pyannote 或其他工具的準確率排行榜。

2/ 不提出適用所有錄音的通用分群或身分門檻。

3/ 不公開任何私人會議的音訊、逐字稿、人名、引言、聲紋或商業資訊。

4/ 不替自己聲明聲紋蒐集、保存、同意或法規做法。

5/ 不把「某人說了」擴張成「某人說的是真的」;外部主張補證留到 Day 13。

6/ 不把整條內容產線改寫成多代理編排;通用編排留到 Day 16。

不知道是誰,是合法狀態

身分還沒確認,工作流不必整條停掉。匿名時間軸可以繼續往下走;姓名、具名引言、責任欄位先停。

這樣會少一些具名產出。

Day 12 把同一個原則帶到每日情報:固定時間到了,卻沒有足夠新訊號時,系統能不能老實輸出「今天沒有題目」,而不是把日期不明或昨天的內容包裝成今天的新消息?

參考資料


上一篇
Day 10|逐字稿整理乾淨後,還找得回原片嗎?
下一篇
Day 12|不知道是誰,不用整條重跑:具名分支怎麼暫停再繼續?
系列文
情報進來,內容發出去:30 天拆一條每天真的在跑的 AI 內容產線12
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言