Commit Graph
20 Commits
Author SHA1 Message Date
cat-shark eba9163246 feat: 优化学习视频转写与字幕清洗 2026-09-11 14:26:02 +08:00
cat-shark a8fe133aa4 feat: whisper 新增 decode_full 无VAD整段解码参数并改为整条删除式幻觉清洗
解决转写漏句(有人说话但没识别出来)问题:silero VAD 对呻吟/轻语/BGM
混叠声学切段能力天然不足,把真话当非语音剔除(实测 savr-1054 全片仅
召回 115 条)。新增 decode_full 参数(默认 false 保持 VAD 现状):

- decode_full=true 时强制无 VAD 整段解码 + 跳过自动 VAD 分析,救回被
  剔除的弱语音(savr-1054 全片 115 条 → 340 条)
- 副作用是长时寒暄套话幻觉(おやすみなさい/ご視聴ありがとうございま
  した 等),whisper 转录后连带时间戳整条删除(clean_japanese_ha
  lllucinations),不留下 '-' 占位污染下游(占位会渲染进 ASS 成减号)
- llm-translate 翻译后同样整条删除中文长时寒暄幻觉(clean_srt_text)
- 短时(≤15s)相同词可能是剧情真实道晚安,保留(15s 阈值实测校准)
- subtitle_cleanup 由 '-' 占位式改为整条删除式 + 剩余重编号,新增
  JAPANESE_HALLUCINATION_TOKENS 词表

新增工作流 learn-translate(学习资料转译+翻译字幕)示范 decode_full
用法,并确立参数标注约定:params._note_<参数名> 存放设定理由与正反例、
_node_help 放节点参数手册(_ 前缀说明键,节点执行时忽略,零运行影响)。

调研记录见 docs/调研-whisper漏句与decode_full验证.md(A/B 实验、结论
修正与 5 个待决问题)。
2026-09-07 17:21:04 +08:00
cat-shark 4d2a1912da feat: VR字幕默认MarginV改为700并统一历史字幕样式
- srt-to-dual-eye-ass: 默认顶部安全边距 margin_top 120→700(2026-09),
  120落在画面最顶需抬头看,700为实测合适值、视线自然可读
- nodes/ass.py: 样式定义抽为单一事实来源(DEFAULT_MARGIN_TOP/颜色常量
  +ass_header/style_row/dialogue_line),新生成字幕与历史统一脚本共用同一
  出口,以后调样式只改一处、两边永不漂移
- 新增scripts/unify_ass_style.py: 解析旧文件分辨率与全部Dialogue后经
  ass_header/dialogue_line重建,把媒体库历史样式(底部an2实心白1200/
  半透明1020/顶部120)原地统一为an8顶部对齐+70%透明+MarginV=700;
  默认dry-run预览,--apply写盘;非VR字幕自动跳过
- /mnt/fnOS/123 库401个.CN_dual_eye.ass已全部改写(0失败),269764条
  字幕事件无an2残留,二次运行幂等
- 测试: ass默认值断言120→700,新增invoke默认700用例;新增
  tests/test_unify_ass_style.py(历史三世代收敛/与write_ass逐字节一致/
  幂等/CLI dry-run与apply)
2026-09-06 18:02:31 +08:00
cat-shark fbcb5115d8 feat: llm 翻译节点打印分批进度与 token 处理速度日志
翻译节点 translate_lines 分批调用 LLM 时补充可观测日志:
- 任务开始打印总行数与总批数;每完成一批打印总进度(已完成/总行数、
  第几批/共几批、批耗时、累计耗时与行/s),结束打印汇总(总耗时、
  累计 tokens、tok/s 与行/s),便于评估 LLM 处理速度;
- _call_llm 解析响应 usage(total_tokens),每次请求打印单批耗时与
  token/s(接口不返回 usage 时按 0 处理);
- _translate_batch 改为返回(译文, 本批 tokens),供累计汇总;
- 补充空输入直接返回的单测,保持 100% 行覆盖率。
2026-09-06 13:57:44 +08:00
cat-shark f2895ee103 feat: 字幕领域纠错模块(通用领域词表 + 有效上下文,不过拟合)
背景:成人视频 ASR 常把性器官(チンポ/マンコ)听错成近音词(手先/
チェーンバー 等),翻译逐字直译导致与画面严重不符。

实验结论:
- 硬编码 ASR 误听例子(手先→肉棒)过拟合——换视频的误听词就失效;
- 通用领域词表(只列性器官的常见日文词+中文)+ 有效上下文 + 通用引导
  可泛化——对从没见过的误听(バナナ/マンゴー→性器官)也能按语境推断。

