字节笔记本

2026年2月22日

使用 OpenAI GPT-4o 翻译 LaTeX 书籍完整指南

本文介绍如何使用 OpenAI GPT-4o API 将一本用 LaTeX 编写的斯洛文尼亚语书籍《欧几里得平面几何》翻译成英语,同时保持所有 LaTeX 命令不变。

项目概述

该项目演示了如何翻译 Milan Mitrović 撰写的《欧几里得平面几何》一书。核心思路是:

  1. 将书籍分割成约一页长度的文本块
  2. 使用 GPT-4o 逐个翻译每个文本块
  3. 将翻译后的文本块重新拼接成完整书籍

技术实现

1. 读取和分块

首先使用 tiktoken 计算文本的 token 数量,然后以双换行符作为分隔符将文本分割成块:

python
from openai import OpenAI
import tiktoken

client = OpenAI()
tokenizer = tiktoken.get_encoding("o200k_base")

with open("data/geometry_slovenian.tex", "r") as f:
    text = f.read()

# 以双换行符分割
chunks = text.split('\n\n')

2. 智能分块策略

为了提高翻译的连贯性,将短文本块合并成约 15000 token 的大块:

python
def group_chunks(chunks, ntokens, max_len=15000, hard_max_len=16000):
    batches = []
    cur_batch = ""
    cur_tokens = 0
    
    for chunk, ntoken in zip(chunks, ntokens):
        if ntoken > hard_max_len:
            print(f"Warning: Chunk discarded for being too long ({ntoken} tokens)")
            continue

        if cur_tokens + 1 + ntoken <= max_len:
            cur_batch += "\n\n" + chunk
            cur_tokens += 1 + ntoken
        else:
            batches.append(cur_batch)
            cur_batch = chunk
            cur_tokens = ntoken
            
    if cur_batch:
        batches.append(cur_batch)
        
    return batches

3. 翻译函数

关键技巧是提供一个示例翻译(包含原文和译文),帮助模型理解只翻译文本内容而保留 LaTeX 命令:

python
def translate_chunk(chunk, model='gpt-4o',
                    dest_language='English',
                    sample_translation=(
                        r"\poglavje{Osnove Geometrije} \label{osn9Geom}",
                        r"\chapter{The basics of Geometry} \label{osn9Geom}")):
    prompt = f'''Translate only the text from the following LaTeX document into {dest_language}. Leave all LaTeX commands unchanged
    
"""
{sample_translation[0]}
{chunk}"""

{sample_translation[1]}
'''
    response = client.chat.completions.create(
        messages=[{"role": "user", "content": prompt}],
        model=model,
        temperature=0,
        top_p=1,
        max_tokens=15000,
    )
    result = response.choices[0].message.content.strip()
    result = result.replace('"""', '')
    return result

4. 批量翻译

顺序翻译(约需 2-3 小时):

python
dest_language = "English"
translated_chunks = []

for i, chunk in enumerate(chunks):
    print(f"{i+1} / {len(chunks)}")
    translated_chunks.append(translate_chunk(chunk, model='gpt-4o', dest_language=dest_language))

result = '\n\n'.join(translated_chunks)

with open(f"data/geometry_{dest_language}.tex", "w") as f:
    f.write(result)

5. 并行翻译优化

使用 ThreadPoolExecutor 加速翻译过程:

python
from concurrent.futures import ThreadPoolExecutor, as_completed

def translate_chunk_wrapper(chunk, model='gpt-4o', dest_language='English'):
    return translate_chunk(chunk, model=model, dest_language=dest_language)

dest_language = "English"
translated_chunks = []

with ThreadPoolExecutor(max_workers=5) as executor:
    futures = {executor.submit(translate_chunk_wrapper, chunk, 'gpt-4o', dest_language): i 
               for i, chunk in enumerate(chunks)}
    
    for future in as_completed(futures):
        i = futures[future]
        try:
            translated_chunk = future.result()
            translated_chunks.append(translated_chunk)
            print(f"Chunk {i+1} / {len(chunks)} translated.")
        except Exception as e:
            print(f"Chunk {i+1} failed with exception: {e}")

result = '\n\n'.join(translated_chunks)

with open(f"data/geometry_{dest_language}.tex", "w") as f:
    f.write(result)

关键技术要点

  1. Prompt 设计:通过提供示例翻译(sample_translation),让模型理解只翻译自然语言文本,保留所有 LaTeX 命令

  2. 分块策略:使用双换行符作为分隔符,既保持文本连贯性,又确保单个块不超过模型 token 限制

  3. 温度设置temperature=0 确保翻译结果的一致性和可重复性

  4. 并行处理:使用 ThreadPoolExecutor 可以显著缩短翻译时间

应用场景

该技术可应用于:

  • 学术论文翻译
  • 技术文档本地化
  • 书籍多语言版本制作
  • 保留格式的专业文档翻译

项目链接

分享: