Evaluating Large Language Models Trained on Code(论文)
Mark Chen, Jerry Tworek, Heewoo Jun, Qiming Yuan 等(OpenAI;部分作者标注工作完成于 OpenAI)。Evaluating Large Language Models Trained on Code。2021-07。arXiv:2107.03374。Chen、Tworek、Jun、Yuan 为通讯作者。正文写明:若干早期 Codex 模型的后代驱动 GitHub Copilot 与 OpenAI API 中的 Codex。
摘要
引入 Codex:在 GitHub 公开代码上微调的 GPT 语言模型,并研究其写 Python 的能力。独立的生产版本驱动 GitHub Copilot。新评测集 HumanEval 衡量「根据文档字符串合成程序」的功能正确性:本模型解出 28.8% 的题目,GPT-3 为 0%,GPT-J 为 11.4%。反复从模型采样是应对难题的有效策略:每题 100 个样本可解出 70.2%。限度包括:长操作链的文档字符串;把操作绑定到变量。最后讨论部署强大代码生成技术的更广泛影响:安全、安保与经济。
1 引言
序列预测模型已成为多模态的通法。代码出现在大规模数据集里之后,语言模型开始推进程序合成。GPT-3 已能从 Python 文档字符串生成简单程序,尽管并未为代码生成专门训练。假设专门的 GPT(Codex)能擅长多种编码任务。
本文聚焦:根据文档字符串生成独立的 Python 函数,用单元测试自动判对错。这与自然语言生成靠启发式或人工打分不同。为此手写 164 道带单测的编程题,覆盖语言理解、算法与简单数学,部分接近初级面试题。数据与评测框架发布于 https://github.com/openai/human-eval。
单样本:12B Codex 解 28.8%,300M 解 13.2%;6B GPT-J 11.4%;各档 GPT 接近 0%。再在「正确实现的独立函数」上微调得到 Codex-S,单样本 37.7%。每题 100 个样本并选出能过单测的,Codex-S 达 77.5%;若不能跑单测、只取平均 log 概率最高的样本,为 44.5%。真实编程通常是迭代与修复缺陷,多采样是对这一过程的近似。
2 评测框架
2.1 功能正确性与 pass@(k)
代码生成主流曾用与参考解的精确或模糊匹配(BLEU)。匹配无法覆盖「功能等价但写法不同」的大空间。本文采用功能正确:样本通过一组单元测试即算对。这与测试驱动开发、合并代码前先通过单元测试的工程习惯一致。
pass@(k):每题生成 (k) 个样本,任一通过则该题算解出,再报解出比例。直接用 (k) 个样本方差大。改为每题生成 (n\ge k) 个(本文 (n=200),(k\le 100)),设 (c) 个通过,用无偏估计
[ \mathrm{pass@}k=\mathbb{E}_{\text{Problems}}\left[1-\frac{\binom{n-c}{k}}{\binom{n}{k}}\right] ]
用 (1-(1-\hat p)^k) 是有偏的。后文显示:功能不等价的错误解与正确解的 BLEU 分布大量重叠,优化 BLEU 不等于优化功能正确。
2.2 HumanEval
164 道手写题。每题含签名、文档字符串、函数体与若干单测,平均 7.7 个测试。必须手写:模型训在 GitHub 很大一部分上,网上已有各种题解(例如 APPS 所用的 Codeforces)。
2.3 沙箱
公开程序意图未知,生成程序常是错的,执行有安全风险。因此评测在隔离环境里执行,并限制网络访问。目标:防止修改宿主机、持久化、访问敏感资源或外泄数据。
3 代码微调
在最多 12B 参数的 GPT 上微调得到 Codex。
数据。 2020 年 5 月,GitHub 上 5400 万个公开仓库;小于 1MB 的不重复 Python 文件 179GB。过滤可能自动生成、平均行长 >100、最大行长 >1000、字母数字比例过低的文件后,159GB。
方法。 原假设从 GPT-3 初始化会更好;未观察到最终提升,可能因为微调数据已经很大。但从 GPT 初始化收敛更快,后续实验仍用。学习率与对应 GPT 相同;175 step 线性 warmup + 余弦衰减;共 1000 亿 token;Adam。词表基于 GPT-3,另加不同长度空白的专用 token,代码大约少用 30% token。采样遇到 \nclass、\ndef 等停止,以免继续写下一个函数。nucleus (p=0.95)。
结果。 代码微调后的测试损失仍近似幂律。pass@(k) 的最优温度随 (k) 升高:多样性对大 (k) 有利。12B:表 1 中 pass@1 / 10 / 100 为 28.81% / 46.81% / 72.31%。GPT-J-6B 约等于 Codex-300M;Tabnine 免费最大模型约等于 Codex-12M。
不能跑单测、只能返回一个补全时:选平均 token log 概率最高的样本好于随机;按总和 log 概率选可能比随机更差。
APPS。 Codex 未在 APPS 上微调。文档字符串末加一条输入输出示例作格式提示(文中称 1-shot)。12B 与在 APPS 上微调的 GPT-Neo 可比。竞赛题常写出正确但不够快的解。
4 监督微调(Codex-S)
GitHub 上还有类、配置、脚本、数据文件,与「从文档字符串合成函数」分布不同。再从竞赛/面试站(约 1 万题)以及带 CI 的仓库(追踪函数调用得到输入输出)收集「正确的独立函数」,过滤掉 Codex-12B 生成 100 个样本仍无一正确的题。在这些题上再微调,得到 Codex-S。pass@1 平均高约 6.5 个百分点,pass@100 平均高约 15.1 个百分点。
5 文档字符串生成(Codex-D)
把签名 + 参考实现 + 文档字符串拼起来,训练根据代码写文档字符串,便于描述生成代码的意图。人工判「是否唯一且准确描述函数体」:Codex-D-12B 的 pass@1 / pass@10 为 20.3% / 46.5%,低于对应 Codex-S。用反向翻译(生成代码再打文档字符串似然)给多样本排序,差于平均 log 概率。
6 限度
作者自己列出:
- 训练样本效率极差:用了 GitHub 上公开 Python 的很大一部分;入门课学生仍应解出比 Codex-12B 更大的比例。
- 会建议语法错误或未定义的代码,调用作用域外的函数、变量、属性。
- 长、高层、系统级规格越来越吃力。把 13 种确定性字符串操作串进文档字符串,每多一环 pass 率大约降 2–3 倍——人若会做长度为 2 的链,应能做任意长;模型不是。
- 操作与变量的绑定会错,尤其文档字符串里操作和变量都多的时候。
7 更广泛影响与危害分析
潜在用处:上手新代码库、减少上下文切换、让非程序员写规格由模型起草实现、教育。同时有对齐、误用与安全问题。危害分析不是某一产品说明书。
要点:过度依赖(看起来正确,实际并未完成意图,对新手尤甚);不对齐(下一 token 目标会模仿提示里的坏代码,规模变大时这类缺陷可能更明显);偏见;不安全代码(附录 G:生成加密上下文时,相当比例选用明显不安全的参数,如过短 RSA、AES-ECB);对恶意软件门槛的当前评估是「尚未实质降低」,更强模型另说。缓解:文档与 UI、代码审查、过滤、API 审核与限流。
8–9 相关工作与结论
程序合成、CodeBERT / GPT-Neo / APPS 等。结论:在代码上微调的 GPT 可用单测衡量的功能正确性写出 Python 函数;多采样显著提高解出率;限度与部署风险需要单独对待。致谢包括与 GitHub 合作构建 Copilot、Azure 训练基础设施。