企业侧缺的不是转写,是可核对的时间轴
内部会议录音的常见去向有两条:一条做成带字幕的回放视频,供没参会的人补看;一条做成纪要,按议题定位到录音的具体位置,方便追溯"这句话是谁在什么时候说的"。
两条都依赖同一件东西——带时间刻度的文本。转写平台普遍能给全文,好一点的给句级时间戳,但企业场景里句级往往不够用:一个句段可能横跨十几秒,做成字幕读不完,做成纪要锚点也太粗。而人工对时间轴这一步,是整条链路里最难规模化、最难保证一致性的环节。
这篇记录我用阿里云百炼 CLI 跑完一轮 TTS→ASR 往返后,从管线接入角度整理的四件事:时间结构分几层、字幕轴该由哪一层推导、验收标准怎么定、机器与人工的分工线画在哪。
一轮可复现的验证链路
验证方式是用 TTS 造一段已知原文的素材,再让 ASR 转回来。原文已知,往返差异就能逐条归因,不必猜哪处是识别问题、哪处是输出约定。
bl speech synthesize --text "今天下午三点在第二会议室开选题会,记得带上周的数据报表。" --voice longcheng_v3 --out 通知.wav
bl speech recognize --url 通知.wav --language zh --out 通知.json
转写全文与原文的唯一差异是"三点"变成"3点",属于数字规范化输出。Key 在控制台密钥管理页创建,命令签名与音色/模型清单见阿里云百炼 CLI(bl)。
第二轮换成三句议题素材("第一个议题是季度复盘。第二个议题,下月选题排期。散会前记得提交周报。"),转写回来后三句被并成了一个句段,标点也被规范化("复盘。第二"变成"复盘,第二")。这一轮的结果直接决定了后面的管线分层。
管线分层:三层时间结构各有各的位置
返回的时间信息是三层,企业管线里应该分开消费,不要混用:
| 层级 | 本轮实测返回 | 在管线里的位置 | 消费方 |
|---|---|---|---|
| 全文 | 整段转写文本 | 纪要正文、全文检索索引 | 纪要系统、搜索 |
| 句级 | 1 段,160–4440ms | 章节打点、议题粗定位 | 回放进度条 |
| 词级 | 16 个词,每词带起止毫秒 | 字幕 cue 边界、精确锚点 | 字幕生成、纪要跳转 |
词级数组节选:
| 词 | 起(ms) | 止(ms) |
|---|---|---|
| 今天 | 160 | 400 |
| 下午 | 400 | 680 |
| 3 | 680 | 840 |
| …… | …… | …… |
| 会 | 2480 | 2640 |
| 记得 | 2920 | 3200 |
| 报表 | 4160 | 4440 |
关键在间隔:多数相邻词间隔为 0,"会"到"记得"之间是 2640→2920,空了 280 毫秒,对应原文逗号处的自然停顿。标点不在词级输出里,但停顿以时间差的形式保留了下来,这就是字幕轴可以自动推导的物理依据。
字幕轴推导:静音间隔切分
管线里的切分节点是一个纯函数:输入词级数组与阈值,输出 cue 列表。规则是相邻词间隔超过阈值即断开,cue 起止取该段首词的"起"与末词的"止"。
本轮阈值取 250ms,产出真实 SRT:
1
00:00:00,160 --> 00:00:02,640
今天下午3点在第二会议室开选题会
2
00:00:02,920 --> 00:00:04,440
记得带上周的数据报表
断点落在原句逗号处(280ms > 250ms),其余位置间隔为 0 不被切断。时间格式 HH:MM:SS,mmm 由毫秒直接换算,不取整到秒——取整会让字幕与语音错位。
两种看起来更省事的做法,实测都不成立:
| 做法 | 不成立的原因 |
|---|---|
| 一个句段 = 一条字幕 | 三句素材被并成 1 个句段,一条 cue 会横跨多句 |
| 按转写标点二次切分 | 词级无标点;句级标点被规范化,句号可能变逗号 |
阈值治理:写进规范,而不是写进代码常量
250ms 是对本轮素材校准出的值,不能当常量固化。不同素材类型的停顿分布不同,阈值应作为按素材类型配置的参数管理:
| 素材类型 | 阈值方向 | 校准依据 |
|---|---|---|
| 念稿、播报 | 调大 | 句内换气也可能超过 250ms,偏小会碎切 |
| 快语速讨论 | 调小 | 句间停顿可能不足 250ms,偏大会漏切 |
| 新接入的会议类型 | 先统计间隔分布再定 | 句内接近 0、句间几百毫秒,阈值取在两峰之间 |
规范化的做法是:每接入一类新素材,先跑一遍间隔分布统计,把选定阈值与统计结果一起归档,后续同类素材沿用并在抽检中复核。
验收标准表
要把这条链路写进团队规范,下面几条可以直接抄:
| 验收项 | 标准 | 本轮实测状态 |
|---|---|---|
| 转写准确率核对 | 转写全文与原文逐字比对,差异逐条归因(识别错误 / 输出约定) | 达成:唯一差异为"三点"→"3点",判定为数字规范化 |
| 数字规范化后处理 | 明确字幕与纪要各自采用哪种数字写法,规则落文档 | 规则已识别;具体写法由业务侧决定 |
| 句段并段处理 | 不将句段数当作原句数,cue 边界一律由词级推导 | 达成:三句素材并成 1 段,已确认不可用作切分单位 |
| 切分断点抽检 | 按素材时长抽取若干断点,人工核对是否落在自然停顿处 | 本轮 2 条 cue,断点与原文逗号对齐(280ms 停顿) |
| SRT 时间格式 | HH:MM:SS,mmm,毫秒级,不取整到秒 |
达成:起点 160ms 与 2920ms 保留毫秒 |
| 阈值归档 | 每类素材的阈值与间隔分布统计一起留档 | 本轮 250ms;归档机制属建议做法 |
| 说话人维度 | 多人会议需先验证 --diarization 效果再上线 |
未实测 |
机器与人工的分工
分工的判断标准是:凡是能被时间数据表达、能被脚本判定的交给机器;凡是需要业务上下文与责任归属的留给人,并要求人在结构化产物上签署,而不是在成稿字幕上签署。
| 环节 | 机器 | 人工 |
|---|---|---|
| 音频转写 | bl speech recognize 输出全文 + 三层时间结构 |
抽样核对转写全文,确认差异归因 |
| 数字与标点规范化 | 按已归档规则做后处理 | 决定字幕/纪要各自采用哪种写法 |
| cue 边界推导 | 按阈值切分,输出 cue 列表与 SRT | 抽检断点是否落在自然停顿处 |
| 阈值取值 | 统计间隔分布,给出候选阈值 | 结合素材类型定档并归档 |
| 字幕文案润色 | 不介入 | 按可读性重排、控制单条字数 |
| 纪要议题锚点 | 用句级/词级时间生成跳转锚点 | 确认议题划分与措辞 |
| 多人会议说话人归属 | --diarization 能力本轮未验证 |
验证前不承诺归属准确性,人工标注兜底 |
边界
- 数字规范化:三→3 是 ASR 输出约定,不是错误;下游写法由业务后处理决定
- 词级无标点:按标点切条不成立;静音间隔切分是本文方法,阈值需按素材自校
- 句段会并段:多句素材的句段数不等于原句数,句段不能当字幕条
- 说话人分离未实测:
--diarization本轮未跑(素材为单说话人),多人会议"谁说了什么"的效果不在本文结论内
还有一条前提必须写进接入评估:本轮素材为 TTS 合成音频,干净、单说话人。真实会议录音的底噪、抢话、重叠话、麦克风差异会改变间隔分布,切分表现与阈值必须在自己的素材上重跑验证后才能定档。本文不含任何模型能力评测与横向对比结论。
接入起点
三步:准备一段自己的会议录音、bl speech recognize --url <本地路径> --language zh --out result.json 转写、用词级数组跑一遍间隔分布统计再定阈值。
第一步跑完先看两件事:转写全文与原始记录的差异集中在哪,以及句段数与你实际说的句数对不对得上。这两项决定了后处理规则要写几条、以及 cue 边界为什么必须走词级。音色与模型清单可在阿里云百炼首页浏览。