两个人的对话,我的转录器硬说有五个人
我有个一直在跑的小工具,把语音备忘录自动转成结构化笔记。录完几分钟,整理好的文稿就躺在那儿了。
用了大半年,转写本身早就不是问题。真正一直没搞利索的,是另一半,也就是「谁在说」。
把声音变成字,今天随便一个模型都够用。但一段两个人的对话,要标清楚哪句是 A、哪句是 B,这件事叫说话人分离(diarization),它才是真正难的那一半。难到什么程度呢?我有一段 28 分钟的录音,从头到尾就两个人,转出来标了五个说话人。
第一版,Gemini 切块,缝合处全乱
最早的方案是 Gemini。长音频有个坑:丢一整个文件给它,超过十几分钟它就开始跳段、循环、自己编时间戳。所以得切块,按静音边界切成十来分钟一段,并行转,每段都在模型的清醒区间里。
转写质量没问题,但切块带来了新麻烦。每一块都自己从「说话人0」开始编号,第一块的「说话人0」,到第二块可能变成了「说话人1」。
我做了个补救:相邻两块留 60 秒重叠区,靠重叠区里同一句话的归属去投票,把编号对齐。大部分时候管用。可只要某个缝合点投票投歪了,整条后面的编号就跟着错位,说话人数量一路虚高。缝得越多,错得越离谱。
第二版,换全局分离,还是把搭话拆成了人
既然跨块缝合不靠谱,那就别缝了,直接对整段音频做一次全局分离。我接了 Senko,苹果芯片上跑 CoreML,比 pyannote 那套快几十倍。它确实比缝合稳,至少编号是全程一致的。
但它还有个改不掉的毛病,把短插话当成新人。真实对话里全是「嗯」「对啊」「然后呢」这种搭话,一个人在讲,另一个人时不时应一声。Senko 经常把这些一两个字的应答判成第三、第四个说话人。28 分钟那段它好歹判对了 2 人,但换几段长一点的,立马虚高。
中间插一脚,豆包转写更好,分离更虚
这中间我去试了火山引擎的豆包,想看看国产模型在中英混说上是不是更顺。转写质量确实是惊喜,中文、中英混说都很干净,带标点,口语顺。这本来就是我最初的痛点,它解决得比 Gemini 那套漂亮。
可一看说话人,更崩了。极速版那个 28 分钟判了 5 个人,2.0 判 4 个,比 Senko 还虚。
到这儿我大概看明白了:通用模型顺手做的说话人分离,普遍都偏激进,宁可多切几个也不肯合并。它分不清「嗯」是搭话还是新人,干脆都算新人。
一个坑,火山有两套鉴权,别认错
试豆包的过程里卡了我大半天的,其实是个鉴权的坑,记下来给后来人。
火山的语音服务有两套账号体系。老控制台给你一组 AppID 加 AccessToken,新控制台给你一个 x-api-key,而这两套绑定的可用资源并不一样。我一开始拿老的 AppID 去调 2.0 的接口,一直返回「resource not granted」,怎么看配额都是有的,就是不让用。折腾到后来才反应过来,2.0 和后面要讲的妙记,都得走新控制台那个 x-api-key。换了头,立马通。
文档里这件事写得很隐蔽。如果你也在调火山的语音接口撞了「资源没授权」,先看是不是认错了鉴权方式。
最后落点,把分离交给专门做它的模型
真正解决问题的是火山的妙记(Lark Minutes ASR)。它和前面那些不一样,说话人分离是服务端做的,跟转写一次调用一起出,不用我在客户端缝任何东西。
我拿 5 段真实录音做了对比,其中 4 段都是两人对话:
| 录音 | 极速版 | 2.0 | 妙记 |
|---|---|---|---|
| 28min | 5 | 4 | 2 |
| 38min | 3 | 3 | 2 |
| 57min | 3 | 3 | 2 |
| 68min | 4 | 3 | 2 |
| 3.45h(剧集) | — | 10 | 3 |
四段两人对话,妙记每一段都精准判 2 人,另外两家全程虚高。那段 3.45 小时的长录音,别家要么传不上去,要么判出 10 个人,妙记一次吃下来判 3 个。那是个多角色的剧集音频,3 个比 10 个靠谱太多。
那一刻我大概理解了一件事。与其让一个通用模型顺手分离,不如把这件事整个交给一个专门做它的服务端模型。分离不该是转写的副产品,它该是一个独立的、被认真对待的任务。
还有一个坑,妙记要公网链接,但跨境上传慢到离谱
妙记有个硬要求,它不收你直接上传的文件,只认一个公网能下载的链接。本地录音得先传到一个对象存储上,再把链接给它。
我用了火山自家的 TOS(对象存储),桶开在上海。妙记从上海取文件是境内的,飞快。慢的是另一头,我从美国把文件传到上海。单线程传,34KB/s,一个 8 兆的文件传了将近四分钟,这显然没法用。
跨境链路有个特点,它卡的是单条连接的速度,不是你的总带宽。所以解法很直接,开并行分片上传,把一个文件切成多段同时传。换上之后,同样的文件 5 秒传完。这个细节值得记一笔:遇到跨境上传慢,先别急着怪带宽,多开几条连接,很多时候一下就上去了。
整套换完,我那个转录器和对应的转写技能,默认都走妙记了。录音进去,出来的文稿带着对的说话人标签。
从 Gemini 切块缝合,到 Senko 全局分离,到豆包,再到妙记,绕了一大圈。回头看,转写从来不是瓶颈。卡了我大半年的,是「谁在说」这半件事,而它的答案不在更聪明的缝合算法里,在一个肯把分离当正经任务做的模型里。
如果你也在折腾会议录音的工具链,我之前还写过一篇开源方案横评,可以一起看。