我是在整理一段口播字幕时,重新遇到这个问题的。语音识别把“语音写作”听成了几个读音相近、意思完全不同的词。与此同时,字幕里还夹着 MiniMax、Opus 5、WorkBuddy 这样的软件和模型名称。它们看起来只是几个错别字,实际上却把同一个问题暴露得很清楚:字幕纠错到底是在查字,还是在理解一句话?
一开始我也倾向于找一张更大的错字表。把常见误识别都列进去,下次碰到就直接替换,听起来最稳定,也最省事。但继续拆开这次的处理过程后,我发现真正需要解决的不是“有没有一个错字列表”,而是哪些错误可以确定地改,哪些错误必须依赖语境判断。如果这两类动作混在一起,表越大,误改的机会反而越多。
先把一个错误拆成3种不同的问题
字幕里的错误至少有3种来源。第1种是确定性错写,比如某个词在当前内容里几乎只会有一种正确写法;第2种是同音或近音误识别,单看这一句无法确定,必须联系脚本、前后句和说话主题;第3种是专名格式问题,字可能没有错,但大小写、空格或品牌写法不统一。
这3种问题的表面结果都一样:屏幕上的文字不对。可是它们需要的证据并不一样。确定性错写可以交给词表,语境误识别要看整句意思,专名则需要一套稳定的规范。把它们都叫作“错别字”,就会把判断难度藏起来,也会诱使我们用同一种自动替换处理所有情况。
字幕纠错的第1步不是扩大词表,而是先判断这次错误属于哪一种。
这个分类会直接改变后面的动作。已确认的错写可以自动修,含义不确定的句子应该留下复核,专名则要在最后统一格式。流程只要顺序反过来,后面的推理就会建立在已经被错误改写的文字上,越修越难知道原句到底说了什么。
词表适合处理确定性错误
词表最有价值的地方,不是它能包办理解,而是它能把重复出现、边界清楚的错误固定下来。比如这次新增的“语写”,在语音识别里可能出现“雨鞋”“淤血”“雨血”等写法。结合实际使用场景,这些词并不是内容要表达的对象,而是同一个术语的发音误识别。将它们加入映射后,字幕校字可以稳定完成,不需要每次重新猜一遍。
这类替换有两个特点。第1,它的输入和输出都可以明确写出;第2,错误不会因为段落变化就突然获得另一种合理解释。这样的规则适合放在字幕进入后续处理之前,因为它做的是清理确定性噪声,而不是替作者决定一句话的意思。
如果不先处理这些稳定错写,后面的脚本参考会被迫花时间辨认一个本来已经知道答案的问题。更麻烦的是,同一个词在不同片段里可能被识别成不同写法,人工复核时就要反复确认,回归测试也很难覆盖。词表的意义,正在于让已经确认过的判断不要每次从零开始。
但词表也必须有边界。“雨鞋”在某段内容里可能真的指鞋子,“淤血”也可能是医学语境中的真实词。如果不看场景就无条件替换,所谓的稳定规则就会把真实语义删掉。因此,新增一个映射时,我更愿意同时记录它的适用范围,并保留单片撤回的能力。一次误判不应该永久污染所有字幕。
同音误识别要交给上下文
这次真正需要推理的部分,是语音识别没有听错声音,却没有听懂意思。说话人可能明确讲的是“语写”,识别结果却落成了另一个常见词。单独拿出这个词,任何候选答案都像有一点道理;把前后句放回关于语音、字幕和写作流程的段落里,答案才会变得清楚。
原有流程已经把这部分单独放在脚本参考纠错层。它不是继续堆近音词,而是让系统参考原始脚本,结合“正在念什么、正在发挥什么、说话口音怎样”来判断。脚本提供了比单个词更长的语义边界,前后文则帮助确认这个词在当前段落里承担的角色。
当一个词存在真实语义时,规则应该先保留不确定性,而不是替模型抢答。
纯口播没有脚本时,处理方式更保守:不确定句子会被写入复核文件,交给后续逐句通读和推理。这个动作看起来比自动替换慢,却避免了把猜测伪装成确定结果。字幕是要让人阅读的文字,一处自信但错误的替换,往往比保留一处待复核更难发现,因为它已经变成了一个语法上通顺的错误。
这里最容易误判的,是把“多数时候正确”当成“任何时候都正确”。某个词在常见口播里大多指一个软件名,并不代表它在所有内容里都只能指软件。没有脚本时,我宁愿让少量句子停在复核边界,也不让一个覆盖过宽的规则替我改变说话人的原意。
专名不是普通错字
软件名和模型名又是另一层问题。MiniMax、Opus 5、WorkBuddy 这些名称,识别结果可能有大小写不一致、空格缺失或词被拆开的情况。它们未必影响人理解,却会影响字幕的专业感,也会让同一篇内容中的称呼前后不一致。
我会把专名规范放在语义纠错之后。先确认这句话确实在说某个产品或模型,再把写法统一成约定格式:MiniMax 保持品牌大小写,Opus 5 保留数字前的空格,WorkBuddy 不被拆成两个普通单词。这样做的原因很实际:如果在没有语境确认前就强行套专名格式,普通英文词也可能被误认成产品名。
这也是为什么“让模型每次从零猜专名写法”不是好办法。模型可能知道这个名字,但不同片段仍可能输出不同大小写;某个名字在一处被写对,也不意味着下一处会同样稳定。专名表承担的是规范化,不是理解整段内容。把已确定的名称写进规则,能让最后一层变成可重复检查的动作。
回归测试比一次改对更重要
字幕纠错很容易产生一种假象:眼前这一条改对了,就以为流程已经完成。实际上,真正需要验证的是同类错误以后还会不会反复出现,以及修复一个误识别有没有破坏另一个真实词义。针对新增的语写相关错写和软件专名规则,相关的字幕校字和脚本参考测试都通过了,这说明新增判断至少没有破坏已有链路。
但测试通过也不等于所有句子都能自动判断。回归测试适合验证确定的输入会得到确定的输出,比如几种已知错写是否统一变成“语写”,几种不同写法的专名是否统一成 MiniMax、Opus 5 和 WorkBuddy。它不应该被用来证明没有脚本时所有同音词都能放心替换,因为那属于开放语境问题,答案取决于具体内容。
一个成熟的纠错流程,不是把所有句子都自动改完,而是知道哪些句子必须停下来复核。
我因此会为高频误识别保留回归样例,也会为可能有真实语义的词保留反例。前者防止已修复的问题反复出现,后者提醒自己不要把一次成功扩大成无条件规则。若某条映射在实际片段中造成误改,还要能单独撤回,而不是只能把整张词表恢复到旧版本。
下次我会怎么做
下次遇到语音转字幕的纠错任务,我会先把工作分成3层。第1层是确定性词表,只处理已经核对过、输入输出清楚的错写;第2层是脚本和上下文推理,把同音词放回完整句子,能确定才改,不能确定就进入逐句复核;第3层是专名规范化,在语义确认后统一大小写、空格和固定写法。
在这3层之外,我还会做两项小检查。第一项是为高频误识别加回归样例,确认新增规则没有破坏原有内容;第二项是检查边界反例,确认真实出现“雨鞋”或其他普通词时仍有撤回和人工纠正的入口。这样做不是为了让流程看起来复杂,而是为了让每个自动动作都能回答一个问题:它凭什么确定?
这件事让我重新意识到,字幕纠错真正沉淀的不是一张越来越长的错字表,而是一条判断链。词表负责记住已经确认的事实,脚本负责提供语义范围,复核负责接住暂时无法确定的句子,专名规则负责最后的表达一致性。真正可靠的自动化,不是替人取消判断,而是把确定的判断固定下来,把不确定的地方清楚地交还给人。