LLM 写的代码到底对不对?一篇把代码 benchmark 打回原形的解读:EvalPlus / HumanEval+

  • 关联论文:2305.01210
  • 作者:spark
  • 更新:2026-07-25

一句话结论

通过大规模自动补充测试用例,把 HumanEval 的 164 道题从「每个题 7-10 个测试用例」扩成「每个题平均 764+ 个测试用例(>80× 增幅)」,得到 HumanEval+ —— 结果令业界大跌眼镜:所有主流 LLM 的真实代码正确率比原榜单平均下降 19.3-28.9 个百分点,甚至部分模型的相对排名都发生了反转

它解决了什么真问题

2023 年随着 Codex、ChatGPT、Codestella 等大规模代码 LLM 兴起,评测代码生成质量的基准——HumanEval(含 164 个 Python 编程题,每题配 7-10 个单元测试)——几乎被用「刷分」的方式固化:

  • 模型在 HumanEval 上得分从 Codex 时代的 28% 涨到 GPT-4 的 80%+,曲线一路向上。
  • 但工业界使用 LLM 写代码时,真实失败率远高于榜单所暗示
  • 接踵而来的疑虑:榜单分数的水分是来自「题目太简单」、还是「测试用例太弱」?

更具体的担忧是:

  1. HumanEval 每题只有 7-10 个 test case,很多 bug 在这 7-10 例下看不出来
  2. LLM 可能在测试用例覆盖不到的分支上写错代码——这是工业 grade 不可接受的;
  3. 部分模型故意或巧合地拟合了题目中的 test case,造成过拟合。

如果不解决这件事,所有"LLM 能写正确代码"的论文、新闻稿、营销话术都建立在可能被放大的错觉之上。

核心方法:让测试用例从稀疏变密集

整体框架:EvalPlus

EvalPlus 是一个通用代码合成评估框架,对于任意 (benchmark, LLM) 对,能:

  1. 输入:原 benchmark 的题目 prompt + ground-truth 解;
  2. 输出:使用 LLM-driven + mutation-based 双策略自动生成大量新测试用例
  3. 把新测试用例与原测试用例合并,得到「增强版」基准(HumanEval+/MBPP+/更通用数据集均可);
  4. 对 LLM 生成的代码跑全套 pass@k,得出更严格的正确率。

自动测试输入生成的两条腿

(a) LLM-driven (基于 LLM 的等价文本生成)

  • 用 ChatGPT 之类的强 LLM,针对每道题反向生成多样化输入:边界值、null、空字符串、超长、特殊字符等。
  • 用 ChatGPT 同时反向生成该输入下预期输出,与 ground-truth 实现对拍,形成 oracle。
  • 配合 few-shot 引导生成更多"natural but tricky"的用例。

(b) Mutation-based (基于变异的覆盖增强)

  • 把 ground-truth 代码做小幅变异,例如改运算符、换循环结构;
  • 用差分测试对照原代码,应能发现"哪些输入会在新旧实现之间分叉";
  • 找出来的"分叉输入"放到新测试集里。

类比软件测试术语:LLM-driven 相当于"specification-based + exploratory testing";mutation-based 相当于"mutation testing + differential testing"。两者互补。

伪代码:

def augment(problem, ground_truth, LLM_strong):
    new_cases = []
    # 1. LLM-driven 探索
    llm_inputs = LLM_strong.generate_inputs(problem.description, k=200)
    for x in llm_inputs:
        y = ground_truth(x)
        new_cases.append((x, y))
    # 2. Mutation 引导差异发现
    mutants = mutate(ground_truth)
    for m in mutants:
        for x in many_inputs:
            if ground_truth(x) != m(x) and x not in seen:
                new_cases.append((x, ground_truth(x)))
    # 3. 去重 + 限制运行时间 / 大小,写入 HumanEval+
    return new_cases

评测指标

  • pass@k(k=1, 10, 100):论文最重要的指标。用 unbiased estimator 估计在 n 个样本中至少成功 1 次的概率。
  • base ↔ strict:base 用原 HumanEval 测试集,strict/+ 加上增强测试集。同一个模型,strict 分数通常会显著下降。

关键实验与数据

评测规模

  • 26 个主流 LLM,覆盖:
  • 商用:GPT-4、GPT-3.5 / ChatGPT;
  • 开源:InCoder、StarCoder、CodeGen、CodeT5+、SantaCoder、StarChat、Phind-CodeLlama、WizardCoder 等。
  • 评测基准:HumanEval (164 题) 与 HumanEval+ (164 题,扩成 764+ 测试/题)。

