从源代码生成LaTeX论文

撰写科学论文通常涉及将算法转换成科学公式,通常采用 LaTeX 格式。这个过程可能很繁琐且耗时,尤其是在大型项目中,因为它需要在代码存储库和 LaTeX 文档之间不断来回切换。

在处理大型算法存储库时,我开始探索简化此工作流程的方法。我的动机源于手动将复杂算法转换为与 LaTeX 兼容的公式效率低下。一个特殊的挑战是确保多个文档之间的一致性,特别是在公式需要频繁更新的项目中。这促使我探索如何通过自动化来简化重复性任务并提高准确性。

对于本文的其余部分,我将同时使用术语“算法”和“科学代码”。本文中的所有图像(封面图片除外)均由作者创建。

1、目标

我的目标是从科学代码过渡到一份全面的文档,该文档介绍代码的用途、定义变量、展示科学公式、包含生成的示例图并演示特定示例的计算。文档将遵循预定义的框架,结合静态和动态元素以确保一致性和适应性。

我设计的框架包括以下结构:

首页

具有视觉吸引力的封面,包含标题和作者等关键细节。

目录

自动生成以提供文档内容的概述。

文档简要说明

概述文档目的和范围的介绍。

算法

专门用于详细记录每个算法的部分。对于每个算法,将包括以下小节:

  • 简介:算法目的和背景的简要概述。
  • 变量:算法中使用的所有变量的明确定义。
  • 公式:从算法中得出的关键公式的介绍。
  • 示例:一个用于说明算法应用的工作示例,并附有生成的图表。
  • 代码:支持可重复性的相应代码片段。

此结构旨在根据记录的算法数量动态调整,确保无论文档的大小或复杂程度如何,都能提供一致且专业的呈现。

2、存储库的结构

为了实现这一目标,一个组织良好的存储库对于实现可扩展且高效的解决方案至关重要。算法计算被分组到一个专用文件夹中,文件使用与算法名称匹配的一致 snake_case 约定命名。

为了确保清晰度和支持重用,示例的初始值和生成的图表存储在单独的文件夹中。这些文件夹遵循与算法相同的命名约定,但具有不同的后缀以区分其用途。这种结构确保所有组件都易于查找并与项目的整体框架保持一致。

3、利用 GPT 实现自动化

该项目的核心是使用 GPT 模型自动将算法转换为 LaTeX。GPT 的优势在于它能够解释通用、变量丰富的代码的结构并将其转换为人类可读的解释和精确格式化的科学公式。这种自动化大大减少了所需的手动工作量,确保了文档之间的准确性和一致性。

对于这个项目,我将利用 OpenAI 的 ChatGPT-4o 模型,该模型以其理解和生成结构化内容的高级能力而闻名。要与 OpenAI 的 API 交互,你必须在环境中设置 OPENAI_KEY。下面是我用来从 GPT 模型获取响应的简单 Python 函数:

import os
from openai import OpenAI
from dotenv import load_dotenv

def ask_chat_gpt(prompt):
    load_dotenv()
    api_key = os.getenv("OPENAI_KEY") or exit("API key missing")
    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

4、工作流程

此代码自动生成 Python 算法的结构化 LaTeX 文档,包括示例、图表和 Python 代码列表。以下是概述:

LaTeX 文档的动态构建流程图

4.1 GPT 的提示创建

本节介绍用于生成 GPT 详细提示的自定义函数,从而实现 LaTeX 文档的自动创建:

make_algo_doc_gpt_prompt:该函数创建提示,指示 GPT 生成 LaTeX 部分,包括介绍、变量描述、公式和示例小节。

make_algo_example_gpt_prompt:该函数生成用于创建 LaTeX 示例部分的提示,包含图表和示例计算。

4.2 Document 生成

这些函数负责处理 GPT 生成的内容并将其保存为 LaTeX 文件:

make_algo_doc:使用 GPT 输出为每个算法生成 LaTeX 文档并将其保存为 .tex 文件的函数。

make_algo_example:为示例部分创建 .tex 文件的函数,包括图表和示例计算。

4.3 LaTeX 汇编

  • 使用 pylatex 库以编程方式创建完整的 LaTeX 文档。
  • 添加标题页、元数据和目录。
  • 包括一个介绍部分,概述了算法及其用途。
  • 为每个算法创建一个章节,其中包含来自 make_algo_docmake_algo_example 的部分、示例图和 Python 代码列表。
# Create and structure the LaTeX document programmatically
doc = Document(documentclass="report")

# Include preamble and metadata
doc.preamble.append(NoEscape(r'\input{algo_docs/init.tex}'))  # Custom preamble
doc.append(NoEscape(r'\input{algo_docs/title_page.tex}'))     # Title page
doc.append(NoEscape(r'\tableofcontents'))  # Table of contents

