Development Log
时间线在下面,但这一页真正值得看的是后半段:那些单元测试全绿、跑起真实素材才暴露的问题。它们不是这个项目独有的,是这类多模态系统的通用失败模式。
Timeline
从一份需求文档和一套只有函数签名的骨架开始。
此前界面五页都能点,但提交任务、看进度、复核候选、导出这条主线全是演示数据,只有命令行能走完。补齐四个空体接口后,界面从「能点」变成「能走完流程」——每一次留用、弃用、微调都落到磁盘上,弃用原因写进操作日志。
台词转写、剧情理解、配套文案三块补齐。语音识别改走本地模型——不依赖任何外部接口也能跑通全链路,顺带绕开了「视频帧要不要外传」这个合规问题。至此四路信号全部参与打分。
人脸不做单帧判定,而是整条轨迹投票定身份——这是「侧脸、挡脸认不出」的解法。渲染出横竖两版,竖版裁切跟随主演位置。这一步撞上了本项目最典型的一次「测试全绿但东西是坏的」,见下一节。
转码、镜头分割、帧间差分、规则打分串起来,第一次真的从一集素材跑出候选时间码。同时把「断点续跑」从死代码变成真功能——那之前它只存在于注释里,而「改完权重秒级重算」正靠它。
确定本机加外部接口的最小验证路径,把工程拆成三个互相独立的子项目。工作台界面先行——包括一个当时看起来无关紧要、后来被证明是整套系统最重要的页面:标注基准。
一个候选项目因 AGPL 且触发条件含「通过网络提供服务」被排除——正好是本产品的形态。人脸识别的预训练权重标注非商用,列入产品化前必须解决的清单。
What actually broke
下面每一条都真实发生过,且都在单元测试全绿的情况下发生。把它们写出来比把功能列出来有用——功能表谁都能写,失败模式得付出代价才知道。
类型一
单元测试验的是「函数按约定返回了值」,验不了「这个值对不对」。两者之间的缝隙,只有把真实素材灌进去、再用眼睛或另一套模型去查结果,才会显出来。
类型二
最危险的一类。程序没有报错,报告是绿的,数字看起来也合理——只是它们是编出来的。
类型三
整套系统设计成「任一环节失败都降级继续」。但降级逻辑正确,不等于降级体验正确。
类型四
这类问题不会让任何测试变红,因为它不改变任何代码行为。它改变的是别人看到的东西。
一条贯穿的规律:这些问题没有一个是被单元测试发现的。它们分别是被人工验收、被另一套模型去查结果、被真实素材的耗时、被肉眼看页面发现的。
所以这个项目里测试代码比产品代码还多,但真正起作用的不只是数量——而是每加一层验证,就换一种角度去看同一个东西:函数返回值、成片里人脸的位置、日志里的降级标记、页面上的像素。
Still open
写出来比藏着有用——被问到时也能直接答。
| 事项 | 说明 |
|---|---|
| 质量基线 | 最要紧的一项。需要剪辑师标出一集的 Top-5 名场面作为对照。没有它,整套系统能给出分数,却无法回答「找得准不准」——而那正是这个需求要解决的第一个问题。界面已经就绪,是半小时的一次性投入。 |
| 语音识别准确率 | 目前测得的数字来自合成语音,干净、无背景音、无叠音。真实剧集音轨会显著更难,那是乐观上界而非预期值,必须用真实素材重测。 |
| 人脸权重授权 | 预训练权重标注非商用。内部验证不受影响,对外交付前须采购授权、换模型或自训。 |
| 说话人分离 | 权重需先在平台接受用户协议,当前版本明确跳过。 |
| 自演进 | 复核时留下的留用、弃用与原因已在逐条记录,但还没有回路把它们变成判定规则的改进。这是下一阶段的事。 |