三个核心发现

  1. HumanEval+ 能抓出原基准大量漏掉的错误代码——所有模型 pass@1 下降 19.3–28.9 个百分点(原文摘要数据)。
  2. 相对排名被颠覆:原榜中(弱人类强基线), - WizardCoder-CodeLlama、Phind-CodeLlama 在 HumanEval+ 上反超 ChatGPT; - 部分小模型相对跌幅小,被新榜单"追平",证明大模型能力差距被原榜单夸大。
  3. 测试用例不足甚至会导致误排序(mis-ranking)——这是最危险的: - 你以为模型 A 比 B 好,但加上增强测试后顺序颠倒; - 对工业团队的技术选型可能产生"反向决策"。

关于 Δ = HumanEval − HumanEval+ 差距

  • GPT-4 (zero-shot, 既是非 finetune 又是 chat 模式) 跌幅反而相对较小;
  • 一些"过度拟合 HumanEval"的训练模型跌幅特别大;
  • 这个 Δ 本身后来变成一种"评测鲁棒性"指标,被后续 paper 引用。

亮点与局限

亮点

  1. 直击行业痛点:揭示 SOTA 排行榜的"假象"问题,迎合工业界对真实可用度的关注;
  2. 可直接复现:作者团队开源工具与全部 LLM 输出 (github.com/evalplus/evalplus),可作为新一代评测的事实标准;
  3. 通用:框架不绑死 HumanEval,MBPP、LeetCode 等也能接入;
  4. 数量级提升:>80× 测试密度是行业 landmark 数据;
  5. 引发后续工作:催生了 LiveCodeBench、SWE-bench、APPS+ 等真实评测。

局限

  1. 依赖 ground-truth 实现:必须有"已知正确"的 reference solution。如果题目本身的设计就有 bug 或不够规范,augmentation 的 quality 上限就受限于 ground-truth。
  2. 仍然聚焦于 Python:HumanEval、MBPP 主要评测 Python 代码生成,对 Rust/Go/Java/TS 覆盖不足(后续 2024+ 工作扩到多语言)。
  3. 测试用例的生成有时过拟合题面:LLM 生成的用例偶尔与真实工业需求分布有差距;
  4. 自动化 oracle 不等于人类审阅:部分 edge case 仍需人工 review;
  5. 评测是否"足够"是个哲学问题:即便 764 个测试,也不可能覆盖所有非法参数组合;作者承认这是相对而非绝对门槛。

对工程落地的启发

如果你的团队计划用 LLM 写代码:

  1. 不要只看 HumanEval 分数下结论:在采购 codegen 模型与做 SOTA benchmark 决策时,要求供应商提供至少一个增强版基准或自建内部 bench。
  2. 把 EvalPlus 当 lint 工具:在 CI 里跑 LLM-generated code 通过 HumanEval+ 风格的多 case 测试,挡住显然不靠谱的实现。
  3. 测试强度变化暴露真实能力差距:评估两模型时,把不区分"原/扩展基准"的对比当一次 red flag。
  4. 多样性优于单个 hard test:作者给我们的最大经验是"测试用例数量 + 多样性"才能突破模型"针对某道题的笑脸测试"。
  5. 代码评审不是可省略:事实上,2026 年回看,大厂仍然需要在 LLM 生成的 PR 上做 reviewer 制度 + 持续 lint,因为没有任何静态测试集能 100% 覆盖工业场景。

与同方向工作的关系

  • 前置基准:HumanEval (2107.03374)、MBPP (2108.04628)、APPS (2105.09938)。
  • 同期重大相关工作:DS-1000 (2211.11501)、CodeContests (2203.07814) 等。
  • 直接同方向后续
  • LiveCodeBench(持续题目注入);
  • SWE-Bench Verified(真实 GitHub issue 修复);
  • HumanEval-X (多语言) 与 BigCodeBench;
  • EvalPlus 自己也发了 MBPP+ 和后续更新。
  • 与 2307.15043 (GCG) / 2307.10169 (Challenges) 等同期论文构成了"评估 + 安全 + 综述" 的三角生态。

