拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

深入TranslateBooksWithLLMs的EPUB翻译管线:标签、样式与元数据如何被完美保留

深入TranslateBooksWithLLMs的EPUB翻译管线:标签、样式与元数据如何被完美保留

深入TranslateBooksWithLLMs的EPUB翻译管线:标签、样式与元数据如何被完美保留

【免费下载链接】TranslateBooksWithLLMsTranslate full-length books and documents with Ollama, OpenAI-compatible, Gemini, Mistral, DeepSeek, Poe or OpenRouter. Preserves formatting. Resumes where you left off. No file size limits.项目地址: https://gitcode.com/gh_mirrors/tr/TranslateBooksWithLLMs

TranslateBooksWithLLMs 是一款基于大语言模型的EPUB 全书翻译工具,支持 Ollama、OpenAI 兼容接口、Gemini、Mistral、DeepSeek、Poe、OpenRouter 等多种 LLM。它的 EPUB 翻译管线(核心位于 src/core/epub/)最打动人的地方在于:翻译完的电子书格式、样式、目录、元数据几乎原样保留,还能断点续翻。这篇文章带你拆解这条管线是如何做到"完美保留"的。

📖 为什么 EPUB 翻译这么难?

EPUB 本质是一个 ZIP 包:正文是一堆 XHTML 文件,外加content.opf(元数据清单)、NCX/nav(目录)、CSS 样式和封面图。直接用 LLM 翻译会踩三大坑:

  • 标签被破坏:模型可能吞掉<p>、改错<span>,甚至把标签当文本翻译;
  • 超长文档:一本书几万字,远超模型的上下文窗口;
  • 包装层不翻译:读者书架、书籍信息面板读的是 OPF 里的dc:title,正文翻完了,书名还挂在旧语言上。

TranslateBooksWithLLMs 的解法是一条8 步流水线,入口在 translate_epub_file()。

🔄 管线总览:8 步走完一本书

步骤做什么关键模块
1安全解压 EPUB 到临时目录translator.py
2解析content.opf清单,找出所有正文文件translator.py
2.5断点恢复:续翻时先还原已完成的文件xhtml_translation_state.py
3逐文件翻译(占位符保护标签 + 智能分块)epub_translation_adapter.py
4保存译文,同步更新 NCX / nav 目录标题translator.py
5更新元数据(lang属性、署名页)attribution_page.py
5.5翻译 OPF 书名与简介,同步 NCX 标题metadata_translator.py
6RTL/LTR 排版修正 + 目标语言lang属性 + CJK 排版清理rtl_support.py、cjk_typography.py
7重新打包 EPUB(中断时输出[partial]文件)translator.py

🏷️ 核心魔法一:标签占位符(Tag Preservation)

这是整条管线最精妙的设计。翻译前,TagPreserver 会把所有 HTML 标签替换成[id0]、[id1]这样的占位符:

<p class="body"><span>Hello world</span></p> ↓ [id0]Hello world[id1]

标签本体被存进一张"标签地图"(tag map),LLM 只看到纯文本 + 占位符,几乎不可能破坏结构。两个细节值得点赞:

  • 相邻标签自动合并:连着的</p><p><span>会合并成一个占位符,既省 token 又降低模型困惑;
  • 不可翻译内容也一起打包:空白、章节编号(如 "1."、"III")会和标签合并,避免模型去"翻译"编号。

翻译完成后,restore_tags()按地图把标签原位恢复。配套的 placeholder_validator.py 会严格校验占位符完整性——如果模型偷偷改写了占位符,管线会检测并自动纠正,而不是默默产出坏文件。

✂️ 核心魔法二:按元素边界智能分块

分块在 html_chunker.py 完成。它不是按字数硬切,而是沿 HTML 元素边界切分带占位符的正文,保证每个 chunk 都是结构完整的片段。每个 chunk 独立送 LLM 翻译,天然适配任意大小的书——这也是官方宣称"无文件大小限制"的原因。

如果你不想保留行内格式(加粗、斜体),还可以开启Plain Text Mode:plain_extractor.py 会把正文抽成纯段落翻译,图片锚定在原段落之后,块级标签保留,产出更"干净"的排版。

⏸️ 断点续翻:中断不丢进度

翻译一本长书可能需要数小时。管线为每个 XHTML 文件维护chunk 级检查点(xhtml_translation_state.py):中途断电、限速、手动暂停,重启后从第一个未翻译的 chunk 继续,已完成的文件直接恢复。

中断产生的输出文件会被自动标记为[partial],与完成版一眼区分;续翻时还能中途切换模型而不丢进度:

🎨 样式与排版:翻译后的"整形"工序

正文翻完只是半成品。管线还有三步"整形",让译文读起来像原生排版:

  1. RTL/LTR 布局修正(rtl_support.py):阿拉伯语、希伯来语目标会自动注入direction: rtl样式并修正 OPF 翻页方向;从 RTL 源语言翻译回 LTR 则自动清理方向 CSS;
  2. lang属性全面更新(lang_support.py):每个 XHTML 根节点重写为目标语言,阅读器才能正确应用连字符、词典和 TTS;
  3. CJK 排版清理(cjk_typography.py):把源语言样式里残留的中文字体栈、首行缩进、行距、书写模式等"中式排版"中和掉,避免英文译文带着中文的视觉习惯。

🏷️ 元数据翻译:书架上的书名也要换语言

很多翻译工具忽略 OPF 包装层,metadata_translator.py 专门补上这块:

  • 一次 LLM 调用同时翻译dc:title(书名)和dc:description(简介),把译出的书名同步到所有 NCX 目录文件的docTitle;
  • 绝不翻译作者名——dc:creator保持原样;
  • 永不失败原则:模型回答不合格(跑题、超长、仍含原文字符)就保留原值。元数据翻译是"锦上添花",任何异常都只记日志,绝不拖累正文翻译成功;
  • 正文里的目录标题(translator.py 的 4.5/4.6 步)也会从译文标题回填到 NCX 和 EPUB3 的nav.xhtml,保证阅读器侧边栏目录与正文一致。

📦 最后一步:安全重打包

所有文件修改完成后,管线把临时目录重新压缩为 EPUB。整个过程通过 safe_extract_zip 等安全函数解压,并追加 署名页 标注翻译工具来源——对开源生态很友好。

📁 想深入源码?从这里开始

  • 管线总控:src/core/epub/translator.py
  • 标签保护:src/core/epub/tag_preservation.py
  • 元数据本地化:src/core/epub/metadata_translator.py
  • 分块逻辑:src/core/epub/html_chunker.py
  • 断点状态:src/core/epub/xhtml_translation_state.py
  • 使用文档:docs/CLI.md、docs/EPUB_SCRIPT_NORMALIZATION.md
  • 相关测试:tests/unit/epub/

✅ 小结

TranslateBooksWithLLMs 的 EPUB 翻译管线用占位符保护标签、按元素分块、检查点续翻、OPF 元数据本地化、排版整形五板斧,把"LLM 翻译书籍"这件高风险的事做成了可信赖的工程流程。如果你需要批量翻译技术文档或小说,又在意输出质量与格式保真,这套管线值得作为参考范本。

【免费下载链接】TranslateBooksWithLLMsTranslate full-length books and documents with Ollama, OpenAI-compatible, Gemini, Mistral, DeepSeek, Poe or OpenRouter. Preserves formatting. Resumes where you left off. No file size limits.项目地址: https://gitcode.com/gh_mirrors/tr/TranslateBooksWithLLMs

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

返回列表