Fork me on GitHub

分类 PDFMathTranslate 下的文章

基于 PDFMathTranslate 的二次开发

经过前几天的学习,我们对 PDFMathTranslate 这款 PDF 翻译工具应该基本上会用了,不仅可以自己用,还可以做成 Web 页面分享给别人用。如果只是将 PDFMathTranslate 作为工具使用的话,没有问题,但是如果希望将 PDF 翻译这个功能集成到我们自己的产品或应用中,那么就需要二次开发了。今天是 PDFMathTranslate 系列的最后一篇,关于如何使用它的 SDK 或 API 进行二次开发。

Python SDK

pdf2zh 不仅是一个命令行工具,同时它也是一个 Python 模块,它提供了两个方法,以便在其他程序中调用:

from pdf2zh import translate, translate_stream

要注意的是,之前我们安装 pdf2zh 的命令如下:

$ uv tool install --python 3.12 pdf2zh

这行命令会创建一个 Python 3.12 的虚拟环境,并将 pdf2zh 及其依赖安装在该环境中,因此在开发时,可以将 Python 环境指向这个虚拟环境。

那么这个虚拟环境的位置在哪呢?可以先通过 which pdf2zh 查看 pdf2zh 的安装位置:

$ which pdf2zh
/Users/aneasystone/.local/share/uv/tools/pdf2zh/bin/pdf2zh

然后再看下这个脚本的内容:

% cat /Users/aneasystone/.local/share/uv/tools/pdf2zh/bin/pdf2zh
#!/Users/aneasystone/.local/share/uv/tools/pdf2zh/bin/python
# -*- coding: utf-8 -*-
import sys
from pdf2zh.pdf2zh import main
if __name__ == "__main__":
    if sys.argv[0].endswith("-script.pyw"):
        sys.argv[0] = sys.argv[0][:-11]
    elif sys.argv[0].endswith(".exe"):
        sys.argv[0] = sys.argv[0][:-4]
    sys.exit(main())

脚本开头的 #! 符号后面就是它使用的 Python 虚拟环境的位置,可以将 IDE 的 Interpreter 设置成这个:

python-interpreter.png

pdf2zh 提供的两个方法都比较简单,translate 方法用于直接翻译 PDF 文件,运行效果和命令行几乎一样:

from pdf2zh.doclayout import OnnxModel
params = {
    'lang_in': 'en',
    'lang_out': 'zh',
    'service': 'google',
    'thread': 4,
    'model': OnnxModel.load_available()
}

(file_mono, file_dual) = translate(files=['example.pdf'], **params)[0]
print(file_mono, file_dual)

注意这里的 model 参数必须设置,这个在官方文档中是缺失的,可以使用默认的 OnnxModel.load_available(),否则运行会报错。

运行成功后,在当前目录生成 example-mono.pdfexample-dual.pdf 两个文件。

translate_stream 方法用于输出文件流,这个方式的好处是可以自己控制输出哪个文件、输出位置以及文件名:

with open(filepath, 'rb') as f:
    (stream_mono, stream_dual) = translate_stream(stream=f.read(), **params)
    with open('./dual.pdf', 'wb') as dual:
        dual.write(stream_dual)

HTTP API

PDFMathTranslate 默认安装是不带 HTTP API 功能的,我们必须安装 pdf2zhbackend 模块:

$ uv tool install --python 3.12 "pdf2zh[backend]"

安装结束后,pdf2zh 命令会多两个参数 --flask--celery

在使用 PDFMathTranslate 的 API 功能之前,还需要启动 Redis 服务:

$ docker run -d -p 6379:6379 redis:alpine

这是因为它的 API 是通过 Celery 任务队列异步实现的,默认使用的 Broker 和 Backend 是 Redis 服务:

flask_app = Flask("pdf2zh")
flask_app.config.from_mapping(
    CELERY=dict(
        broker_url=ConfigManager.get("CELERY_BROKER", "redis://127.0.0.1:6379/0"),
        result_backend=ConfigManager.get("CELERY_RESULT", "redis://127.0.0.1:6379/0"),
    )
)

可以在配置文件中修改 CELERY_BROKERCELERY_RESULT 参数:

pdf2zh-config.png