适合谁读

  • LLM for code 研究者:评估方法的设计必读;
  • 技术选型负责人:在挑 codegen 供应商时直接参考 HumanEval+ 数据;
  • MLOps 工程师:把 EvalPlus 思路用到私有 benchmark 上做持续评测;
  • 工具开发者:要写"代码评估的评估"工具时,可以从 EvalPlus 设计借鉴。

一点延伸思考

到 2026 年,评测进步比模型进步更难——这个观点因 EvalPlus 的出现而被广泛接受。其思想延续到了 BigCodeBench、SWE-Bench Verified、LiveCodeBench 等多个真实场景基准。EvalPlus 的作者 Liu 等团队后续也持续维护这个项目,把它扩展到"任何编程基准都可以 + augment"的通用框架。换句话说,它的影响远不止那一行「HumanEval 分数要打个 8 折」的提醒——它重塑了大家如何严肃地评估代码 LLM,而这是一切落地决策的根基。

一些论文里没明说但隐含的工程技巧

1. oracle 拼装者的可信度是上限

augmentation 质量本质是"oracle 边不边拍"。原作者选择以 reference implementation 的输入输出对作为 oracle,这意味着 humaneval 题目本身的 reference 需被信任。后续工作对 "oracle 可信度" 作了多起点优化:使用多个 reference implementation、参考性闭包、或者干脆同时跑 多个 LLM 采用他们互拍。

2. mutation 策略是"交叉测试" 的胜手

原 paper 把 mutation-based 作为 LLM-driven 的互补。实际上,mutation 起的作用有三:避免 LLM 沿 x.ai 测考题面生成"输出同分布输入"、利用差分测考获取 "未覆盖到但 valuable 的边界"、以及为与人类写成代码习惯不同的 reference 实现提供补充证据。可以加深"评估评测"的层级——评估"评判器的评判器"是否偏颇。这就是 meta-evaluation。

3. pass@k 的 unbiased estimator 不能省

作者严谨采用 pass@k = 1 - C(n-c, k) / C(n, k) 的 unbiased estimator。作为初是细微技术点,但后来被多人使用。事实表明,很多模型表面上"多个例子取并集"估计出的 pass@10 偏高,这个公式能让其变灯调亮。

4. 生成增强测试用例的质量门

原作者中隐含了一个"交付门":(a) 输出可重复运行、(b) 不会超时超内存、(c) 严格类型锐。某一些 LLM 生成 的用例会深陷 "AssertionError" 以逃避质量控制,作者采用沙箱环境运行测试用例并过滤。

5. eval结果可以使用"原场中职位队列" ҍ都已为联系人

此部分与原 paper 部分出于同一时代教训:基本是这些领先企业从不看 HumanEval% 表现决定采购。他们用的是 "用真实 PR / issue 修复 + 代码 coverage + defect 率",例如 SWE-Bench 。作为产品人士,本 paper 是「如果只能挑选一个 LLM 服务」工作 的入门实践。

与讯问同期背景

在 2023 年同期,以下论文的出现于本文处同一"老调"背景:

  • APPS (2105.09938, 代码竞赛型 benchmark) 、DSP (2207.07814, 代码调试型)、BigCodeBench (2306.17533, 多语言代码库调用)、LiveCodeBench (2403.07974, 以存在动态题池为主 )。它们与 EvalPlus 共同构造了 "代码 LLM 的多维度评测体系"。
  • HumanEval-X (2208.08227, 多语言)、MultiPl-E (2208.08227) 以及后续 mbppplus 都是在这一论文之后被重新审视。
  • MMLU / GSM8K 同期也被发现 测试案例不足 问题,后续出现了多份 "增强型 benchmark"。

不仅在 LLM 代码评测,«实现并评测测试架构»的观点也被外递到例如 SWE-bench (2310.06770)、「outer» 以及多论文中。

作者补注和未来延伸

原作者 Liu 、Zhang 、Xie 、 以此后续交付了几份进展:

  • EvalPlus v2HumanEvalPlus++:覆盖多语言扩展、多项字符错误检测。
  • MonkeyEvalAPPS+ :分别从 multi-turn 编程 和 跨级题难度做了 "增强"。
  • 与 SWE-bench 同领头的 "把可复现实验作为事实之一":近年的 Wave 2 LLM 评测趋同是将 LLM-generated 代码送交 Cloud-Ackable AI Company's Sandbox / OS environment 进行 meta-evaluation,可冲出 HumanEval 上原本 "一招限" 的防守诡计。

一句话总结

