手记

从代码到论文:用GPT模型和Python自动生成科学LaTeX文档

科学代码自动文档化:一个基于GPT的概念验证,实现高效的工作流程。

这是一张由ChatGPT生成的插图。

简介

写科学论文时常需把算法变成科学公式,通常是用 LaTeX 来排版。这过程通常既繁琐又耗时,尤其是大项目里,需要在这俩之间不停切换。

在处理一个大型算法库时,我开始寻找简化这个工作流程的方法。我的动机来自于手工将复杂算法转换成LaTeX兼容公式时的低效。一个特别的挑战是保证各文档间的一致性,尤其是在那些公式需要频繁更新的项目里。这促使我探索自动化如何简化重复任务并提高准确性。

在接下来的部分,我将交替使用“算法”和“科研代码”这两个术语。本文中的所有图片,除了封面图片外,均由作者创建。

我们要做什么

我的目标是将科学代码转化为一个全面的文档,介绍代码的目的,定义变量,展示科学公式,包含一个生成的例子图,并演示特定示例的详细计算过程。该文档将遵循一个预定义的框架,结合静态和动态元素来,以确保保持一致性和灵活性。

我设计的这个框架包含以下结构:

  1. 封面设计
    一个吸引眼球的封面,包含标题和作者等重要信息。
  2. 目录
    自动生成的目录,提供文档内容概览。
  3. 文档简介
    简要介绍文档的目的和范围。
  4. 算法部分
    详细记录每个算法的章节。每个算法将包括以下子部分:
    - 简要介绍 :算法的目的和背景的简要概述。
    - 变量 :算法中使用的所有变量的清晰定义。
    - 公式说明 :从算法中得出的关键公式的展示。
    - 实例演示 :以具体示例展示算法的应用,附带生成的图表。
    - 代码示例 :支持可重复性的相应代码片段。

以确保此结构设计能够根据需要记录的算法数量动态调整,无论文档大小或复杂度如何,都能始终保持一致和专业的展示。

仓库存构

为了实现这个目标,一个组织良好的存储库是必不可少的,以实现可扩展和高效的解决方案。算法计算被分组到一个专用文件夹中,并按照与算法名称一致的小蛇写法(snake_case)命名文件。

为了确保清晰度和便于重用,示例数据和生成的图表的初始值被存储在单独的文件夹中。这些文件夹遵循与算法相似但带有不同后缀的命名约定,更好地解释了差异。这种结构确保了所有组件易于查找和使用,并保持与项目的整体框架的一致性。

利用GPT自动化

在这个项目的核心是使用GPT模型技术来自动将算法转换成LaTeX格式。GPT的优势在于它能够理解结构复杂且富含变量的代码,并转化为易于人类理解的解释和精准格式化的科学公式。这种自动化显著减少了手动工作量,保证文档的准确性和一致性。

对于这个项目,我将利用OpenAI的ChatGPT-4模型,它以其强大的理解和生成结构化内容的能力著称。您需要在环境中设置OPENAI_KEY。以下是我用于从GPT模型获取响应的简单Python函数:

    导入 os  
    从 openai 导入 OpenAI  
    从 dotenv 导入 load_dotenv  

    def ask_chat_gpt(prompt):  
        load_dotenv()  
        api_key = os.getenv("OPENAI_KEY") or exit("缺少 API 密钥")  
        client = OpenAI(api_key=api_key)  
        response = client.chat.completions.create(  
            model="gpt-4o",   
            messages=[{"role": "user", "content": prompt}]  
        )  
        return response.choices[0].message.content
流程

代码功能简介
此代码自动为Python算法生成结构化的LaTeX文档,其中包括示例、图表和图像,以及Python代码示例。

LaTeX文档的动态构建流程图如下所示,由作者绘制。
动态构建流程图展示如下所示,由作者绘制。

为GPT创建提示

本节介绍了一些用于为生成式预训练模型GPT生成详细提示的自定义函数,从而实现LaTeX文档的自动化生成。

  • make_algo_doc_gpt_prompt:生成 GPT 指令以创建包含介绍、变量描述、公式和示例的 LaTeX 部分的函数。

  • make_algo_example_gpt_prompt:生成 GPT 指令以创建包含图表和示例计算的 LaTeX 示例部分的函数。

生成文档的过程

这些功能用于处理由GPT生成的内容,并将结果保存为LaTeX(一种排版语言)文件。

  • make_algo_doc:利用GPT输出为每个算法生成LaTeX文档并将其保存为.tex文件的函数。
  • make_algo_example:生成包含绘图和示例计算等内容的.tex文件的函数,并将其保存为.tex文件。

LaTeX 搭建

  • 利用 pylatex 库来生成完整的 LaTeX 文档。
  • 添加了标题页、元数据,并生成了目录。
  • 包含了一个介绍部分,总结了算法及其目的。
  • 为每个算法创建一个章节,包括从 make_algo_docmake_algo_example 中获得的内容、示例图表以及 Python 代码列表。
    # 创建并构建 LaTeX 文档
    doc = Document(documentclass="report")

    # 包含前言和元数据
    doc.preamble.append(NoEscape(r'\input{algo_docs/init.tex}'))  # 自定义前言
    doc.append(NoEscape(r'\input{algo_docs/title_page.tex}'))     # 封面
    doc.append(NoEscape(r'\tableofcontents'))  # 目录

    # 添加介绍章节
    with doc.create(Chapter('Introduction')):
        doc.append(
            '本文件提供了各种算法的概览,探讨了它们的设计、分析及其在计算问题解决中的应用。'
            '目的是使读者能够理解这些算法的机制及其在不同领域中的重要性。'
        )

    # 添加算法章节
    with doc.create(Chapter('Algorithms')):
        doc.append(
            '本章详细分析了各种算法,强调了它们的理论基础、应用场景和实用见解。'
            '每个算法都配有示例和可视化,以说明其功能和潜在的限制。'
        )

    # 处理 'python_code' 目录中的每个 Python 文件
    python_code_dir = "python_code/"
    output_folder = "algo_docs/"
    plot_folder = "plots/"

    for filename in os.listdir(python_code_dir):
        if filename.endswith(".py"):  # 只处理 Python 文件
            algorithm_name = filename.replace(".py", "")
            formatted_name = algorithm_name.replace("_", " ").title()

            # 定义文档文件和图像的路径如下
            document_path = os.path.join(output_folder, f"{algorithm_name}_doc.tex")
            example_path = os.path.join(output_folder, f"{algorithm_name}_example.tex")
            plot_path = os.path.join(plot_folder, f"{algorithm_name}_plot.png")
            python_code_path = os.path.join(python_code_dir, filename)

            print(f"正在处理 {filename}")

            # 为每个算法创建新页
            doc.append(NoEscape(r'\newpage'))

            # 使用 GPT 生成文档和示例
            make_algo_doc(algorithm_name)
            make_algo_example(algorithm_name)

            # 插入生成的 LaTeX 部分
            doc.append(NoEscape(rf'\input{{{document_path}}}'))
            doc.append(NoEscape(rf'\input{{{example_path}}}'))

            # 在示例子部分后插入图像
            if os.path.exists(plot_path):
                with doc.create(Figure(position='H')) as figure:
                    figure.add_image(plot_path, width=NoEscape(r'\textwidth'))
                    figure.add_caption(f'示例图像:{formatted_name} 的示意图')

            # 添加代码示例部分
            with doc.create(Subsection('代码示例部分')):
                doc.append(NoEscape(rf'\lstinputlisting[language=Python]{{{python_code_path}}}'))

            # 添加页面分隔符以增强清晰度
            doc.append(NoEscape(r'\clearpage'))

    # 生成 LaTeX 文档
    tex_file = "programmatic_report"
    doc.generate_tex(tex_file)

    # 编译 LaTeX 文件生成 PDF
    subprocess.run(["pdflatex", f"{tex_file}.tex"])

PDF 编译

  • 整理好的文档保存好并使用 pdflatex 编译成一个整洁的 PDF。

一个简单的首页。

目录啦。

编写有效的提示:核心难题

该项目最具挑战性的方面之一是设计和优化与GPT交互的提示。整个过程的成功与否取决于GPT生成输出的质量,这使得设计出有效的提示变得尤为重要,需要花费大量时间和进行多次实验。

达到微妙平衡所需的提示:

  • 清晰性:精确指导GPT生成结构化的LaTeX内容,包括章节、子节和数学方程,确保格式上毫无歧义。
  • 适应性:确保提示可以应对各种算法,从简单的计算到复杂的实现。
  • 一致性:即使对于边缘情况或非传统代码结构,也能保证可靠、格式正确且准确的输出。

为了应对这些问题,我实现了动态提示技术。这种方法是根据每个文件的内容生成相应的提示。通过给GPT提供相关背景信息和具体指令,动态提示确保了输出既准确又符合算法的实际语境。

通过多次迭代,提示逐渐变得精确且灵活,成为自动化过程的基础。
例如,生成LaTeX代码的算法提示词示例:

从提供的Python代码生成LaTeX代码。遵循以下指南:  

1. **文档结构**:  
    - 使用 `\\section{}` 开始,作为算法标题。  
    - 添加 `\\subsection{Introduction}` ,简短介绍这个算法。  
    - 包含 `\\subsection{Variables}` 部分,列出所有变量及其描述,并使用下标符号(例如,`v_{\\text{earth}}`)。  
    - 添加 `\\subsection{Formulas}` 部分,以LaTeX公式形式展示代码的逻辑,使用下标符号表示变量名,而不是直接复制Python变量名。  

2. **格式规则**:  
    - 输出内容应仅包含LaTeX内容,不包含 `\\documentclass`、`\\usepackage`、`\\begin{document}`、`\\end{document}` 或任何无关的文本。  
    - 不要在LaTeX代码外部添加任何文本或解释。  
    - 正确关闭所有LaTeX环境(例如,`\\begin{align*}...\\end{align*}`)。  
    - 确保所有括号、括号和大括号匹配正确。  
    - 保持所有变量的一致下标表示。  

3. **重要注意事项**:  
    - 不要在LaTeX代码外部写任何解释或文字。  
    - 仅生成与 `\\section`、`\\subsection`、`\\begin{align*}` 和 `\\end{align*}` 部分相关的LaTeX内容。  
    - 确保没有添加任何多余的或无关的LaTeX部分。
示例:霍曼转移轨道示例。

以下展示了如何使用GPT生成的LaTeX代码描述霍曼转移轨道算法。该算法计算将航天器从地火转移轨道所需的速度增量(delta-v)。下面是算法的Python实现:

    def calculate_hohmann_transfer(earth_orbit_radius, mars_orbit_radius):  
        # 太阳的引力参数  
        mu_sun = 1.32712440018e20  

        # 地球和火星绕太阳的公转速度  
        v_earth = np.sqrt(mu_sun / earth_orbit_radius)  
        v_mars = np.sqrt(mu_sun / mars_orbit_radius)  

        # 转移椭圆轨道的长半轴  
        transfer_orbit_semi_major_axis = (earth_orbit_radius + mars_orbit_radius) / 2  

        # 地球和火星处的转移轨道速度  
        v_transfer_at_earth = np.sqrt(2 * mu_sun / earth_orbit_radius - mu_sun / transfer_orbit_semi_major_axis)  
        v_transfer_at_mars = np.sqrt(2 * mu_sun / mars_orbit_radius - mu_sun / transfer_orbit_semi_major_axis)  

        # 从地球和火星所需的Δv  
        delta_v_earth = v_transfer_at_earth - v_earth  
        delta_v_mars = v_mars - v_transfer_at_mars  

        # 转移轨道所需的总Δv  
        total_delta_v = abs(delta_v_earth) + abs(delta_v_mars)  

        return delta_v_earth, delta_v_mars, total_delta_v

使用此代码和GPT提示,我生成了文档中的LaTeX小节。下面列出了生成的各个部分。

算法介绍
GPT 生成了一个关于算法目的的 LaTeX 解释,详细说明了该算法的目的是如何计算速度的调整以实现高效的星际航行。

这是一个由GPT模型生成的算法简介,其中包括一些LaTeX代码部分。

变量定义
GPT 对算法中用到的所有变量都做了清晰的解释。

这是算法中变量的定义,这部分LaTeX代码是由GPT模型生成的。

公式
算法中用到的关键公式被格式化成了LaTeX格式。

算法中用到的公式,例如:GPT模型生成的LaTeX代码。

示例
通过示例值,GPT 生成了用于具体示例的 LaTeX 代码。

示例摘录,使用示例值和算法进行输入。由GPT模型生成的示例LaTeX代码片段。

轨道生成
使用示例值生成了该轨道,并将该轨道数据添加到LaTeX文档中。

