几十年来,能够自己编写代码的 AI 一直是计算机科学领域的“圣杯”。我们在科幻作品中曾瞥见过这样的未来,但在现实中,教会机器掌握编程所需的 逻辑创造力精确性 一直是一项巨大的挑战。

当 GPT-3 这样的大型语言模型 (LLM) 出现时,它们展现出一种令人惊讶、尽管还很初级的能力——能够根据自然语言提示生成简单的代码片段,即便它们并没有经过专门的代码训练。

这引出了一个发人深省的问题:** 如果我们用一个强大的语言模型,并且专门在代码上对其进行训练,会发生什么?**

这正是 OpenAI 在 2021 年发表的里程碑论文《评估在代码上训练的大型语言模型》背后的核心思想。该论文介绍了 Codex——一个在 GitHub 海量公开代码库上进行微调的 GPT 模型,也是广受欢迎的 GitHub Copilot 工具的核心驱动力。

研究人员不仅构建了一个模型,还提出了一种全新的评估方法,超越了模糊的文本匹配,直接关注真正重要的问题:** 代码是否真的可运行?**

在本文中,我们将深入探讨这篇论文:

  • Codex 是如何训练的。
  • 研究人员如何构建 HumanEval 基准来评估“功能正确性”。
  • 为什么生成多种可能的解决方案能显著提升解题能力。
  • Codex 仍存在哪些局限。
  • 将这样的工具释放到世界,会带来哪些深远而广泛的影响。

如何评价 AI 的代码?

在讨论 Codex 之前,我们需要先解答一个根本问题:** 如何评估 AI 生成的代码?**

传统上,自然语言处理中的生成模型会使用 BLEU 分数等指标来评估——它通过比较输出与参考文本,衡量词语的重叠度。

但这种方法在代码领域却完全失效。

考虑两个将数字翻倍的 Python 函数:

1
2
3
4
5
6
7
8
# 参考解决方案
def double(x):
    return x * 2

# AI 生成的解决方案
def double_number(num):
    result = num + num
    return result

这两个函数在功能上完全等价——对所有输入都返回相同结果。
但是,BLEU 会因为变量名和结构不同而给它们很低的评分;反之,它可能会给文本相似度很高但功能上是错误的代码打高分。

Codex 的作者提出了一个更实用的评估指标:** 功能正确性**——代码是否能通过测试?

他们通过 单元测试来评估这一点,采用了一个名为 pass@k 的指标,其定义为: 如果模型为一个问题生成 k 个不同的解决方案,其中至少有一个通过所有单元测试的概率。

形式化定义如下:

\[ \text{pass@k} := \mathbb{E}_{\text{Problems}} \left[ 1 - \frac{\binom{n-c}{k}}{\binom{n}{k}} \right] \]

pass@k 无偏估计量的方程。

其中:

  • \(n\) = 生成的样本总数
  • \(c\) = 正确样本的数量
  • \(k\) = 每个问题允许生成的样本数

这个公式给出了在 k 次尝试内解决一个问题的无偏概率。

一个用于计算 pass@k 无偏估计的数值稳定 Python 脚本。


HumanEval: 一个真实的评测基准

为了应用这一指标,团队构建了 HumanEval——一个包含 164 个手写编程问题的数据集,内容包括:

  • 函数签名,
  • 文档字符串 (自然语言问题描述) ,
  • 单元测试。

为什么要手写?因为 Codex 训练于海量的 GitHub 公开代码,他们想避免测试题与训练集重复。

题目涉及语言理解、算法与基础数学——类似于简单的软件面试题。

HumanEval 数据集中的三个示例问题,展示了提示 (白色) 和正确的模型补全 (黄色) 。这些问题的难度各不相同。

所有代码都在一个使用 gVisor 构建的安全沙箱中运行,从而防止恶意或不安全的代码危害主机或网络。


构建与训练 Codex

从 GPT-3 到 Codex

Codex 源自 GPT-3 模型家族。其思路是: 由于 HumanEval 的文档字符串是英文的,先用强大的自然语言模型作为基础,有助于更好地理解提示。

在 2020 年 5 月,团队从 5400 万个公开 GitHub 仓库中收集了 159 GB 的独立 Python 文件,并过滤掉了自动生成的文件、格式异常的文件,以及代码量过少的文件。

为提高效率,他们修改了 GPT-3 的分词器——为连续的空白符添加特殊标记——从而将 token 数量减少了约 30%。


扩展定律同样适用于代码

GPT-3 的一个重要发现是,更大的模型会在幂律关系下可预测地提升性能。Codex 在代码任务上也表现出相同规律:

一张对数-对数图,显示随着 Codex 非嵌入参数数量的增加,留出代码数据集上的测试损失呈平滑幂律趋势下降。

更大的模型在更多的代码上训练 → 更低的损失 → 更强的性能。


采样: Codex 的秘密武器

虽然单次生成 (pass@1) 很重要,但真正的性能提升来自于生成更多方案 (pass@100) 。

这与人类编程类似——尝试多种思路、修复 bug、不断迭代。


温度 (Temperature) 调优

温度控制输出的随机性:

  • 低温 (如 0.2) → 结果更确定,适合最佳单次猜测。
  • 高温 (如 0.8) → 更具创造性和多样性。

