# 待办:翻译上下文复用与语义纠错 本文件记录**尚未解决**的问题与用户给出的需求规格,供后续对话接着做。 已完成的改动见 git 历史(分支 `master` 上的 `fix/review-improvements` 合并结果)。 --- ## ⛔ 方案状态:已技术评审,**不实施** 「一、需求规格」与「五、落地这个需求时需要先想清楚的点」所描述的**会话式长上下文 方案经技术评审否决,后续不要再按本方案修改代码**。结论与依据见 [decisions.md](./decisions.md#翻译会话式长上下文方案否决): 1. **前提不成立**:需求 5 假设"长上下文能让模型发现并改掉语义错",但本文件自己 记录的两次实验(纠错节点 ±60s 上下文、加强提示词 A/B)全部失败。错因是 ASR 听岔、语境里没有声学证据——加长上下文只是增加同类证据,不能修掉问题 A。 2. **成本放大 3×~70×**:会话式每批原样重发全部历史(随批数二次增长),该档 Qwen 在 SiliconFlow 无 cached-input 折扣(价格表缓存列为 `-`);按实测口径推算, 剩余 187 小时素材的 API 费用从 ¥5.5–9.4 涨到约 ¥300–400。 3. **压缩阈值踩计费档**:`>150k 触发` 跨过 `[128k,+∞)` 档(输入 ¥0.4→¥1.6、 输出 ¥3.2→¥12.8,整请求按 4× 计价),阈值应低于 128k。 4. **与现有不变式/机制冲突**:文件夹级可变共享状态(节点只经产物 URI 交换、每 run 独立产物目录)、批量非 GPU 阶段并行(共享会话要求按文件夹串行)、"暂停后 整节点重跑、不留半成品"的暂停语义,都要新增子系统并改动语义。 本文件**保留为需求与问题记录**(问题 A/B/C、需要知道的坑、数据现状仍然有效)。 问题 A 的可行方向(ASR 侧低置信度 + 文件夹级热词二次解码等)**尚未评审、未决定**, 需要修时另行提出方案与代价。 --- ## 一、需求规格(用户 2026-09-19 明确) 1. **翻译阶段要复用对话**:不再每批(20 条)都是无状态独立请求,而是把同一视频的 多批放进同一个会话上下文里,让模型能看到前面译过的内容。 2. **文件夹级共享上下文**:同一文件夹下的多个视频(同番号多集)共用一个上下文, 让各集之间复用信息(人名、称呼、场景设定等)。 3. **术语稳定**:因为共用上下文,整片/整文件夹的人名、专名、称呼能固定下来, 不因批次不同而漂移。 4. **上下文压缩规则**(小模型上下文有限): - 上下文占用 **超过 150k** 时触发压缩; - 压缩对象主要是**前 100k**:调用 LLM 对前 100k 做总结,**重点保留名字、场景**等信息; - **后 50k 原样保留**,避免丢失"与当前高度相关"的近期信息。 5. 预期收益:模型在长上下文里更容易发现"语义不顺/与前后矛盾"的句子,从而修掉 下面的问题 3(ASR 听岔成"成句但语义错")。 --- ## 二、现状(代码事实,2026-09-19 核对) | 事实 | 位置 | | --- | --- | | 翻译按 `CHUNK_SIZE=20` 分块,**每块一次独立请求**:请求体只有 `system` + `user` 两条消息,无历史、无跨批信息 | `nodes/llm.py::translate_lines` / `_translate_batch` / `_call_llm` | | 动态提示词**按批计算**:本批正文命中词表才追加规则;同一视频其它批次命中的词不会带过来 | `nodes/llm.py::_translate_batch` + `nodes/proper_nouns.py::build_proper_noun_rule` | | 一批的"上下文"只有本批 20 条(约 1–2 分钟对话) | 同上 | | 译文**整批返回并入库**(不是只取目标句):`_parse_translations` 要求返回的 id 集合与请求完全一致,缺项/多项/重复/空文本都判失败并重试 3 次 | `nodes/llm.py` | | 纠错节点是**逐条调用**、输出中文译文(不是改日语),未接入任何工作流 | `nodes/subtitle_correction.py`(`workflows/*.json` 中无引用) | --- ## 三、问题清单 ### 已解决(供参考,不必再动) | # | 问题 | 处理 | 证据 | | --- | --- | --- | --- | | 1 | whisper 重复伪影(30 秒被同一单元填满;短时 3.7 秒填 111 个假名) | 清洗规则删除(长条 ≥15s 且重复 ≥6 次;或重复 ≥20 次) | `nodes/subtitle_cleanup.py::remove_repetition_entries` | | 2 | 静音段幻觉(`こんにちは`/`おはようございます`/`東京都交通局8800形電車`…) | 开启 `hallucination_silence_threshold=2.0` + `word_timestamps`(工作流 v3);片头 120 秒由 15 条降到 4 条 | 见 `data/experiments/regen_plan/REPORT.md` 第九节 | | 3 | 批量任务被误标 COMPLETED(明细写入竞态) | 任务先以 `CREATING` 入库,明细写完才置 QUEUED;启动清理遗留 | `src/wov_app/batch.py::create_job` | | 4 | 历史产物损坏:CN 里出现"无正文的 cue",下一条的序号+时间轴被吸进正文(ASS 同源损坏,播放器加载失败) | 全库 112 个:85 个旧字幕随重跑修好;27 个新字幕 + 1 个命名特例已单独重做 | 见本文件"四、数据现状" | ### 未解决(本次对话的核心遗留) **问题 A:ASR 把词听岔成"语法通顺但语义错"的句子,中文照字面直译** 实例(`kiwvr-886/masex.tv@kiwvr00886_2_8k.mp4`,00:15:45–00:16:20): | 产品里的 JA(错) | 复核后的 JA(两个模型一致) | 现译(错) | 实际含义 | | --- | --- | --- | --- | | `じゃあ、ママの声をおなかに入れますね` | `じゃあ、まままんこにおなほに入れますね` | 那我让妈妈的声音进入你肚子里了哦 | 那妈妈用小穴(把它)套进去哦 | | `写真してもこんなにカチカチなんですね` | `射精してもこんなにカチカチなんですね` | 也会变得这么僵硬呢 | 就算射了也还是这么硬呢 | | `あくまで、あくまでください` | `奥まで、奥までください` | 再吃一个,再吃一个吧 | 再深一点,再深一点 | | `あくまで入ってしまいました` | `奥まで入ってしまいました` | 它已经全都进来了 | 已经顶到最里面了 | | `生鼻を使わさせていただきますね` / `口紋かでもご奉仕` / `生おなほ` / `おなほまんこで` | 均为 オナホ/マンコ 一类词的走音 | — | — | 已实测**失败**的修法(不要再重复试): | 尝试 | 结果 | | --- | --- | | 纠错节点(`Qwen/Qwen3.6-35B-A3B` 与 `Qwen/Qwen3.5-35B-A3B`,±60s 上下文) | 均输出"那我把妈妈的声音放进肚子里哦"——**没改对** | | 加强提示词 A:"语义不合常理/与动作链矛盾即判为误听" | 仍保留"声音" | | 加强提示词 B:"上下文反复出现 オナホ/マンコ/チンポ;同位置的怪词应改写" | 仍保留"声音"(只把"身体/肚子"换了个说法) | | 审校节点:LLM 定位问题 cue + 定向修复(输入日文原文 + 现有译文 + ±2 邻句 + 系列词表) | 定位召回 0/3(仅中文)~ 1/3(加日文);修复依次输出"声音传送到身体里""继续吃""已经完全进去了",**仍全部保留错译**,另有脑补改坏 | 上述失败实验的完整数据(定位触发率/合成正样本召回/逐条修复前后对照)与 原因分析见 [实验数据-字幕审校定位与修复实验.md](./实验数据-字幕审校定位与修复实验.md)。 **问题 B:翻译无跨批/跨视频上下文**(对应上面"需求规格"要解决的对象)。 直接后果:一批里同时出现多处坏转写时(`写真しても`、`あくまで`×2),模型既无整片 术语线索、也看不到前后动作链,只能按字面翻译。 **问题 C:`_call_llm` 不重试网络错误**。实测云端 API 偶发"挂住 600 秒读超时" (2/634 批,两批集中在同一分钟),直接把整段翻译判失败、视频白跑一遍。 用户明确选择**暂不修**,留待后续决策;全量 349 个约 5000 次调用,按此失败率会有 10–20 个视频需要重跑(重跑方式:建库级任务,缺字幕的视频会自动判 PENDING)。 ### 需要知道的坑 - **任务行的 `updated_at` 会被读操作刷新**:`GET /api/batch/jobs*` 会触发 `sync_batch_job_progress` 重算并写回时间戳,统计耗时请用日志的"批量任务 … 完成"行 或明细的 `updated_at`,不要用任务行。 - **产物损坏的根因**:某一步"只删正文行、留下空 cue",后续解析器把下一条的 序号+时间轴当成正文吸走。产出端(当前 pipeline)已验证不会再产生:`serialize_srt` 对空正文会写空行,`clean_srt_text` 也能正确处理空文本 cue。 - **`savr-1054/…_1_8k` 的产物名曾带 `666` 后缀**(`…_1_8k666.CN.srt`),批量引擎按 "文件名含视频主名"仍能匹配,但严格按 `<视频名>.CN.srt` 匹配的脚本/播放器会漏掉。 --- ## 四、数据现状(2026-09-19) - 媒体库:`/mnt/fnOS/123`(NAS `192.168.123.199:/vol1/1000/123`),524 个视频 / 287.27 小时。 - 待重生成(CN 字幕早于 2026-09-01):**349 个 / 187.86 小时 / 1417.8 GiB**。 - 已按新管线重做:20 个样本 + NKKVR-175 两个 + 28 个损坏修复 = 50 个视频。 - 每个视频现有产物:`<视频名>.JA.srt`(ASR 后的日语转写)、`<视频名>.CN.srt`、 `<视频名>.CN_dual_eye.ass`;旧字幕备份为 `*.old-20260918` / `*.corrupt-20260918`。 --- ## 五、落地这个需求时需要先想清楚的点(新对话用;**本节方案已否决,不再作为实施依据**) 1. **会话形态**:把 `messages` 从"system+user"扩成多轮,是把**上一批的 JSON 原文与译文** 作为 assistant/user 消息追加,还是只追加"术语表 + 摘要"?前者上下文增长快(每批 ~800 tokens),后者省但信息有损。 2. **对齐与重试**:现有实现靠"每批独立、id 对齐、失败重试 3 次"保证不错位;改成会话后 某批失败/重试会污染会话历史,需要明确回滚策略(例如失败批不写入历史)。 3. **压缩触发与实现**:`>150k` 触发、总结前 100k、保留后 50k。要确定 token 口径 (用接口返回的 usage 还是本地估算)、总结用哪个模型(同模型/更便宜的模型)、 总结产物如何缓存复用(同一文件夹复用意味着总结要能跨视频复用)。 4. **文件夹级共享**:按文件夹串行处理是前提(当前批量引擎是分组的,同组视频可能并行), 否则两个视频同时读写同一会话会互相污染;还要定义文件夹内视频的处理顺序。 5. **暂停/断点续跑**:run 恢复时上下文是否重建?重建口径(从已有 CN.srt 复原历史?)。 6. **成本与限额**:长上下文会显著抬高输入 token(每批都带上历史),要重算 `docs/实验数据-字幕重生成成本与耗时.md` 里的单价;注意不少接口对超长输入有倍率价。 7. **与现有清洗/词表的关系**:`subtitle_cleanup`(重复伪影/寒暄幻觉/短呻吟)与 `proper_nouns`(词表规则)仍然保留,会话上下文是补充而非替代。 8. **验收用例**:至少覆盖本次的 `kiwvr-886_2` 00:15:45–00:16:20 那段——目标句应译成 "那妈妈用小穴(把它)套进去哦"这类含义,而不是"声音进入肚子";同时不能把正常句 改坏(例如呻吟/短句不应被"脑补"成新意思)。 ## 六、问题 A 的阶段性结论:暂缓(模型能力不足) 已实测过两条路子,均不能解决问题 A: 1. **翻译侧审校**(LLM 定位问题 cue + 定期修复:输入日文原文 + 译文 + ±2 邻句 + 系列词表)。实测:定位召回 0/3(只给中文)~ 1/3(加上日文);修复后仍保留错译, 且出现无依据脑补改坏正常句。**有效的只有术语/忠实性类**(如 `阴道`→`小穴`)。 2. **硬规则定位**(词表违背 + 近音匹配):严格口径目标召回 0/3,宽松口径命中率 48.6% 全是假阳性——硬规则泛化不了,不作为定位手段。 原因:`字面通顺但语义错`的句子中文本身读得通,模型没有怀疑动机;即使怀疑, 可依据的日文原文也是错的,模型只能沿错译换词。**判定为当前 LLM 能力不足,暂缓。** 实测数据、成本与复现方式: [实验数据-字幕审校定位与修复实验.md](./实验数据-字幕审校定位与修复实验.md)。 若将来重开,应把方向挪回 **ASR 侧**(只审日文/给候选读法/先建场景再对照), 那里才有声学证据;三个可测方向见该文档第六节。 ## 七、相关代码与文档 - 翻译节点:`nodes/llm.py`(`translate_lines` / `_translate_batch` / `_call_llm` / `_system_prompt`) - 审校实验脚本(一次性,已归档):`scripts/probe_subtitle_review_stage0.py` - 词表规则:`nodes/proper_nouns.py`(`PROPER_NOUNS` / `ONOMANOPOEIA` / `ADULT_EUPHEMISMS`) - 纠错节点(原型,未接入):`nodes/subtitle_correction.py` - 清洗规则:`nodes/subtitle_cleanup.py` - 批量引擎:`src/wov_app/batch.py`、资源门控 `src/wov_app/resources.py` - 决定性样本与提示词快照:`data/experiments/regen_plan/prompt_dump/` - 全量实测记录:`data/experiments/regen_plan/REPORT.md` - 成本与耗时:`docs/实验数据-字幕重生成成本与耗时.md`