Celery 是一个基于 Python 的 分布式任务队列(Distributed Task Queue),主要用于处理异步任务和定时任务。它可以让你把一些耗时的操作(比如发送邮件、处理图片、数据分析等)放到后台去执行,而不会阻塞主程序的运行。Celery 通过 消息中间件(Broker) 来传递任务,常用的有 Redis、RabbitMQ、Amazon SQS 等。

Flash Web 服务

当以 --flask 参数启动时,代码会调用 flask_app.run(port=11008),即以 11008 端口启动 Flask Web 服务:

$ pdf2zh --flask
 * Serving Flask app 'pdf2zh'
 * Debug mode: off
 * Running on http://127.0.0.1:11008

此时我们就可以调用 HTTP 接口了。

首先,提交任务:

$ curl http://localhost:11008/v1/translate \
    -F "file=@2504.08748v1.pdf" \
    -F "data={\"lang_in\":\"en\",\"lang_out\":\"zh\",\"service\":\"google\",\"thread\":4}"
{"id":"2294c23a-8fbe-4ab6-9d57-c6ece0cd9e9e"}

该接口返回任务 ID,通过 ID 可以查看任务状态和进度:

$ curl http://localhost:11008/v1/translate/2294c23a-8fbe-4ab6-9d57-c6ece0cd9e9e

等待处理状态:

{"state":"PENDING"}

处理中状态:

{"info":{"n":5,"total":80},"state":"PROGRESS"}

处理结束状态:

{"state":"SUCCESS"}

当任务状态为 SUCCESS 时,即可下载翻译后的文件:

# 中文版本
$ curl http://localhost:11008/v1/translate/2294c23a-8fbe-4ab6-9d57-c6ece0cd9e9e/mono \
    --output example-mono.pdf

# 双语版本
$ curl http://localhost:11008/v1/translate/2294c23a-8fbe-4ab6-9d57-c6ece0cd9e9e/dual \
    --output example-dual.pdf

Celery Worker

当以 --celery 参数启动时,代码会调用 celery_app.start(argv=sys.argv[2:]),即用命令行参数启动 Celery Worker:

$ pdf2zh --celery worker
 
 -------------- celery@aneasystone.local v5.5.2 (immunity)
--- ***** ----- 
-- ******* ---- macOS-15.3.2-arm64-arm-64bit 2025-05-17 07:14:05
- *** --- * --- 
- ** ---------- [config]
- ** ---------- .> app:         pdf2zh:0x12d604a40
- ** ---------- .> transport:   redis://127.0.0.1:6379/0
- ** ---------- .> results:     disabled://
- *** --- * --- .> concurrency: 8 (prefork)
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
--- ***** ----- 
 -------------- [queues]
                .> celery           exchange=celery(direct) key=celery

参考 pdf2zh/backend.py 的代码,可以调用 translate_task.delay() 来向 Celery Worker 提交任务:

from pdf2zh.backend import translate_task

with open(filepath, 'rb') as f:
    task = translate_task.delay(f.read(), params)
    print(task.id)
    
    while True:
        time.sleep(1)
        if str(task.state) == "PROGRESS":
            print('state: ', task.state, 'info: ', task.info)
        else:
            print('state: ', task.state)
        if str(task.state) == "SUCCESS":
            break

    doc_mono, doc_dual = task.get()
    with open('./dual.pdf', 'wb') as dual:
        dual.write(doc_dual)

小结

至此,关于 PDFMathTranslate 的学习暂时就告一段落了,除了 SDK 和 API 之外,PDFMathTranslate 还提供了 MCP 工具,方便我们在 AI 工具中使用,或者用在智能体应用的开发中,感兴趣的朋友可以继续探究。

从 PDFMathTranslate 的学习中我们可以看到,虽然这只是一个小小的工具,解决的也只是一个小小的 PDF 翻译问题,但是麻雀虽小,五脏俱全,从命令行工具,到 Web 页面,到 Docker 部署和云部署,到 SDK、API、MCP 样样俱全,满足了各类人群的需求,这也是它为什么在开源社区如此流行的原因,目前 Github 上星标已经超过 23K。通过对 PDFMathTranslate 的深入学习和探索,可以看到一个流行的开源项目是怎么做的,希望能给大家一些启发。


学习 PDFMathTranslate 的 Web UI