# Add Introduction Chapter
with doc.create(Chapter('Introduction')):
    doc.append(
        'This document provides an overview of various algorithms, exploring their design, analysis, and application in computational problem-solving. '
        'The aim is to facilitate understanding of their mechanisms and significance across different domains.'
    )

# Add Algorithms Chapter
with doc.create(Chapter('Algorithms')):
    doc.append(
        'This chapter presents detailed analyses of various algorithms, highlighting their theoretical foundations, use cases, and practical insights. '
        'Each algorithm is accompanied by examples and visualizations to illustrate its functionality and potential limitations.'
    )

# Process each Python file in the 'python_code' directory
python_code_dir = "python_code/"
output_folder = "algo_docs/"
plot_folder = "plots/"

for filename in os.listdir(python_code_dir):
    if filename.endswith(".py"):  # Process only Python files
        algorithm_name = filename.replace(".py", "")
        formatted_name = algorithm_name.replace("_", " ").title()

        # Define paths for documentation files and plots
        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"Processing: {filename}")

        # Start a new page for each algorithm
        doc.append(NoEscape(r'\newpage'))

        # Generate documentation and example files with GPT
        make_algo_doc(algorithm_name)
        make_algo_example(algorithm_name)

        # Insert generated LaTeX sections
        doc.append(NoEscape(rf'\input{{{document_path}}}'))
        doc.append(NoEscape(rf'\input{{{example_path}}}'))

        # Insert plot directly after example subsection
        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'Example plot for {formatted_name}.')

        # Add a subsection for the Python code listing
        with doc.create(Subsection('Code Listing')):
            doc.append(NoEscape(rf'\lstinputlisting[language=Python]{{{python_code_path}}}'))

        # Add a page break for clarity
        doc.append(NoEscape(r'\clearpage'))

# Generate the LaTeX file
tex_file = "programmatic_report"
doc.generate_tex(tex_file)

# Compile the LaTeX file to a PDF
subprocess.run(["pdflatex", f"{tex_file}.tex"])

4.4 PDF 编译

组装好的文档已保存并使用 pdflatex 编译成精美的 PDF。

简单的首页
目录

5、制作有效的提示:核心挑战

该项目最具挑战性的方面之一是设计和改进用于与 GPT 交互的提示。整个过程的成功取决于 GPT 生成的输出的质量,因此创建有效的提示是一项需要大量时间和实验的关键任务。

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

  • 清晰度:精确引导 GPT 生成结构化的 LaTeX 内容,包括章节、小节和数学方程式,同时不留下所需格式的歧义。
  • 适应性:确保提示可以处理各种算法,从简单计算到复杂实现。
  • 一致性:实现可靠、格式良好且准确的输出,即使对于边缘情况或非常规代码结构也是如此。

为了应对这些挑战,我实施了动态提示。这种方法涉及以编程方式生成针对每个文件内容的提示。通过为 GPT 提供相关上下文和具体说明,动态提示可确保输出既准确又适合给定算法的上下文。

经过多次迭代,提示变得精确而灵活,形成了自动化过程的基础。

从算法生成 LaTeX 代码的提示示例:

Generate LaTeX code from the provided Python code. Follow these guidelines:

1. **Document Structure**:
- Start with `\\section{}` for the algorithm title.
- Add a `\\subsection{Introduction}` for a brief overview of the algorithm.
- Include a `\\subsection{Variables}` section that lists all variables with descriptions, using subscript notation (e.g., `v_{\\text{earth}}`).
- Add a `\\subsection{Formulas}` section presenting the code's logic as LaTeX formulas. Use subscripted symbols for variable names instead of copying Python variable names directly.

2. **Formatting Rules**:
- Ensure that the output includes **only** the LaTeX content, without `\\documentclass`, `\\usepackage`, `\\begin{document}`, `\\end{document}`, or any unrelated text.
- Do **not** include the triple backticks (e.g., ```latex or ```).
- Properly close all LaTeX environments (e.g., `\\begin{align*}...\\end{align*}`).
- Ensure all brackets, parentheses, and braces are matched correctly.
- Maintain consistent subscript notation for all variables.

3. **Important Notes**:
- **Do not** include any text or explanations outside the LaTeX code.
- Only the relevant LaTeX content for the `\\section`, `\\subsection`, `\\begin{align*}`, and `\\end{align*}` parts should be generated.
- Ensure no extra or unrelated LaTeX sections are added.

6、示例:霍曼转移轨道计算

以下演示了如何使用 GPT 生成的 LaTeX 代码记录霍曼转移轨道计算算法。该算法计算将航天器从地球轨道转移到火星轨道所需的速度变化 (delta-v)。以下是该算法的 Python 实现:

def calculate_hohmann_transfer(earth_orbit_radius, mars_orbit_radius):
    # Gravitational constant for the Sun
    mu_sun = 1.32712440018e20

    # Orbital velocities of Earth and Mars
    v_earth = np.sqrt(mu_sun / earth_orbit_radius)
    v_mars = np.sqrt(mu_sun / mars_orbit_radius)

    # Semi-major axis of the transfer orbit
    transfer_orbit_semi_major_axis = (earth_orbit_radius + mars_orbit_radius) / 2

    # Transfer orbit velocities at Earth and Mars
    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)

    # Delta-v at Earth and Mars
    delta_v_earth = v_transfer_at_earth - v_earth
    delta_v_mars = v_mars - v_transfer_at_mars

    # Total delta-v for the transfer
    total_delta_v = abs(delta_v_earth) + abs(delta_v_mars)

    return delta_v_earth, delta_v_mars, total_delta_v

使用 GPT 提示符和此代码,我为文档生成了 LaTeX 子节。以下是创建的组件:

6.1 算法简介

GPT 生成了算法目的的 LaTeX 解释,详细说明了它如何计算速度变化以实现高效的行星际转移。

算法简介。GPT 模型生成的 LaTeX 代码

6.2 变量定义

GPT 提供了算法中使用的所有变量的清晰解释。

算法的变量定义。GPT 模型生成的 LaTeX 代码

6.3 公式

GPT 将算法中使用的关键公式格式化为 LaTeX。

算法中使用的公式。GPT 模型生成的 LaTeX 代码

6.4 示例部分

使用示例值,GPT 为工作示例生成了 LaTeX 代码。

使用示例值和算法作为输入的示例片段。GPT 模型生成的 LaTeX 代码

6.5 绘图生成

使用示例值生成了转移轨道的图,并将其包含在 LaTeX 文档中。

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

6.6 代码清单

算法的源代码已附加到文档末尾以保证完整性。

代码清单位于章节末尾(部分视图)

7、结果和挑战

该系统的初步实验很有希望。使用 Python 和 GPT-4,我成功地将几种算法自动转换为 LaTeX 文档。这个概念验证 (POC) 的结果可以在我的 GitHub 存储库中探索,该项目的所有方面都可以在这里查看。

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

虽然初步结果很有希望,但这个过程并非没有挑战和价值

一路走来,不断获得新见解:

  • 格式化挑战:GPT 有时会生成不正确的 LaTeX 格式,导致 PDF 转换过程中出现错误。虽然这个问题很少见,但我尝试了一种解决方案:将 LaTeX 代码重新提交给 GPT,并要求其修复格式。虽然这种方法始终成功,但它并未作为工作流程的一部分实施。
  • 代码注释:在代码中添加清晰的注释有助于 GPT 更好地理解上下文并生成更准确的 LaTeX 输出。
  • 结果不一致:GPT 有时会为相同的代码和提示生成不同的输出,强调其固有的可变性和仔细测试的重要性。
  • 制作有效的提示:编写有效的提示具有挑战性。在提示中加载过多的细节(例如示例)通常会导致 GPT 错过较小的元素,例如格式或结构。我发现逐步分解说明并使用非常小的、有针对性的示例有助于 GPT 表现更好。保持提示简洁、结构化并带有项目符号,可确保清晰理解和执行每个关键指令。
  • 领域特定术语:针对专业术语对 GPT 进行微调是一个需要进一步改进以提高准确性的领域。
  • 变量定义:保持算法和示例中的 LaTeX 变量定义一致是一项挑战。将 GPT 生成的变量定义添加到后续提示有助于保持一致性。

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

8、改进方向

  • 开发验证机制

根据已知标准或基准对生成的公式进行交叉引用,以确保准确性和一致性。

  • 扩展用例

在更大、更多样化的数据集上测试工作流程,以提高各个科学领域的可扩展性和适应性。

  • 增强可视化文档

通过使用 GPT 生成 XML 文档或类似格式,整合其他可视化元素(例如流程图)。

  • 使用 GPT 生成图表和示例

扩展 GPT 的功能以直接创建示例图表,减少对外部绘图工具的依赖。

  • 尝试不同的 GPT 模型

到目前为止,我主要使用 ChatGPT-4,因为它易于访问,但需要进一步研究以确定此任务的最佳模型。探索针对技术内容量身定制的模型或将检索增强生成 (RAG) 方法与各种科学论文的数据库结合起来可以提高准确性和相关性。

  • 从概念验证 (POC) 过渡到最小可行产品 (MVP)

通过添加强大的错误处理、可扩展性功能和以用户为中心的改进,将项目从概念验证发展为最小可行产品。

9、结束语

该项目证明了 GPT 模型可以自动创建结构化 LaTeX 文档,从而大大减少所需的手动工作量。它成功地生成了专业质量的输出,包括公式、图表和结构化示例。然而,结果不一致、格式问题和 GPT 输出的多变性等挑战凸显了改进的必要性。动态提示、更好的代码注释和迭代验证等策略有助于解决这些问题,但仍需要一些人工监督。

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


原文链接:From Code to Paper: Using GPT Models and Python to Generate Scientific LaTeX Documents

汇智网翻译整理,转载请标明出处