对 Codex 而言:

  • pass@1 → 最佳温度为 T=0.2。
  • pass@100 → 最佳温度为 T=0.8,多样性更重要。

上图显示,对于更多样本数 (k) ,更高的温度能获得更好的 pass@k 率。下图给出了不同 k 值下的最优温度,呈现明显上升趋势。


模型大小与成功率

此图显示了不同规模 Codex 模型的 pass@1 和 pass@100 值。两者均随模型增大而提升,但 pass@100 (橙线) 提高更显著,最大模型超过 70%。

最大的 Codex (120 亿参数) 得分:

  • 28.8% pass@1
  • 72.3% pass@100

无测试情境下的最佳选择

在生产环境 (如 Copilot) 中,不可能展示 100 个输出。没有单元测试 (“Oracle”) 的情况下,团队尝试了以下启发式方法:

  • 最高平均对数概率——选择模型最有信心的方案。
  • 该方法优于随机选择,并且适用于部署。

此图比较了不同的样本选择启发式方法。“Oracle” (蓝) 为理论最高性能,“平均对数概率” (红) 明显优于“随机选择” (紫) 。


BLEU 分数的最终败北

正确与错误方案的 BLEU 分数分布存在大量重叠——证明 BLEU 无法可靠判断代码正确性。

四张图显示在四个 HumanEval 问题上的 BLEU 分布,正确方案 (蓝) 与错误方案 (绿) 大量重叠。


Codex 与其他模型对比

Codex 在同类竞品中优势明显:

此表比较了 Codex、GPT-Neo、GPT-J、TabNine 在 HumanEval 数据集上的 pass@k 值。Codex 始终领先,且随模型增长性能提升明显。

Codex-300M 的得分与 GPT-J-6B 接近——但参数少了 20 倍


Codex-S: 监督微调的成果

原始 GitHub 数据内容杂乱。团队精选了约 5 万个高质量问题,来源包括:

  1. 编程竞赛网站——有严格说明与隐藏测试。
  2. 持续集成项目——通过追踪输入输出生成新问题。

在这些数据上微调 Codex 得到 Codex-S:

  • 12B Codex-S → 37.7% pass@1, 77.5% pass@100

上图比较了 Codex-S (实线) 与 Codex (虚线) ,显示 Codex-S 在所有规模下通过率更高。下图显示排序启发式在 Codex-S 上更有效。

Codex-S 也从更高采样温度中受益:

此图显示在 k>1 时,Codex-S (橙) 最优温度始终高于 Codex (蓝) 。


APPS 数据集的泛化表现

Codex-12B 的成绩与在 APPS 数据集上微调的 GPT-Neo 相当——尽管 Codex 未在 APPS 格式题上训练过。

此表显示 Codex-12B 在 APPS 数据集的各难度下表现,采样与筛选在入门题中作用尤为明显。


Codex-D: 用文档字符串解释代码

反向任务——由代码生成文档字符串——对文档编写与代码理解十分有用。

Codex-D 经过专门训练,人工评分的准确率略低于 Codex-S 的代码生成表现。

此表显示文档字符串生成模型 Codex-D 的人工评分通过率。


局限性

数据利用率低

Codex 虽然训练于数亿行代码,依然难以解决普通计算机专业学生能轻松应对的问题。

长链式指令

随着链式操作增多,性能呈指数掉落:

此图显示在文档字符串中链式组件增多时,Codex-12B 的通过率急剧下降。

变量绑定错误

复杂提示中多变量、多操作会导致绑定错误——错误地将转换应用到错误的变量上。


更广泛的影响与风险

论文对潜在风险进行了深入探讨:

过度依赖

初学者可能会盲目信任 Codex,代码看似正确却可能隐藏 bug 或安全问题。

目标不一致

Codex 仅根据训练数据预测下一个 token——不一定符合用户意图。

如果输入中含有缺陷代码,它会模仿这种错误风格。

此图显示了目标不一致性: 当提示包含细微错误示例时 (橙) ,相比正确示例 (绿) 或无示例 (灰) ,Codex 性能下降。这种差距随模型规模增大而扩大,表明更大的模型更易模仿不良模式。


安全问题

Codex 会继承训练数据中的漏洞。例如,它常建议不安全的加密配置。

此图显示,当请求生成加密密钥时,Codex 模型在不少情况下会建议明显不安全的配置 (如 RSA 密钥长度短于 2048 位) 。


偏见与表达

可能生成反映源数据社会偏见的代码或注释。

经济与劳动力市场影响

或带来生产力提升,但也可能造成岗位转移或工作流程变化。


结论: 编程的新纪元

Codex 是迈向 AI 辅助编程的里程碑,体现了:

  1. 功能正确性 + 单元测试 » 文本匹配评分 (如 BLEU) 。
  2. 扩展定律适用于代码——更大模型带来更好结果。
  3. 高温采样与智能排序在解决难题中具有突破性。
  4. **专门微调 **(Codex-S) 显著提高了效率。

Codex 并非替代程序员——而是增强他们的能力。作为强大的协作伙伴,它能处理样板代码、提供解决方案、加速开发,甚至帮助学习。

但能力伴随责任: 审查与验证输出,警惕过度依赖、目标不一致及偏见。

可信 AI 编程伙伴的旅程已经开始。我们如何整合并监管这些工具,将决定软件开发的下一个篇章。