这两天对 PDFMathTranslate 的命令行用法大致学习了一遍。首先,我们学习了它的基本参数,使用基本参数已经可以满足我们的日常需要,然后在高级参数里,我们又深入研究了它的实现原理。除了使用命令行,PDFMathTranslate 还提供了可视化 Web 页面,这可以方便我们搭建自己的 PDF 翻译服务,今天就继续看看 Web UI 的使用。

使用 Web UI

输入 pdf2zh -i 命令启动 Web 服务:

$ pdf2zh -i

启动后通过浏览器访问 http://localhost:7860/ 即可进入 PDFMathTranslate 的 Web 页面:

pdf2zh-webui.jpg

启动如果报错,注意看下电脑上是不是开启了全局代理。

修改端口号

Web 服务默认端口为 7860,可以通过 --serverport 参数修改:

$ pdf2zh -i --serverport 7861

* Running on local URL:  http://0.0.0.0:7861

公开链接

通过上面的命令启动 Web 服务只能在本机通过 localhost 访问,或者同一局域网的人通过你的内网 IP 访问。PDFMathTranslate 支持为我们的 Web 服务生成一个公开链接,分享给互联网上的其他人访问:

$ pdf2zh -i --share

* Running on public URL: https://8e15230244c69bee4e.gradio.live

这是通过 HuggingFace 提供的 Gradio 服务实现的:

gradio-home.jpg

Gradio 能为我们分配一个公共 URL,这个 URL 会反向代理到你的本地应用。注意这个 URL 是临时的,有效期通常是 1 个星期。

其实,PDFMathTranslate 的整个 Web UI 功能就是基于 gradio 库实现的,这个库看上去蛮有意思,可以让 Python 开发人员不写任何前端代码实现一个 Web 页面,后面有机会专门学习下这个库。

用户认证

如果不想让你的 Web 服务对所有人开放,可以开启用户认证功能。首先建一个 users.txt 文件:

admin,123456
test,test

文件中每行代表一条用户信息,包含用户名和密码,用逗号分隔。然后通过 --authorized 参数启动:

$ pdf2zh -i --authorized users.txt

再次打开 Web 页面,就需要输入用户名和密码:

pdf2zh-webui-login.png

我们还可以对登录页面做一些定制,比如修改标题或加一些自己的文案。创建一个 auth.html 文件:

<!DOCTYPE html>
<html>
<head>
    <title>Simple HTML</title>
</head>
<body>
    <h1>Hello, World!</h1>
    <p>Welcome to my simple HTML page.</p>
</body>
</html>

通过下面的命令启动:

$ pdf2zh -i --authorized users.txt auth.html

刷新登录页面,如下:

pdf2zh-webui-login-custom.png

指定配置文件

当我们自己部署 PDFMathTranslate 的 Web 服务并分享给别人使用时,还有两个问题需要特别注意。第一个问题是,默认情况下 PDFMathTranslate 在翻译服务列表中会显示所有支持的服务:

pdf2zh-webui-options.png

但是很显然,可能只有几个服务是可用的,其他的服务不希望显示在下拉列表中。另一个问题是,当我们选某个翻译服务时,这个翻译服务的配置信息也会显示出来:

pdf2zh-webui-options-openai.png

这会把我们的 API KEY 泄露出去,这也是公开部署时不希望看到的。

为了解决这两个问题,PDFMathTranslate 支持在配置文件中设置 ENABLED_SERVICESHIDDEN_GRADIO_DETAILS 两个参数:

  • ENABLED_SERVICES - 控制选项列表中仅显示启用的服务;
  • HIDDEN_GRADIO_DETAILS - 隐藏真实的 API KEY,防止用户获取服务器端密钥;

默认情况下,PDFMathTranslate 的配置文件保存在 ~/.config/PDFMathTranslate/config.json 中,可以通过 --config 参数修改配置文件的位置:

$ pdf2zh -i --config /path/to/config/config.json

程序首先读取 config.json 的内容,然后读取环境变量的内容,当环境变量可用时,优先使用环境变量,同时更新文件。修改后的配置文件如下:

pdf2zh-config.png

其中,Google 和 Bing 翻译服务默认就有,不用配置。

部署到云平台

PDFMathTranslate 的 Web 服务可以使用 Docker 部署:

$ docker run -d -p 7860:7860 byaidu/pdf2zh

因此也可以很方便地部署到云平台上:

pdf2zh-deploy-cloud.png

这里列出的是一些比较热门的云应用部署平台:

  • Heroku - The AI PaaS for Deploying, Managing, and Scaling Apps
  • Render - Cloud Application Platform
  • Zeabur - Deploy Painlessly, Scale Infinitely
  • Sealos - Develop, deploy, and scale in one seamless cloud platform
  • Koyeb - High-performance Infrastructure for APIs, Inference, and Databases

这几个基本上都需要付费使用的,免费的额度内存太小部署不起来。其中 Koyeb 有几天 Pro 权益的试用,我体验下来感觉还可以,感兴趣的朋友可以尝试下。

pdf2zh-deploy-koyeb.png


深入 PDFMathTranslate 的高级用法

昨天学习了 PDFMathTranslate 的基本用法,主要是一些简单的命令行参数。它的命令行参数还有很多,今天继续看看它的一些高级用法。

多线程

使用多线程可以显著提高翻译速度,特别是对于包含大量文本的文档。可以通过 -t--thread 参数控制翻译时使用的线程数,默认值为 4:

$ pdf2zh example.pdf -t 8

忽略翻译缓存

PDFMathTranslate 在翻译的过程中会将原文和译文保存到缓存里,下次再遇到相同文本时直接使用缓存,这样不仅可以提高翻译速度,也避免了对相同内容进行不必要的 API 调用。

可以通过 --ignore-cache 参数来忽略翻译缓存,强制重新翻译:

$ pdf2zh example.pdf --ignore-cache

深入源码可以发现 PDFMathTranslate 使用 SQLite 作为缓存,缓存的文件位于 ~/.cache/pdf2zh/cache.v1.db,感兴趣的同学可以打开这个文件研究下:

pdf2zh-sqlite.png

可以看到它使用 翻译引擎+翻译引擎参数+原文 三个参数作为唯一键:

UNIQUE (
    translate_engine,
    translate_engine_params,
    original_text
    )
ON CONFLICT REPLACE

处理特殊情况

PDFMathTranslate 的核心功能是翻译过程中保持论文中的公式、图表、目录结构和注释不变。其中公式识别是比较难做的,源码中有大量和公式相关的处理代码(参考 TranslateConverter 类的 receive_layout() 方法)。尽管如此,难免会遇到一些特殊情况,PDFMathTranslate 提供了 -f-c 两个参数来允许我们手动处理这些例外。

这两个参数都是正则表达式,-f 表示需要保留的公式字体,-c 表示需要保留的字符,比如下面这个例子:

$ pdf2zh example.pdf -f "(CM[^RT].*|MS.*|.*Ital)" -c "(\(|\||\)|\+|=|\d|[\u0080-\ufaff])"

其中 -f "(CM[^RT].*|MS.*|.*Ital)" 使用正则表达式来匹配特定的字体名称:

  • CM[^RT].* :匹配以 CM 开头,后面不是 RT 的字体,如 CMSansCMMono 等;
  • MS.* :匹配以 MS 开头的字体,如 MSGothicMSSong 等;
  • .*Ital :匹配以 Ital 结尾的字体,如 TimesItalArialItal 等;

后面的 -c "(\(|\||\)|\+|=|\d|[\u0080-\ufaff])" 匹配特定的字符:

  • \( :左括号
  • \| :竖线符号
  • \) :右括号
  • \+ :加号
  • = :等号
  • \d :任何数字(0-9)
  • [\u0080-\ufaff] :Unicode 范围从 0x0080 到 0xfaff 的字符,这个范围包含了大多数非 ASCII 字符,包括中文、日文、韩文等 CJK 字符;

或者下面这个更复杂的例子,保留 LatexMonoCodeItalicSymbolMath 字体:

$ pdf2zh example.pdf -f "(CM[^R]|MS.M|XY|MT|BL|RM|EU|LA|RS|LINE|LCIRCLE|TeX-|rsfs|txsy|wasy|stmary|.*Mono|.*Code|.*Ital|.*Sym|.*Math)"

这些字体一般都是数学公式中常用的字体,这对于正确识别和保留数学公式非常重要,确保 PDFMathTranslate 不会尝试翻译数学符号,而是保持它们的原样。

