[!TIP] 受众:在折腾本地图像 / OCR / 翻译流水线的人,以及想给工具做体验审计的人。 核心目标:五段流水线怎么跑通,以及"不改一行代码的 UX 走查"为什么能抓到 6 处读代码发现不了的问题。 问题-方案映射

  • 冷启动并发 import torch 崩溃 → 主线程预导入
  • 机器翻不对的地方 → pages.json + 应用内校对
  • “导出没生效"的错觉 → 只有「导出全部」才写最终交付物

这套漫画翻译工具把一卷漫画从日文变成熟肉,跑的是五段流水线:日文定位 → OCR 识别 → 翻译 → 抹字修复 → 译文贴回。输入输出同格式,文件夹 / ZIP / CBZ / EPUB / PDF 进什么出什么(RAR 不可写,转 CBZ)。翻译引擎三个:sakura(仅日文源)、llm(Qwen3-4B,多语言)、mock(离线自测)。

批量页把几十卷一口气跑完:任务逐个顺序执行(一块 GPU 同时只能跑一个模型任务),结束零弹窗自动推进,中途停止后重新开始,已完成的不会重跑、被停止或失败的从各自断点继续。

1. 模型账单,和不用重复下载

五个阶段各吃一份模型:检测约 170MB、OCR 约 450MB、抹字约 200MB,Sakura 引擎另需约 4.3GB。首次运行的向导可以把模型目录指向已有的池子——比如我在 subgen 项目里下过的那份——直接复用,不重复下载。模型路径按 manifest 记 repo / 文件名 / 精确字节数,四态判定就位 / 缺失 / 路径失效 / 大小不符,绑定失效直接报错,绝不静默回落去联网下载顶替。

2. 机器翻不对的地方,人得能改

翻译质量再高也总有机器处理不了的地方,所以每页结果落在工作目录的 pages.json 里:原文 / 译文 / 坐标,外加各模型实际路径和阶段耗时。校对在应用内做,不碰任何文件:画布上每个检测框都可点,右侧显示原文,改完译文按 Ctrl+Enter 保存。「需要注意」列表按检测置信度低 / OCR 没识别出文字 / 缺译文 / 整页失败筛出来,不用通读全书。

这里有一条特别容易踩的坑:只有「导出全部」才会把改动写进最终交付物。单页「重渲染本页」只更新工作目录里的图,最终包还是旧的——用户以为"改过了就完成”,拿到手的却是旧产物。这是"界面看着完成、产物没跟上"的典型。

3. 一次不改代码的 UX 走查

流水线跑通之后,我做了一次全操作面的 UX 走查:单任务 / 批量 / 校对 / 导出 / 模型管理 / 设置 / 自检 / 首次运行,全部按「前置 → 进行中 → 结束 → 再次进入」四段拆解。验证方式是 10 次离屏真实运行:用 QT_QPA_PLATFORM=offscreen 构造真窗口,跑真实 detect/OCR/抹字模型 + mock 翻译,覆盖文件夹 / EPUB / PDF 三种输入,含取消、续跑、批量零弹窗推进、跨会话重渲染。只分析,没改一行代码。

最值得写的一条:冷启动并发导入 torch 会崩。重渲染路径跳过前两阶段,worker 线程第一次 import torch 发生在抹字模型构造,与启动时环境自检线程的并发导入互撞,触发 torch 2.6 的 circular import(partially initialized module 'torch' ...)。实测 2/2 复现;主线程预导入 torch 后 1/1 通过;纯 Runner(无 Qt 无线程)调用 1/1 通过。失败时甩给用户的是整屏英文 Python 堆栈——这违反"失败要说人话"。

其余几条同类问题:导出重新打包到默认路径而不是原任务的实际输出位置(实测原 book_out.epub,导出得到 book_translated.epub),用户容易以为导出没生效;模型管理 / 自检页的按钮在任务运行中可点但静默无效,是全项目唯一"点了没反应"的地方;模型下载只有起止两条日志,没有字节进度和 ETA,违反"超 10 秒必须有进度"。

这次走查最有价值的产出是一句话:读代码得出的结论和真跑一遍的结论,有 6 处不一样。这不是审计方法的功劳,是"跑过"和"看过"本来就是两种信息。

4. 稳定性收尾

0.2.0 把一批积累的问题收掉:三处无限增长——comicgen.log 每次启动截断、run.log 每次 run 重置、retired_threads 退出即清;行平衡二分从 16 次迭代减到 10 次,密集页 CPU 排版 -24.7%(多出来的迭代纯属白算,10 次后精度已到亚像素);离线开关从进程级永久态改成"本次运行"作用域,跑完恢复;四处"静默吞掉异常"的路径补上日志;落地 ruff + mypy 门禁。

小结

这条流水线最深的体会是:机器把五段跑通只是第一步,“让人愿意用它"才是真正难的。而做到后者,靠的不是多聪明的模型,是把机器做不好的地方——校对入口、导出语义、失败反馈——一点点补成能用的状态。那句"6 处不一样"我留在这里,下次给任何工具做体验评估,我都会先真跑一遍再说。