《高性价比人生指南》知识视频产线 E01 结案 —— 踩坑全录(2026-10-14)
从 0 搭建"读书解说日更视频产线"(开源书 HowToLiveBetter → 每天自动写稿/配音/渲染/定时发B站),到 E01 人工验收放行(BV17Upm6sE6R,10-15 11:30 上线)。全天烧掉约 10 轮重产,其中 8 成时间在处理"机器全绿但人听着不像人话"的问题。按发现顺序记录,每条含:现象 → 根因 → 修法 → 泛化教训。
一、写稿层(LLM 文案)
1. 提示词里的"N字"是建议,不是合同
- 现象:要求每段 60-120 字,实发全片仅 348 汉字 ≈ 79 秒成片,违反"每集≥3分钟"红线;且每段单看都"没超纲"。
- 根因:LLM 对总字数没有自感知,分段约束拦不住总量偷工。
- 修法:脚本层机械校验。计数口径必须用汉字数
re.findall(r"[\u4e00-\u9fff]", t)——用 len() 会把标点和英文算进去,把贴线合格稿误杀。 - 泛化:凡是"数量红线",落到代码断言,不落到提示词。
2. 初稿校验卡"全片字数下限" = 死循环坑
- 现象:重试 4 次全同法失败,初稿永远进不到补写环节。
- 根因:本地模型初稿天然偏短(实测三轮 528/544/546 汉字),assert 总下限=560 后每轮都整体作废重写,重写也是同分布偏短。
- 修法:初稿只做结构校验(每段有内容、不超长);字数缺口全部交给"逐场景素材驱动补写"(topup 循环喂原始书稿续写,直到分段下限+全片总量达标)。
- 泛化:生成式流水线分层校验——结构层宽容、数量层用确定性补写收敛,不要用"整体重掷骰子"修数量问题。
3. 闸门重试 ≠ 从头重跑
- 修法:LLM 解析成功先落草稿盘(script_draft.json),下一轮把"草稿+缺陷清单(哪段差几字、QC 命中哪句)“喂回去只定向改问题段,事实句式不动。从头重跑大概率以相同方式再次偷工。
4. 书面缩略词:闸门要确定性替换,别交 LLM 改写
- 现象:用户抓到台词"系带?"(应为"系安全带”)——模型照抄书稿的书面缩略。“过 qc_tone 闸门”≠“没有 AI 味”,闸门只覆盖已知统计特征,不覆盖"听众歧义词"。
- 踩坑升级:先试 LLM 句级改写,口播风险 6 处连修 4 轮残留不动,空转烧光重试次数。
- 修法:
apply_spoken_fix()确定性 regex(系带→系安全带、戴盔→戴头盔、土法→土办法、娃→小孩…),每轮 QC 前代码级跑;LLM 只留给需要语义判断的句式问题。 - 替换规则两个坑:
- 负向断言要覆盖后缀词:
没系(?!安全带|紧)——漏了"紧",把"扣带没系紧"改成"扣带没系安全带紧"病句,直接进了成片音频才发现。 - 上线前拿 case 表(含误伤反例)回归测替换函数,别只看目标词消失。
- 负向断言要覆盖后缀词:
5. 黑话/栏目词闸门(“落地:花几十块买个报警器"案)
- 现象:旁白出现"落地:花几十块…",用户:“不像说话表达出来的,像书写的文案”。
- 根因有两层:a) 模型爱把 PPT 栏目词当句首引导词;b) 我自己写的节拍模板里就管那一拍叫"怎么落地”——提示词自己种下了禁用词。
- 修法:提示词点名禁用清单(落地/抓手/赋能/闭环/复盘/底层逻辑/先看一组数据)+ 正则闸 + 确定性替换(“落地:"→“说白了:");模板措辞同步改成"行动建议"并显式写"这拍不叫落地”。论文统计腔(OR/95%CI/置信区间)同禁:旁白说"最保守也降三分之一”,精确值放画面卡。
- 泛化:先查自己的提示词有没有污染源,再怪模型。
6. 补写环节的复读副作用
- 现象:成片 s03/s04/s05 尾段把本段开头的数字原样再念一遍凑总结。
- 修法:topup 带去重闸。算法实测校准:4-gram 重合率会误杀"复用同段实体词的合法句"且对换措辞复读漏检;可用方案=16 字滑窗字符 bag:窗内 ≥8 个曾出现字符 → 判复读丢弃(真复读对重合 0.12~0.25、真新句 0.0,两类全分对)。
- 泛化:阈值别拍脑袋,拿成片真实复读对+合法句各 2~3 条做回归再定。
7. 收尾句位置铁律
- 现象:用户发现"关注我…“被夹在全片总结中间、下集预告后面还吊着蘑菇数字。
- 根因:节拍模板把"关注引导+观点”、“预告+数字"塞同一拍,模型习惯先写钩子再补数字。
- 修法:提示词显式规定"预告/关注句永远压轴,补充信息排它前面”;存量稿定点改写 script.json + 按场景重配音(指纹缓存保证只重合成受影响场景)。
二、配音层(TTS)
8. 阿拉伯数字禁裸喂 TTS
- 现象:用户:“248099 是按数字读出来的,不正确”——被逐位念成"二四八零九九"。
- 修法:写 tts_norm.py 文本前端,送合成前做书面→口语转换(
45%→百分之四十五、17.4→十七点四、年份逐位2021年→二零二一年、2165→两千一百六十五、量词前独立"二"→“两”),屏幕字幕/画卡保留阿拉伯原文——视觉不变、只改听觉。 - 工程纪律:段缓存 key 必须带"归整后文本 hash + 规则版本号",规则升级自动失效旧音频;归整函数拿风险句全集做回归 case。
9. 句间静音必须真插进音频(字幕"越往后越晚几秒"案)
- 根因:时间轴按"句长+0.45s 停顿"累计,但 wav concat 只贴语音段不加静音 → 音轨逐句前移,累计到片尾漂好几秒,表现为字幕滞后。
- 修法:生成 0.45s anullsrc 静音 wav,concat list 里句间交替插入。
- 泛化(本条最值钱):时间轴用哪种累计口径,媒体轨道就必须按同口径物理构造。程序 QC 只查时长/音轨/亮度,永远抓不到这个。
- 无 ASR 的成片验收两招(本机实测可用):
- 漂移核对:对成片跑
ffmpeg -af silencedetect=n=-40dB:d=0.35,每5 句取"字幕结束点 vs 其后第一个实测 silence_start"看偏移有无累积趋势——单点 +14s 是逗号/句末自然长停顿落在采样窗内,只有单调递增才是拼接漏静音。 - 数字读法核对:字/秒时长法。23 汉字句 8.3s(≈0.36s/字),逐位念 6 位数字必装不下——时长数学即可排除逐位读,不必人耳/ASR。
- 漂移核对:对成片跑
10. 重跑脚本必须自带服务拉起
- 现象:绕过 pipeline 的 rebuild 脚本直接调 TTS,吃
ConnectionRefused。 - 根因:产线 TTS"用完即停"纪律(omnivoice 服务合成完就 stop 释放 GPU)。
- 修法:rebuild_tts.sh 自带 拉起 systemd 单元+health 轮询+EXIT trap 停服收尾;双卡被 flashnext 占时先走 GPU 仲裁桥接腾卡、完事 restore 归位;全程 tee 到 ~/桌面/pipeline.log。
三、画面层
11. 字段语义绑错只能靠 VLM 抽帧抓
- 现象:s02 画面写"全书 48 条",封面/片尾却写 528。48=本节条目数,被错绑进"全书"位。数字本身"真"、代码层 QC 全绿,错在字段语义≠文案措辞。
- 修法:画面文案含"全书/总计/共X"类全局量,装配模板绑全局常量,勿绑局部量;VLM 抽帧把"跨帧数字一致性"列为显式检查项。
12. CJK 断词防线
- 现象:“研/究"“电/池"被拆行(Chrome 对中文
text-wrap:pretty保护有限,加了仍拆)。 - 修法:卡片类固定文案在模板里手动
<br>定断点;旁白动态文本只能靠 pretty 降概率,抽帧 QC 必查孤字断行。
13. 返工勿重跑全链
- 产线无 –step 时:只改 CSS/模板 → rebuild_only.sh(复用已验收的 script/beats/narration,≈3min 出片);改配音 → rebuild_tts.sh。全链重产 ≈12min 且写稿是随机的,好稿会被冲掉。
- 复位重产时三件套必须齐:
rm -rf <epdir> queue.json+ state.json 归零;漏一个=指针已推进,产的是下一集。
四、QC 与验收
14. “exit 0"不等于"成功”
- 后台 bash 包装进程报"completed normally”,内层 pipeline 实际
RC=1;“bash: 无法设定终端进程组"是后台 shell 噪音。判定一律看 RC= 和产物。
15. 机器全绿 ≠ 人验收通过
- 今天 4 个用户人工抓出来的问题(系带/248099/字幕漂/落地),全部发生在 qc_tone+时长+音轨+亮度检查全绿之后。人耳/人眼能发现的统计闸门抓不到的缺陷至少有三类:听众歧义词、TTS 读法、音画口径分叉。所以交付格式固定为:机器结论逐条附实测口径 + 明确 1~2 个人工试听点位(数字密集句起点、收尾句起点)+ 局域网直链。
16. 验收刹车与发布纪律
- 首版必挂 HOLD(产完入队不投稿),人工放行=备份 queue.json → 撤 HOLD → 单独调 publish()(勿重跑 main,防再产一集)。
- B站排期核验:member archives 接口(浏览器 UA + cookies.json 里
cookie_info.cookies拼 Cookie 头——顶层是 dict,直接遍历=未登录 -101);state=-30 审核中+ dtime 正确即坐实。 - 定时位:每天 11:30 上线(10-14 用户定),22:05 产片提交,间隔 13h+ 满足 dtime>4h 硬约束。
17. 结案后新发现:修复词本身要过闸门
- 为修"落地”,替换规则把"落地:"→“说白了:"——结案后复跑 qc_tone 才发现"说白了"正是规则9的 AI 起首语标记(R=3.2,283万字语料对照)。E01 稿件带着这处命中发布了(该条属软性风格项,人工判定"说白了"恰是用户偏好的口播腔,不返工;但产线替换映射已修正为"干脆/其实"类)。
- 泛化:任何"修复用"的确定性替换,替换后的成品必须回炉全量闸门(含它本要满足的那些闸),否则修一个坑埋一个坑。
五、B站发布速记(本次实测)
- biliup 必须
cd ~/.biliup跑(cookie 按目录找);--tag只能传一次多标签逗号合并;bvid 判读正则兼容 Rust Debug 格式"bvid":\s*(?:String\()?"(BV[\w]+)"。 - 标题必含完整系列名(用户点名),封面/简介/标签四处口径一致。
- E01:BV17Upm6sE6R,《2秒花零钱保命?《高性价比人生指南》揭秘24.8万人的生死账》,10-15 11:30 定时上线。
沉淀去向
- 产线代码:/mnt/nvme1/kf-video/hltb/(book_extract → gen_script → script2_tts → step4 → render → queue → publish,cron 22:05 产 + @reboot 补跑)
- 技能卡:bili-series-autopublish(产发一体+全部铁教训)、hyperframes-kf-pipeline(口语化四闸)、knowledge-video-visuals(音画同步律+验收方法)