可以使用 Popplerpdffonts 命令查看某个 PDF 文件使用的所有字体:

pdffonts.png

兼容模式

PDF/A 是一种专为长期电子文档归档设计的国际标准格式,它解决了普通 PDF 可能面临的长期可读性挑战,确保文档在未来数十年内无论使用何种软硬件环境仍可访问和完整呈现。PDF/A 通过三大核心原则实现这一目标:自包含性(嵌入所有字体和资源)、自文档化(包含标准元数据)和 自描述性(禁用外部依赖)。它禁止使用 JavaScript、外部链接和多媒体内容等不稳定元素,同时要求文档包含必要的结构信息。这使其成为法律文档、医疗记录、学术论文和政府档案等重要信息的理想载体,既满足合规要求,又保障内容的长期可用性和完整性。

PDFMathTranslate 支持通过 --compatible-cp 参数将 PDF 转换为 PDF/A 格式,提高 PDF 文件的兼容性:

$ pdf2zh example.pdf --compatible

在遇到 PDF 解析问题时,可以考虑这个参数试试。

值得一提的是,这个功能主要是通过 pikepdf 这个 PDF 库实现的:

pdf2zh-convert-pdfa.png

跳过字体子集化

字体子集化(Fonts subsetting) 是一种字体处理技术,用于减少字体文件的大小。具体来说,它从一个完整的字体文件中提取出只需要的字符或字形,从而创建一个包含所需字符的较小的字体文件。这在 网页设计移动应用开发文档生成 等场景中非常有用,能够提高加载速度和性能,同时也可以减少占用的存储空间。

上面 pdffonts 命令的输出结果中,ABCDEF+XXX 这种格式的字体其实就是子集化字体。

默认情况下,PDFMathTranslate 会使用字体子集化来减小输出文件的大小。可以通过 --skip-subset-fonts 参数跳过这个步骤:

$ pdf2zh example.pdf --skip-subset-fonts

使用这个参数的主要原因是解决兼容性问题。在某些情况下,字体子集化可能会导致生成的 PDF 文件在某些阅读器上无法正确显示,特别是那些对字体处理有特殊要求的阅读器。当你发现翻译后的文件在某些 PDF 阅读器中显示不正确或排版有问题时,可以尝试使用这个参数。

PDFMathTranslate 的字体子集化使用的是 PyMuPDFDocument.subset_fonts() 方法实现的:

if not skip_subset_fonts:
    doc_zh.subset_fonts(fallback=True)
    doc_en.subset_fonts(fallback=True)

使用自定义的 DocLayout 模型

PDFMathTranslate 在使用时会从 HuggingFace 下载一个模型 wybxc/DocLayout-YOLO-DocStructBench-onnx 用于 PDF 的布局分析,可以使用 --onnx 这个参数指定自己训练或微调的 ONNX 模型来替代默认模型:

$ pdf2zh --onnx [onnx/model/path]

DocLayout 模型一般用于确定文档中的不同元素(如文本、图形、表格、公式等)的位置,下面这段代码是使用 ONNX 模型对 PDF 页面进行布局分析并处理的核心部分:

pdf2zh-model-predict.png

这段代码的大致逻辑如下:

  1. 使用 ONNX 模型识别 PDF 页面中的各种元素(文本、图片、表格、公式等);
  2. 创建一个"蒙版"矩阵,标记页面上需要翻译的区域(值>1)和不需要翻译的区域(值=0);
  3. 这个蒙版矩阵后续会被用于指导翻译过程,确保只翻译正常文本而保留图片、表格和数学公式等不需要翻译的内容;

使用 BabelDOC 后端

BabelDOC 是沉浸式翻译团队提供的 PDF 翻译服务,可以通过他们的在线页面进行体验:

同时他们也将其核心部分开源了出来。PDFMathTranslate 支持通过 --babeldoc 参数,允许用户使用 BabelDOC 作为后端进行 PDF 翻译,而不是使用 pdf2zh 的默认后端:

pdf2zh --babeldoc -s openai example.pdf

使用 BabelDOC 后端目前还处于实验特性,如果默认翻译有问题的话可以尝试下。


学习 PDFMathTranslate 的基本用法

