自 ChatGPT 3.0 以来,AI 翻译功能以前所未有的准确度横扫翻译市场。因为本博客曾经一度使用过英文写作,所以不少文章存在中英语混用现象,趁着 Deepseek 即将涨价,我花了几分钟时间,将本博客所有文章翻译为了英文。同时借助 Github Actions,实现全自动翻译。
翻译前期工作
- 确认自己的 HUGO 版本和主题已支持 i18n 功能
只要不是特别古董的 hugo 版本(低于0.60.0),应该都支持这个,而且大部分主流 hugo 主题也都默认可以支持 i18n 功能。可以在主题 yaml/toml 文件中查看是否有多语言配置。
- 安装 python
在 python 官网 下载 Windows 版本然后安装。
- 安装必要依赖
用 Windows 终端或者 Git bash 之类的命令行工具安装 requests 和 openai 两个库,前一个用于发送 HTTP 请求,后一个用于 deepseek api 配置(deepseek 使用标准 openai 格式)。
1
2
| pip install requests
pip install openai
|
- 申请 deepseek api
到 deepseek 开放平台 创建 api KEY,创建时复制保存好。 (每个新手机号码注册时都会送 10 元余额,如果没有,可以自己充 10 块钱。)
编写 python 脚本并运行
这里可以直接使用我的脚本,将下边代码保存为 translate.py 文件,然后在 py 文件保存的位置,运行命令行工具,输入 python translate.py
即可开启自动翻译。使用说明:
- 替换 “sk-xxx” 为你自己的 deepseek api KEY
- 替换 “D:/hugo/lawtee/content/” 为你自己的 Hugo 文章目录
- 固定翻译映射主要是解决文章分类可能存在中英文字义差异问题,可以根据实际情况使用。
- MAX_TOKENS 可以自行修改,也可以不改,如果文章普遍很短,可以改小点。
- 这里的翻译逻辑是,将所有 hugo content 目录中的文件夹遍历,对文件夹中只有 index.md 的,将其翻译为 index.en.md ,如果已经同时存在 index.md 和 index.en.md 则不翻译。
查看代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
| import os
import re
from openai import OpenAI
# 配置
API_KEY = "sk-xxx" # 替换为你的DeepSeek API密钥
CONTENT_DIR = "D:/hugo/lawtee/content/posts" # Hugo的博客文章目录路径
MAX_TOKENS = 8192 # API的最大token限制
CHUNK_SIZE = 6000 # 每块的最大token数量(根据实际情况调整)
# 固定翻译映射
CATEGORY_TRANSLATIONS = {
"生活": "Life",
"法律": "Law",
"社会": "Society"
}
# 初始化OpenAI客户端
client = OpenAI(api_key=API_KEY, base_url="https://api.deepseek.com")
# 翻译函数
def translate_text(text):
response = client.chat.completions.create(
model="deepseek-chat",
messages=[
{"role": "system", "content": "You are a helpful translator. Translate the following text into English."},
{"role": "user", "content": text},
],
max_tokens=MAX_TOKENS, # 指定最大输出长度
stream=False
)
return response.choices[0].message.content
# 分块翻译函数
def translate_long_text(text, chunk_size=CHUNK_SIZE):
chunks = [text[i:i + chunk_size] for i in range(0, len(text), chunk_size)]
translated_chunks = []
for chunk in chunks:
try:
translated_chunk = translate_text(chunk)
translated_chunks.append(translated_chunk)
except Exception as e:
print(f"分块翻译失败,错误:{e}")
translated_chunks.append("") # 如果失败,添加空字符串
return "".join(translated_chunks)
# 提取并处理Front Matter
def process_front_matter(content):
# 匹配Front Matter部分
front_matter_match = re.search(r"---\n(.*?)\n---", content, re.DOTALL)
if not front_matter_match:
return content # 如果没有Front Matter,直接返回原文
front_matter = front_matter_match.group(1)
body = content[front_matter_match.end():].strip()
# 处理Front Matter中的categories字段
if "categories:" in front_matter:
for cn_category, en_category in CATEGORY_TRANSLATIONS.items():
front_matter = front_matter.replace(f"categories: {cn_category}", f"categories: {en_category}")
# 重新组合Front Matter和正文
return f"---\n{front_matter}\n---\n\n{body}"
# 遍历content目录
for root, dirs, files in os.walk(CONTENT_DIR):
# 检查是否存在index.md但不存在index.en.md
if "index.md" in files and "index.en.md" not in files:
index_md_path = os.path.join(root, "index.md")
index_en_md_path = os.path.join(root, "index.en.md")
# 读取index.md内容
with open(index_md_path, "r", encoding="utf-8") as f:
content = f.read()
# 处理Front Matter
content = process_front_matter(content)
# 分块翻译内容
try:
translated_content = translate_long_text(content)
# 保存翻译后的内容为index.en.md
with open(index_en_md_path, "w", encoding="utf-8") as f:
f.write(translated_content)
print(f"已翻译并保存:{index_en_md_path}")
except Exception as e:
print(f"翻译失败:{index_md_path},错误:{e}")
print("批量翻译完成!")
|
提示
AI 翻译速度整体来说不会很快,但 deepseek 已经是目前最快的了。 我 300 多篇文章 80 万汉字大概翻译了五个多小时,消耗 1.7 元 api 。
Hugo 的 frontmatter 部分有可能翻译失败,特别是 frontmatter 与正文衔接处,可能翻译后的结果会丢掉 ---
,翻译后建议人工排查下,大概每几篇文章就有可能出现一次。也可以在本地用 hugo server 调试是否存在错误。
启用英文站点
参照 hugo 主题配置启用。例如本站 hugo.yaml 设置如下:
- languageCode 设置为 zh-Hans 代表网站默认为中文,对于所有 index.md 文件,默认网址前缀是
https://lawtee.com
,对于所有 index.en.md 文件,网址前缀为 https://lawtee.com/en
,其他语言同理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| baseurl: https://lawtee.com
languageCode: zh-Hans ## 默认为中文
languages:
en:
languageName: English
title: Lawtee
weight: 2
params:
sidebar:
subtitle: Legal Practitioners
zh-cn:
languageName: 中文
title: 法律小茶馆
weight: 1
params:
sidebar:
subtitle: 基层法律工作者
|
到这里,本地实现 AI 翻译功能已经设置完毕。后续需要翻译时,只需要在本地重新运行 python translate.py
即可自动翻译新的 index.md 文件。如果嫌麻烦,可以参照 我这篇文章 的设置,在本地设置一键启动自动翻译。另外也可以通过 Github Actions 强大的 CI/CD 工具实现自动翻译。区别在于,本地翻译结果可以先查看是否存在 Bug 再提交构建;而通过 Github Actions 自动翻译时则需要等构建后才知道是否有 Bug。
设置 Github Actions 自动翻译
- 在 Hugo 仓库中创建一个工作流文件 translate.yml,例如
D:/hugo/lawtee/.github/workflows/translate.yml
),用于定义自动化任务,模板如下。请根据自己实际修改分支、用户名等信息。
查看代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
| name: Translate Markdown Files
on:
push:
branches:
- master # 在 master 分支推送时触发
jobs:
translate:
runs-on: ubuntu-latest
steps:
# 1. 检出代码
- name: Checkout repository
uses: actions/checkout@v3
with:
persist-credentials: true
# 2. 设置 Python 环境
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.9'
# 3. 安装依赖
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install openai
# 4. 运行翻译脚本
- name: Run translation script
env:
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
run: |
python translate.py
# 5. 提交更改
- name: Commit and push changes
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git config --global user.name "USERNAME" # 你的 Github 用户名
git config --global user.email "EMAIL@EMAIL.com" # 你的 Github 邮箱
git add .
git diff --quiet && git diff --staged --quiet || git commit -m "Auto-translate Markdown files"
git push
|
在 Github 仓库设置中添加仓库密钥,Settings -> Secrets and variables -> Actions
,名称为 DEEPSEEK_API_KEY
,内容为自己的 Deepseek api KEY。( Github 禁止直接在文件中上传 API KEY,只能在仓库设置中添加)
在 Github 仓库设置 Actions -> general
中打开 Workflow permissions
的读写权限和创建、提交权限。
推送 translate.yml 和 translate.py 到 Github 仓库。
- 注意将 translate.py 中的
CONTENT_DIR = "D:/hugo/lawtee/content/posts"
修改为仓库地址。例如:CONTENT_DIR = "content/posts"
。 - 注意将 translate.py 中的
API_KEY = "sk-xxx"
修改为 API_KEY = os.getenv("DEEPSEEK_API_KEY")
。
如此,Github Actions 便会自动为新添加的 index.md 文档自动将其翻译为 index.en.md。
提示
建议首次使用 AI 批量翻译时全程在本地操作,方便调试,后续再使用 Github Actions 自动翻译。我在本地测试时发现批量翻译会偶发 frontmatter 翻译出错,但单篇文章翻译时暂未遇到出错现象。