实现 nodes/subtitle_correction.py:
- PROPER_SESSION_WORDS:通用性器官领域词表(不含 ASR 误听噪声词)
- _is_fragment:纯语气词/碎片过滤
- _build_context:目标 ±60s 有效上下文(过滤碎片,保留动作链)
- _system_prompt:通用引导(无具体误听例子)
- _extract_target_line:从 LLM 输出解析目标行译文
- invoke:逐条领域纠错,产出 corrected.srt

测试 tests/test_subtitle_correction.py(12 个):
- 碎片判定/上下文过滤/目标解析/提示词无噪声例子(9 快速单测)
- 真实 LLM 泛化回归(对未出现误听词也能推断性器官)+ 端到端 invoke
2026-09-06 10:44:09 +08:00
cat-shark 2c3c356348 feat: whisper 节点自动接入自适应 VAD + 方案文档
- nodes/whisper.py:invoke 检测到 vad_filter=true 且未显式传 vad_parameters
  且 WOV_AUTO_VAD=1 时,自动调用 vad_profiler.vad_parameters_for_audio 按
  本音频信号动态确定 VAD 参数并传给 transcribe;分析失败回退默认不中断转写
  (防御性,不影响整段流程)。
- tests/test_nodes.py:新增自动 VAD 异常回退测试(patch profiler 抛错,
  验证 whisper 正常转写 + transcribe 收到 vad_parameters=None)。
- docs/adaptive_vad.md:完整方案文档(背景/可行性/三层架构/参数建议规则/
  评分器/实现落点/取舍/实现状态)。
2026-09-06 08:15:13 +08:00
cat-shark d0d96a8f89 feat: 每视频自适应 VAD 调参模块(信号分析 + 幻觉词扣分评分)
背景:实测 CJOD-255 全程 BGM 覆盖(56% 低能量、几乎无静音),固定 VAD
参数把音乐当语音 → whisper 全段解码 → 80% 碎片化 + 32% 漏句 + 敏感段丢失。

实现 nodes/vad_profiler.py:
- profile_audio:1s 能量网格分析 → 静音比例/BGM 覆盖/长停顿识别
- suggest_vad_parameters:按信号特征推荐 threshold/min_silence/speech_pad
  (BGM 覆盖 -> 降 threshold 增人声敏感;长停顿 -> 降 speech_pad 防时间漂移;
   静音占比高 -> 升 threshold 剔虚警)
- score_transcript:启发式评分(不用参考字幕,符合部署实际)——
  碎片率 + 幻觉词(感谢观看/晚安/音乐)扣分 + 平均字数适中
- vad_parameters_for_audio:信号分析 + 可选片段网格验证,选最优参数
- _grid_search_vad / _candidate_params:候选网格搜索与异常回退

测试 tests/test_vad_profiler.py:19 个用例覆盖信号分析、四个建议分支、
幻觉词/碎片评分、网格选优、异常回退、空音频/低采样率、候选展开。
2026-09-06 08:14:59 +08:00
cat-shark a032855210 feat: 字幕质量提升——长时寒暄幻觉清洗 + 专名/成人隐语不直译
两部分同属字幕质量优化,共用 llm.py 翻译链路:

1) 长时寒暄幻觉词清洗(nodes/subtitle_cleanup.py)
   对展示时长超过阈值(默认 15s,实测 30s 幻觉占位 vs 2s 真实词的分界)
   且文本含收尾/开场寒暄(晚安、感谢观看等)的字幕,文本替换为 '-',
   由后续过滤流程移除;短时寒暄(如剧情中真实互道晚安)保留不误删。
    写文件前调用 。

2) 专名/隐语不直译(nodes/proper_nouns.py)
   片假名专名(人名/品牌/角色)与成人语境隐语是 LLM 误译重灾区:
   - ジンゴ 被误译成'芒果'、カンタくん 被保留日文而非音译;
   - マンゴー/バナナ/リンゴ/金玉/おまんこ/ちんちん 等在色情语境中
     是生殖器官代称,字面直译严重错译。
   整理三张规则表(专名/拟声词/成人隐语,用户提供隐语表),
    检测原文命中后动态注入翻译提示词,
   让 LLM 按正确语义处理。文档见 docs/proper_nouns.md。