昨天给大家介绍了 PDFMathTranslate 这款免费开源的 PDF 文档翻译工具,主要包括功能介绍、安装步骤以及基本使用。今天继续学习它的基本用法,介绍下它的几个基本命令行参数。

基本参数

初次使用 PDFMathTranslate 时,我们直接执行了下面这个不带任何参数的命令:

$ pdf2zh example.pdf

这个命令默认使用 Google 作为翻译服务,将 example.pdf 翻译成中文文档 example-mono.pdf 以及双语文档 example-dual.pdf

翻译后的文档默认输出到当前工作目录中,可以通过 -o 指定输出目录:

$ pdf2zh example.pdf -o output_dir

下图是 PDFMathTranslate 的一些基本参数:

pdf2zh-cmd.png

指定翻译文档

命令行的第一部分指定要翻译的文档,PDFMathTranslate 支持本地单个文档翻译,本地目录批量翻译,以及在线文档翻译。

本地单个文档翻译:

$ pdf2zh ~/local.pdf

本地目录批量翻译:

$ pdf2zh --dir /path/to/translate/

在线文档翻译:

$ pdf2zh http://arxiv.org/paper.pdf

指定翻译服务

PDFMathTranslate 支持传统的翻译服务,如 Google、Bing、DeepL 等,也支持使用大模型翻译,如 OpenAI、Gemini、DeepSeek 等。除了 Google 和 Bing 这两个免费的翻译服务,其他的服务在使用前需要通过环境变量设置必要的参数。

比如使用 DeepL 翻译,通过 DEEPL_AUTH_KEY 设置 API KEY:

$ export DEEPL_AUTH_KEY=xxx
$ pdf2zh example.pdf -s deepl

使用 OpenAI 大模型翻译,通过 OPENAI_BASE_URL 设置 API 接口地址,这对于一些 OpenAI 兼容的服务非常有用,另外 OPENAI_API_KEYOPENAI_MODEL 分别用于设置 API KEY 和模型:

$ export OPENAI_BASE_URL=https://api.bianxie.ai/v1
$ export OPENAI_API_KEY=sk-xxx
$ export OPENAI_MODEL=gpt-4o-mini
$ pdf2zh example.pdf -s openai

当使用大模型翻译时,默认使用的 Prompt 如下:

pdf2zh-default-prompt.png

可以通过 --prompt 参数进行修改,用户自定义的 Prompt 中可以使用 lang_inlang_outtext 三个变量:

$ pdf2zh --prompt [prompt.txt]

下面是关于每个翻译服务所需环境变量的详细表格,在使用相应服务之前,请确保设置它们:

pdf2zh-translate-service.png

指定翻译范围

PDFMathTranslate 默认翻译整个 PDF 文档,可以通过 -p 指定只翻译部分页,多个页码之间使用逗号分割,连续页码可以用连字符连接:

$ pdf2zh example.pdf -p 1-3,5

指定翻译语言

通过 -li-lo 设置源语言和目标语言,比如下面的命令表示从英文翻译成日文:

$ pdf2zh example.pdf -li en -lo ja

其中的语言编码符合 ISO 639-1 标准,可以参考 Google Languages CodesDeepL Languages Codes


PDFMathTranslate 介绍:一款免费开源的 PDF 文档翻译工具

最近几年 AI 技术发展很快,和 AI 相关的论文也是层出不穷,比如我关注的论文网站 arXiv 上,经常发布一些 PDF 论文,但是这些论文常常以英文呈现,对于英文不好的同学来说,阅读和理解这些论文是一大挑战。

今天给大家介绍一款免费开源的 PDF 文档翻译工具 PDFMathTranslate,可以在保留原文档排版的前提下,将文档内容翻译成中文,是数学、科学等领域学习者的必备神器!

pdf2zh-banner.png

项目地址:https://github.com/Byaidu/PDFMathTranslate

功能介绍