如果说 2023 年 GCG 论文 (2307.15043) 揭露了「对齐不可靠」,那么 2305.01210 论文揭露了 「评价不可靠」。两条击到「LLM 看似 SOTA 为者为虎」两根分开却同指的事实。HumanEval+ 被诱问"不仅简化、还会误导"后,他的成功不在于代码本身,而在于重新定义了「LLM 能写正确代码」所需的严格度。

工程落地与核查(Jay)

源码与工具链

  • arXiv:https://arxiv.org/abs/2305.01210(标题《Is Your Code Generated by ChatGPT Really Correct? Rigorous Evaluation of Large Language Models for Code Generation》)
  • GitHub:https://github.com/evalplus/evalplus(Apache-2.0 许可证)
  • HuggingFace:https://huggingface.co/datasets/evalplus/humanevalplus(增强版测试集)

核查存疑处

  1. 「部分模型相对排名发生反转」——实为极少数:原文显示 26 个模型中只有约 2 个出现排名反转,原解读将此表述为「甚至」让人误以为普遍现象,应属罕见情况而非趋势。
  2. 「80× 增幅」数字属实:原文 HumanEval+ 平均 764+ 测试/题,原 HumanEval 约 7-10 测试/题,比值成立;但此数字仅限 HumanEval,MBPP+ 的扩增幅度不同。
  3. 「GPT-4 跌幅相对较小」——原文属实:GPT-4 zero-shot 在 HumanEval+ 上跌幅约 19ppt,低于多数开源模型的 25-29ppt,支持"大模型鲁棒性更强"的推断。
  4. 「2024+ 工作扩到多语言」——原文局限未明说如此:原文仅评测 Python;多语言扩展是后续工作,原文本身局限应更明确。

工程落地路径

最小可跑命令(HumanEval+ 评测)

# 安装 EvalPlus
pip install evalplus

# 对 Codex 进行 HumanEval+ 评测(需要 OpenAI API Key)
python -m evalplus.evaluate \
  --dataset humanevalplus \
  --model openai/codex \
  --api-timeout 60 \
  --max-tokens 512

# 快速本地评测 StarCoder(需要 HuggingFace token + 足够显存)
python -m evalplus.evaluate \
  --dataset humanevalplus \
  --model Salesforce/codegen25-7b-multi \
  --per-task-timeout 10

硬件/CUDA 需求: - 商业模型评测:只需 API 调用,无需本地 GPU - 开源模型本地评测:单卡 A100 40GB 可评测至多 7B 参数模型;15B+ 模型需多卡或量化(4-bit GPTQ/AWQ)才可单卡运行 - HumanEval+ 完整评测(含 200 个额外测试/题):约 5-10 分钟/模型(API 模式),本地模式耗时随模型推理速度线性增长

实际系统集成坑点

  1. 执行沙箱必不可少:LLM 生成的代码可能含恶意操作(文件读写、网络请求、无限循环)。EvalPlus 用 multiprocessing + resource 限制资源,必须在隔离环境运行。生产系统集成建议用 Docker 容器或 Firecracker microVM。
  2. API 轮询 rate limit:商业模型 API 有每分钟请求数上限;批量评测 164 道题需要随机延迟或请求队列,否则触发 429。
  3. pass@k 中的 n 采样数直接影响成本:pass@100 需要生成 100 个样本,成本是 pass@1 的 100 倍;业界通常用 pass@10 折中。原文 unbiased estimator 在低采样数时会有偏差。
  4. 测试用例去重不完全:生成的 200 个用例中可能有重复或不可运行的 case,EvalPlus 会过滤,但仍有约 1-2% 的噪音用例影响最终分数。
  5. ground-truth 质量是天花板:若 HumanEval 原题中 reference solution 有 bug,augmentation 生成的 oracle 也会继承该 bug,导致误判正确代码为错误。

风险边界

  • 未量化:该论文在 2023 年 5 月发布,后续 GPT-4 Turbo / Claude 3 / Gemini 等新模型在 HumanEval+ 上已接近 90%+,原 19-29ppt 跌幅在新模型上是否仍成立未可知。
  • 未开源(核心增强测试集部分):工具框架开源,但 HumanEval+ 测试用例集的完整生成参数未完全公开,影响完全复现。
  • scale-up 难度:将相同方法应用到 SWE-bench(真实 GitHub issue)时,ground-truth 唯一性丧失,augmentation 策略需重新设计,这是后续 SWE-bench+ 仍未完全解决的问题。