代码生成的图和示例值,插入到LaTeX文档中。

代码清单
为了完整起见,我们在文档末尾附上了该算法的源代码。

本章最后展示的部分代码(仅供参考)。

结果和挑战

初步的实验结果看起来很有前景。我利用Python和GPT-4成功地将几个算法自动转换成了LaTeX文档。这个概念验证项目的成果可以通过我的GitHub仓库查看,其中包含了项目的各个方面,可供审核。

该仓库包含了完整的Python代码库,包含了一系列自定义函数,用于生成LaTeX文档和创建GPT提示。其中还包括详细的提示,展示了系统如何指导GPT生成结构化且准确的LaTeX内容。此外,仓库还包含了最终输出,包括LaTeX源文件和编译的PDF文件。

尽管初步结果令人鼓舞,过程中也遇到了许多挑战,并且获得了一些有价值的见解。

  • 格式挑战:有时GPT会产生错误的LaTeX格式,导致将LaTeX代码转换为PDF的过程中出现错误。尽管这种情况很少见,我还是尝试了一种解决方法:将LaTeX代码重新提交给GPT并要求它修复格式。这种方法虽然每次都很成功,但并没有被纳入工作流程中。
  • 代码注释:在代码中添加清晰的注释有助于GPT理解上下文并生成更准确的LaTeX输出。
  • 结果不一致:GPT有时会对相同的代码和提示产生不同的输出,这强调了其固有的变化性和测试的重要性。
  • 编写有效提示:编写有效的提示很具挑战性。如果在提示中添加过多细节,例如示例,往往会导致GPT遗漏格式或结构等较小的元素。我发现将指令分解为逐步说明并使用非常小且集中的示例可以帮助GPT表现得更好。保持提示简洁并用项目符号列出,确保每个关键指令都被清晰理解并执行。
  • 特定领域的术语:对GPT进行特定领域的术语微调是需要进一步改进的地方,以提高准确性。
  • 变量定义:保持LaTeX变量定义在算法和示例中一致是一个挑战。将GPT生成的变量定义添加到后续提示中,有助于保持一致性。

尽管存在一些不足,该工作流已大大减少了文档编写所需的时间,通过自动化了大部分过程。虽然仍然需要进行一些小的审阅和调整,但它们仅占之前所需努力的一小部分。这个概念验证展示了无需手动编写LaTeX即可生成精美的文档的潜力,尽管还需要进一步的改进来增强一致性、可扩展性和适应性。迄今为止的结果突显了这种方法的巨大潜力。

改进
  • 开发验证机制
    实现生成公式与已知标准或基准的交叉验证,确保生成的公式准确无误,并且与已知标准或基准保持一致。
  • 扩展用例
    在更大、更多样化的数据集上测试工作流程,以适应各种科学领域的需求。
  • 增强可视化文档
    通过GPT生成XML文档或其他类似格式,纳入更多如流程图等视觉元素。
  • 使用GPT生成图表和示例
    扩展GPT的功能以直接创建示例图表,减少对外部绘图工具的依赖。
  • 尝试不同的GPT模型
    到目前为止,我主要使用的是ChatGPT-4,主要是因为它方便易用,但还需进一步研究以确定最适合此任务的模型。探索针对技术内容优化的模型,或结合检索增强生成(RAG)方法,利用多样化的科学论文数据库。
  • 从概念验证(POC)过渡到最小可行产品(MVP)
    通过增强错误处理、可扩展性和用户友好性,将项目从概念验证演进为最小可行产品。
结论

这个项目证明了GPT模型在自动化生成结构化的LaTeX文档方面的潜力,大大减少了手动工作量。它成功生成了高质量的专业文档,包括公式、图表和结构化示例。然而,如结果不一致、格式问题和输出变异性等问题,凸显了进一步优化的必要性。采用动态提示、更好代码注释和迭代验证等方法已帮助解决这些问题,但仍需要一定程度的人工监督。

尽管存在这些挑战,该工作流程已经显示出明确的好处,简化了文档过程并节省了大量时间。虽然该解决方案还有待完善,但它标志着向自动处理复杂文档任务迈进的重要一步,为未来提高文档准确性铺平了道路。

查看Peder Ward的LinkedIn个人资料页面

GitHub — Peder Ward 的 GitHub 主页

0人推荐
随时随地看视频
慕课网APP