PDFMathTranslate 是一个专注于科学论文翻译的开源工具,能够将 PDF 文档全文翻译并生成双语对照版本。它的核心功能如下:

  • 保留原文格式 :翻译过程中保持论文中的公式、图表、目录结构和注释不变;
  • 多语言支持 :支持中文、英语、日语等100多种语言,可以在多种语言之间进行翻译;
  • 多种翻译服务 :支持 Google、DeepL、Ollama、OpenAI 等多种翻译服务或大模型服务,并支持 Xinference 本地模型;
  • 全文翻译与部分翻译 :支持全文翻译,或用户选定页面翻译;
  • 双语对照 :支持生成双语对照文件,方便用户对照原文和译文;
  • 多种使用方式 :提供命令行(CLI)、图形界面(GUI)、Docker 部署和 Zotero 插件等多种使用方式,满足科研人员快速翻译和阅读的需求;
  • 公共服务 :提供在线翻译服务,用户无需安装任何软件;

安装 PDFMathTranslate

首先确保电脑上有 Python 环境,版本不低于 3.10 且不高于 3.12,然后使用 pip install 命令直接安装:

$ pip install pdf2zh

不过,官方推荐的安装方式是使用 uv 命令,不仅速度更快,而且对 Python 环境的管理更方便。我们可以通过下面的命令安装 uv

$ pip install uv

uv 是一个快速的 Python 包安装器和解析器,由 Astral 开发,旨在替代传统的 pippip-toolsvirtualenv 等工具。主要特点如下:

  • 极速性能uv 使用 Rust 编写,相比传统工具速度提升显著,安装包的速度可以比 pip 快 10-100 倍;
  • 兼容性 :与现有的 Python 生态系统完全兼容,支持 requirements.txtpyproject.toml 等标准格式;
  • 虚拟环境管理 :内置虚拟环境创建和管理功能,可以替代 virtualenv 命令;
  • 依赖解析 :提供先进的依赖解析器,可以替代 pip-tools,解决复杂的依赖关系;
  • 工具管理 :通过 uv tool 命令可以安装和管理全局 Python 工具,类似于 pipx 命令;

然后使用 uv tool install 安装:

$ uv tool install --python 3.12 pdf2zh

这行命令会创建一个 Python 3.12 的虚拟环境,并将 PDFMathTranslate 安装在该环境中,安装成功会列出所有的依赖包,可以看到 PDFMathTranslate 使用了不少优秀的开源项目,如下:

Resolved 117 packages in 16.69s
      Built peewee==3.18.1
      Built untokenize==0.1.1
Prepared 103 packages in 34.29s
Installed 117 packages in 535ms
 + aiofiles==24.1.0
 + annotated-types==0.7.0
 + anyio==4.9.0
 + azure-ai-translation-text==1.0.1
 + azure-core==1.34.0
 + babeldoc==0.2.33
 + bitarray==3.4.0
 + bitstring==4.3.1
 + certifi==2025.4.26
 + cffi==1.17.1
 + charset-normalizer==3.4.2
 + click==8.2.0
 + click-default-group==1.2.4
 + coloredlogs==15.0.1
 + configargparse==1.7
 + cryptography==44.0.3
 + deepl==1.22.0
 + deprecated==1.2.18
 + distro==1.9.0
 + docformatter==1.7.7
 + fastapi==0.115.12
 + ffmpy==0.5.0
 + filelock==3.18.0
 + flatbuffers==25.2.10
 + fonttools==4.58.0
 + freetype-py==2.5.1
 + fsspec==2025.3.2
 + gradio==5.29.0
 + gradio-client==1.10.0
 + gradio-pdf==0.0.22
 + groovy==0.1.2
 + h11==0.16.0
 + hf-xet==1.1.1
 + httpcore==1.0.9
 + httpx==0.28.1
 + huggingface-hub==0.31.1
 + humanfriendly==10.0
 + idna==3.10
 + imageio==2.37.0
 + isodate==0.7.2
 + jinja2==3.1.6
 + jiter==0.9.0
 + lazy-loader==0.4
 + levenshtein==0.27.1
 + lxml==5.4.0
 + markdown-it-py==3.0.0
 + markupsafe==3.0.2
 + mdurl==0.1.2
 + mpmath==1.3.0
 + msgpack==1.1.0
 + networkx==3.4.2
 + numpy==2.2.5
 + ollama==0.4.8
 + onnx==1.18.0
 + onnxruntime==1.22.0
 + openai==1.78.1
 + opencv-python==4.11.0.86
 + opencv-python-headless==4.11.0.86
 + orjson==3.10.18
 + packaging==25.0
 + pandas==2.2.3
 + pdf2zh==1.9.9
 + pdfminer-six==20250416
 + peewee==3.18.1
 + pikepdf==9.7.0
 + pillow==11.2.1
 + protobuf==6.30.2
 + psutil==7.0.0
 + pyclipper==1.3.0.post6
 + pycparser==2.22
 + pydantic==2.11.4
 + pydantic-core==2.33.2
 + pydub==0.25.1
 + pygments==2.19.1
 + pymupdf==1.25.2
 + python-dateutil==2.9.0.post0
 + python-levenshtein==0.27.1
 + python-multipart==0.0.20
 + pytz==2025.2
 + pyyaml==6.0.2
 + rapidfuzz==3.13.0
 + rapidocr-onnxruntime==1.4.4
 + regex==2024.11.6
 + requests==2.32.3
 + rich==14.0.0
 + ruff==0.11.9
 + safehttpx==0.1.6
 + scikit-image==0.25.2
 + scipy==1.15.3
 + semantic-version==2.10.0
 + shapely==2.1.0
 + shellingham==1.5.4
 + six==1.17.0
 + sniffio==1.3.1
 + socksio==1.0.0
 + starlette==0.46.2
 + sympy==1.14.0
 + tenacity==9.1.2
 + tencentcloud-sdk-python-common==3.0.1377
 + tencentcloud-sdk-python-tmt==3.0.1377
 + tifffile==2025.5.10
 + tiktoken==0.9.0
 + toml==0.10.2
 + tomlkit==0.13.2
 + toposort==1.10
 + tqdm==4.67.1
 + typer==0.15.3
 + typing-extensions==4.13.2
 + typing-inspection==0.4.0
 + tzdata==2025.2
 + untokenize==0.1.1
 + urllib3==2.4.0
 + uvicorn==0.34.2
 + websockets==15.0.1
 + wrapt==1.17.2
 + xinference-client==1.5.1
 + xsdata==25.4