测试(红→绿):
- tests/test_hallucination_mask.py:长时掩码/短时保留/非寒暄保留/阈值边界
- tests/test_proper_nouns.py:专名命中/拟声词/成人隐语/真实数据集成
- 真实 LLM 集成测试(完整 1440 行翻译 + 清洗 + 专名注入)通过
2026-09-05 22:32:40 +08:00
cat-shark 2e8bbb15a4 feat: ASS字幕移到顶部安全区并加透明度(零视差不变)
- srt-to-dual-eye-ass: an2底部→an8顶部对齐,MarginV改为可配margin_top(默认120),
  字幕避开画面中央人脸高发区(B-1顶部安全区)
- 文字填充&H80FFFFFF→&HB3FFFFFF(约70%透明),描边纯黑→&H80000000半透明黑
- A-1零视差保持不变:左右眼水平相对位置一致,字幕固定屏幕平面
- 新增3条测试(顶部对齐/自定义margin_top/invoke读参数),ass节点覆盖率100%
- 新增docs/调查报告:双目视觉景深原理、字幕深度配置公式与遮挡解决方案
2026-09-05 21:03:55 +08:00
cat-shark 5c12bbcb74 fix: 翻译批内行数错位(内容-时间错位)+ system_prompt 元组 bug
根因(真实任务 run_51242078d76e):
1. LLM 按 CHUNK_SIZE=20 分批翻译时,对语义碎片句(如单独的助词/名词/
   语气词)偶发多拆/少拆一行,translate_lines 无条件 extend 导致:
   - 多行 -> 后续所有字幕文本整体错位,时间戳从原文复制、文本却错贴时间;
   - 少行 -> invoke 末尾补空导致该条内容缺失。
   程序按时戳看不出问题,实际"内容对错时间"(如第756条"好像喜欢害羞
   的样子"错贴 3805s,实为"恥ずかしいのが好きみたいなので"的译文)。
2. system_prompt 圆括号内出现 f-string 赋值导致隐式字符串拼接失效,
   整体变成 tuple,json 序列化后 content 是数组 -> LLM API 400。

修复:
- 提示词强化:逐行独立翻译 + 碎片句按语境独立成行 + 禁止合并/拆分;
- _repair_batch:多行末尾合并到前一行、少行重试该批(最多3次)仍不足
  补空串占位(宁缺勿错位),保证译文与原文逐条时间对齐;
- system_prompt 显式 + 拼接为单个字符串。

测试(先红后绿):
- test_translate_lines_aligns_extra_line:多行合并对齐
- test_translate_lines_aligns_missing_line:少行重试补齐
- test_translate_lines_pads_after_retries_exhausted:重试耗尽补空
- test_pipeline_zh_cn_timetext_alignment:真实 LLM 完整 1440 行逐条对齐
pyproject.toml: 注册 integration marker
2026-09-05 19:36:47 +08:00
cat-shark 39f309094d fix: ASS 双眼字幕样式修正
- 右眼 MarginR 误用 width-50 改为 50(左右眼对称内边距)
- 字幕颜色改为半透明白(&H80FFFFFF),避免遮挡 VR 画面
2026-08-23 16:25:20 +08:00
cat-shark 87abde33d4 feat: subtitle-ocr 进度日志增加预计剩余时间 ETA
- 进度日志追加"预计剩余 X分Y秒"(剩余帧/当前速度,速度未知时不显示)
2026-08-23 16:25:18 +08:00
cat-shark 5688f38d62 fix: frame-extract 默认裁切区域改为画面底部 1/4
- 默认 crop 由 [0,0.82,1,0.18] 调整为 [0,0.75,1,0.25]:字幕很少出现在
  画面上半部分,扩大裁切高度提升 OCR 召回
- 同步更新 ocr-subtitle 工作流 DAG 与参数覆盖测试
2026-08-23 16:25:17 +08:00
cat-shark 3aa05bbf76 feat: whisper 分块间暂停检查与默认 float16 计算类型
- 分块转写在每个分块前检查 run 根目录 paused.flag,批量/任务暂停时
  分块粒度内中止(默认 60s 一块),当前块执行完才停
- 默认 compute_type 由 auto 改为 float16,测试断言同步更新
2026-08-23 16:25:15 +08:00
cat-shark 3b5bd42b60 feat: llm-filter 节点级断点存档
- 每条 LLM 判定成功立即追加 filter_partial.jsonl(多线程加锁串行化)
- 失败/中断后重跑只重判未判定条目,已判定结果复用,与 OCR 存档同机制
- 附带上下文净化回归重跑脚本(run_011d01f19999)
2026-08-23 16:25:13 +08:00
cat-shark b16e0e9f3c feat: 任务断点续跑/暂停中断/LLM 过滤优化与调度容错
调度与状态机:
- 修复 PAUSED 任务被拾起后复活执行(点击暂停反而开始任务):next_queued_run
  只取 QUEUED,execute_run 以 PAUSED 进入直接返回,暂停必须显式 resume
- 重启恢复:启动时 recover_interrupted_runs 把遗留 RUNNING 置 QUEUED(保留产物)
- 暂停信号 paused.flag:暂停接口写、继续/重试清除,OCR 逐帧检查秒级中断,
  节点内被暂停保持 PAUSED 不误报 FAILED
- 调度轮询容错:_loop 异常不杀死线程(曾致任务永久停留 QUEUED)

subtitle-ocr 节点级断点:
- ocr_partial.jsonl 逐帧存档,重启/暂停后只处理未处理帧,产物与一次跑完一致
- 进度日志携带窗口平均耗时与线程数;取消后抑制进度日志井喷

llm-filter 过滤质量与限流自适应:
- 上下文净化:喂给 LLM 的是过滤后的字幕(规则层垃圾从上下文剔除)
- 正则确定性过滤:裸网址域名、HTML/水印模式直接删除
- 429/5xx 指数退避重试;worker 限流错误 report_failure 内存临时降最大线程数
  并缩容(无错误窗口回升),失败条目降并发后重试一轮
- 保留长文本保护(noise 不删 ≥min_keep_len 文本,LLM 判定不稳的必要兜底)

前端:
- 工作流编排页支持选择工作流编辑(加载最新/历史版本)、版本历史面板、
  新建/编辑双模式;管理后台编辑跳转 workflow.html?edit=<id>

工作流:ocr-subtitle v7(filter pool_max_workers=20、pool_fast_threshold=1)
2026-08-19 01:27:41 +08:00
cat-shark 5ffa2ac39e feat: llm-filter 两级过滤(规则层+五类分类+去重+长文本保护),工作流单线程 v4
- 规则层(不调 LLM):横线装饰/HTML 水印 token/URL/邮箱/单双 ASCII 字符直接删
- LLM 五类分类:garbage/overlay/noise 删,repeat/dialogue 留,未识别回退保留
- 按文本去重:相同文本只调一次 LLM(忽略空白/大小写),判定一致并省调用
- 长文本保护:≥min_keep_len 时 noise 不构成删除依据
- 真实任务 run_ac7f480a3ccb 验证:非规则误删 350→193(-45%),呻吟/对话保留
- ocr-subtitle 工作流 v4:pool 钉死单线程(1/1)
- 回归夹具 testdata/ocr_srt_run_ac7f480a3ccb.srt(真实 1666 条 OCR 输出)
2026-08-17 23:20:16 +08:00
cat-shark 2b3a650612 fix: 帧文件按帧号数值排序,修复超 9999 帧字典序错位
- frame-extract 新增 _sorted_frame_files:ffmpeg %04d 编号超过 9999 帧后扩为
  5 位,sorted() 字典序会把 5 位编号排在 4 位之前,导致 frames.json 时间与
  图像错位(真实发生于 run_339ec7ee437f 的 14236 帧任务)
- subtitle-ocr 提取 _merge_kept 供重组装复用
- 回归测试用真实任务留存数据(testdata/frames_boundary/),并新增真实 OCR
  数据按正确时间轴重组装为 SRT 的集成测试(test_integration_reassemble_ocr)
2026-08-17 23:20:11 +08:00
cat-shark 885cf07921 feat(extract): 抽帧打印进度日志
ffmpeg 增加 -progress pipe:1 并解析 frame=N:每约 10 个检查点打印
'抽帧进度 X/Y 帧 (Z 帧/s)',长视频抽帧期间可见实时进度与处理速度。
测试覆盖进度行解析、进度日志输出与失败路径(Popen mock)。
2026-08-17 00:03:51 +08:00
cat-shark 4746e0363f feat: VRSub 单体应用(WOV 单机版)初始提交
为视频生成 VR 双眼字幕的单体实现:FastAPI 后端、调度器与全部节点
(提音/转写/翻译/ASS/抽帧/OCR/LLM 过滤)在单进程内运行。

- 节点协议(wov_sdk 数据模型)与分布式版保持一致,预留回退桥梁
- 工作流即数据:DAG 存于 workflows/*.json,模型/链路改动只改数据
- 调度器:拓扑顺序执行、断点续跑(产物重建)、任务暂停/继续
- 抽帧按帧间隔(select 按帧号精确取帧),VLM OCR 与 LLM 过滤使用
  自适应线程池弹性并发,并打印数据处理速度进度日志
- 100% 行覆盖率(pytest --cov-fail-under=100)
2026-08-16 23:58:25 +08:00