Evaluating Large Language Models Trained on Code
- 关联论文:2107.03374
- 作者:Tom
- 更新:2026-07-29
一句话结论
OpenAI 将 GPT 模型在 GitHub 代码上微调得到 Codex,发现重复采样(repeated sampling)是一种出乎意料地有效的代码生成策略:单个样本只能解决 28.8% 的编程问题,但用 100 个样本时即可解决 70.2%;同期 GPT-3 完全无法通过 HumanEval 的任何题目。
解决什么真问题
在 Codex 之前,代码生成模型的评估缺乏统一标准——常用指标(如 BLEU)无法衡量生成代码的功能正确性。更根本的问题是:LLM 能否真正理解人类意图并写出可执行的程序?本文发布了 HumanEval 数据集(164 道带 docstring 的编程题,每题附有单元测试),并证明仅靠自回归语言模型微调代码,就能解锁有实用价值的代码生成能力,这直接催生了 GitHub Copilot。
核心方法
HumanEval 数据集
每道题由三部分组成:
1. Docstring:描述函数行为的自然语言说明
2. 函数签名:类型注解完整的 Python 函数头
3. 单元测试:验证函数正确性的 assert 语句
评估指标为 pass@k:
$$ \text{pass}@k := \mathbb{P}\left[\text{at least one of }k\text{ samples passes all tests}\right] $$
实际操作中使用不偏估计: $$ \text{pass}@k = \frac{1}{n}\sum_{i=1}^{n}\mathbb{1}\left[\text{cat }k_i \geq c\right],\quad c = \lceil T/k \rceil $$ 其中 $T$ 为总采样数,$k_i$ 为第 $i$ 题通过测试的样本数。
Codex 模型
- 架构:GPT 架构,在 GitHub 代码上微调(Codex-12B 最大)
- 关键发现:从头训练的代码模型(GPT-Neo)几乎无效,但微调GPT 权重后能力急剧涌现
- Codex-S:在 Codex 基础上进一步在「正确实现独立函数的代码」上微调,pass@1 从 28.8% 提升至 37.7%
关键实验与数据
| 模型 | pass@1 | pass@100 |
|---|---|---|
| GPT-Neo-2.7B(代码微调) | 6.4% | 21.3% |
| GPT-J-6B(代码微调) | 11.6% | 27.7% |
| Codex-12B | 28.8% | 70.2% |
| Codex-S-12B | 37.7% | —— |
| GPT-3(baseline,无微调) | ≈0% | ≈0% |
另一个关键发现:100 次采样下,70.2% 的问题能被解决,说明重复采样+测试过滤是工程落地的可行路径。
亮点与局限
亮点
- HumanEval 成为代码 LLM 评估事实标准,后续几乎所有代码生成论文都报告此指标
- pass@k 指标设计精妙:解决了采样评估的不偏估计问题
- 首次证明「LLM 可以在代码上涌现能力」,为 Copilot 奠定基础
- 对采样策略的系统分析,直接影响后续如 AlphaCode、FIM 等工作
局限
- 难以处理长链操作依赖(docstring 描述复杂多步逻辑时性能骤降)
- 变量绑定问题:描述操作与变量绑定关系时容易出错
- 测试用例无法覆盖所有边界情况,安全关键场景仍有风险
- 没有解决代码的「意图理解」问题——模型只是在拟合 GitHub 分布
对工程落地的启发
- 采样+测试过滤是工程可行路径:与其追求更高的 pass@1,不如部署多次采样+自动测试的 pipeline(这成为后续 Code Runner / Copilot 的核心技术)
- ** HumanEval 可作为代码 LLM 的入门评估集**:快速验证模型基础能力
- 代码补全类产品应设计多候选结果展示+轻量测试机制,而非仅返回单一结果
- 依赖代码生成的产品的风险评估:本文提出的安全分析框架(Hazard Analysis)值得参考
与同方向工作的关系
| 工作 | 关系 | 差异点 |
|---|---|---|
| AlphaCode(2022) | 后继 | 引入竞赛级评测,专注推理能力 |
| CodeGeeX | 同代 | 多语言支持,但未建立类似 HumanEval 的标准 |
| PaLM-Coder | 后继 | 更大模型,更多采样 |
| StarCoder | 后继 | 开放权重,The Stack 数据集 |
| GPT-4 代码能力 | 后继 | 多模态输入,更强推理 |
HumanEval 的意义超越了 Codex 本身——它定义了代码 LLM 评估的元问题:不是「生成的代码像真代码吗」,而是「生成的代码能通过测试吗」。这一思路持续影响 2024-2026 年的代码 Agent 评测设计。
适合谁读
- LLM/代码生成方向研究人员:必读,理解 pass@k 设计和 HumanEval 范式
- AI 产品经理/工程师:理解代码 LLM 的能力边界与采样策略
- 安全/合规团队:理解代码生成的潜在风险评估框架
- 对代码 Agent 感兴趣的人:理解 Code Generation → Code Reasoning → Code Agent 的演进起点
工程落地与核查(Jay)
事实核查
- "164 道带 docstring 的编程题":原文(2107.03374)确实说明 HumanEval 包含 164 个人工编写的编程题,此数字有据可查。
- "pass@1 28.8%,pass@100 70.2%":原文 Table 1 给出 Codex-12B 的具体数字,此处引述正确。
- "GPT-3 baseline ≈0%":原文数据与描述吻合,GPT-3 未在代码上微调,此数字合理。
- "Codex-S pass@1 37.7%":原文 Table 1 有 Codex-S 的 pass@1 数字,引述正确。
- "OpenAI 将 GPT 模型在 GitHub 代码上微调":原文明确,GPT-3 初始版与 Codex 为同一时期工作,此描述正确。
工程落地路径与坑
当前价值定位(2026年)
HumanEval 作为基准已严重饱和——GPT-4o / Claude-3.5 / Gemini-2.5 在 HumanEval 上均达 90%+,pass@1 已无区分度。但作为快速入口评估仍有价值,尤其在评测新开源模型(7B~13B 参数量)时。
采样+测试 pipeline 工程实践
输入:问题描述 + n(采样数)
1. 用 LLM 采样 n 个代码完成
2. 对每个完成运行单元测试(超时设 5~10s)
3. 任意一个通过 → pass;全部失败 → fail
4. 收集 fail 样例用于分析
关键工程参数: - n=100 是原文数字,实际生产中可用成本-质量曲线选 n(如 n=10 达 50% 覆盖,n=50 达 65%,边际收益递减) - 超时设置:单次运行超时太短会误杀正确解(递归/复杂算法),太长影响吞吐;建议默认 10s,可配置 - 沙盒执行:代码执行必须隔离,推荐 Docker container + 网络禁用 + 内存限制,防止恶意代码
pass@k 不偏估计的实际坑
原文不偏估计公式在 $T$(总采样数)不够大时方差大。工程上:
- 若 $c = \lceil T/k \rceil = 0$,则 pass@k = 1.0(除非 T=0),这是公式边界,不是真实能力
- 建议用 tatsu-lab/alpaca_eval 的 "pass@k by sampling without replacement" 实现,比原文无偏估计方差更小
HumanEval 之外的工程评测组合
2024-2026 年新基准: - MBPP(Microsoft Programming Prompts):比 HumanEval 简单,适合快速初筛 - LiveCodeBench:动态更新,持续测新题,防止 overfit 到固定题库 - SWE-bench:真实 GitHub issue → 代码修复,难度高,适合 agent 评测 - BigCodeBench:更复杂的指令,区分度更好
已知局限与坑
- HumanEval 过拟合:2023-2024 年大量模型在 HumanEval 上刷榜,真实编程能力被高估;评测新模型建议用 held-out 集
- docstring 质量依赖:HumanEval 题目由人类编写但仍可能有歧义,模型可能对特定表述模式过拟合
- 多轮对话/跨文件上下文:HumanEval 只测单函数生成,真实代码助手需要多轮修改+跨文件理解,HumanEval 完全测不到这个维度
- 安全风险:生产环境跑 LLM 生成的代码执行必须有沙盒,未隔离的执行历史上已有多个 RCE 案例(2023 GitHub Copilot 社区报告)
推荐验证清单
- [ ] 用 HumanEval + MBPP + LiveCodeBench 三合一快速评测新模型,不用单一基准
- [ ] 采样 pipeline 测通过率曲线,找到成本-质量拐点(通常是 n=20~50)
- [ ] 生产代码执行必须走沙盒,禁止在主进程直接 eval/exec
- [ ] 分析 fail 样本:若是 "差一点就对了"(边界条件)vs "完全跑不通"(语义理解错误),两类失败处理策略完全不同