Installed 1 executable: pdf2zh

使用 PDFMathTranslate

通过 pdf2zh -v 显示 PDFMathTranslate 版本号,确认安装无误:

$ pdf2zh -v
pdf2zh v1.9.9

然后就可以使用 PDFMathTranslate 的翻译功能了。我们先找一个英文的 PDF 文件,比如我最近在看的这篇关于多模态 RAG 的一个综述论文:

我们将其下载到本地,然后直接运行 pdf2zh xxx.pdf 即可:

$ pdf2zh ./2504.08748v1.pdf

运行结束后会在当前目录生成两个文件:2504.08748v1-mono.pdf2504.08748v1-dual.pdf,其中 mono 文件是翻译后的中文 PDF 文件,而 dual 文件是中英双语 PDF 文件:

pdf2zh-dual.png

我认为这个功能非常赞,打开 PDF 文件时使用双页视图,双语的阅读体验非常好。

需要注意的是,PDFMathTranslate 在使用时会从 HuggingFace 下载一个模型 wybxc/DocLayout-YOLO-DocStructBench-onnx 用于 PDF 的布局分析,如果你访问 HuggingFace 时遇到网络问题,建议通过下面的命令将 HuggingFace 地址替换为国内的镜像源:

$ set HF_ENDPOINT=https://hf-mirror.com

由于使用了沉浸式翻译团队开源的 BabelDOC 项目,下载的模型位于 ~/.cache/babeldoc/models/ 位置。

另外,PDFMathTranslate 也提供了可视化 Web 页面,运行 pdf2zh -i 自动打开浏览器:

$ pdf2zh -i
[05/13/25 07:20:11] INFO     INFO:babeldoc.docvision.doclayout:Loading ONNX model...
                    INFO     INFO:babeldoc.docvision.doclayout:Available Provider: CPUExecutionProvider
* Running on local URL:  http://0.0.0.0:7860
* To create a public link, set `share=True` in `launch()`.

如果浏览器没有自动打开,手工访问 http://localhost:7860/ 即可:

pdf2zh-webui.jpg

也可以使用 Docker 命令启动 Web 服务:

$ docker run -d -p 7860:7860 byaidu/pdf2zh

在线服务

我们也可以通过以下几个在线服务免安装体验 PDFMathTranslate 的功能:

免费服务的计算资源有限,因此请避免滥用它们。