代码生成
# 代码生成
# 介绍
# 相关工作
# Codex
[2107.03374] Evaluating Large Language Models Trained on Code (arxiv.org) (opens new window)
如何使用 Codex 模型处理代码 - Azure OpenAI Service | Microsoft Learn (opens new window)
# CodeT5
EMNLP 2021
# CodeT5+
# CodeGen
ICLR 2023
Salesforce Research
程序合成致力于生成一个计算机程序,作为给定问题规范的解决方案,用输入输出示例或自然语言描述来表达。尽管有限的训练资源和数据阻碍了对此类模型的开放访问,但大型语言模型的普及推动了程序合成的最先进技术。为了使其民主化,我们在自然语言和编程语言数据上训练并发布了一系列高达16.1B参数的大型语言模型,称为CODEGEN,并开源了训练库JAXFORMER。我们通过证明在HumanEval上生成零样本Python代码方面,经过训练的模型与以前的最新技术相比具有竞争力,展示了该模型的实用性。 我们进一步研究了程序合成的多步骤范式,其中单个程序被分解为指定子问题的多个提示。为此,我们构建了一个开放的基准测试,多回合编程基准测试(MTPB),由115个不同的问题集组成,这些问题集被分解为多回合提示。 我们对MTPB的分析表明,以多回合方式提供给CODEGEN的相同意图比以单回合方式提供的意图显著改进了程序合成。我们将训练库JAXFORMER和模型检查点作为开源贡献提供:GitHub - salesforce/CodeGen: CodeGen is a family of open-source model for program synthesis. Trained on TPU-v4. Competitive with OpenAI Codex. (opens new window)
# CodeGeeX
Tsinghua University
大型预先训练的代码生成模型,如OpenAI Codex,可以生成语法和功能正确的代码,使程序员的编码更高效,使我们对人工通用智能的追求更紧密。在本文中,我们介绍了CodeGeeX,一个具有130亿个代码生成参数(13B)的多语言模型。截至2022年6月,CodeGeeX在23种编程语言的8500亿个tokens上进行了预训练。我们的大量实验表明,CodeGeeX在HumanEval-X上的代码生成和翻译任务上都优于规模相似的多语言代码模型。在HumanEval(仅限Python)的基础上,我们开发了HumanEval-X基准测试,通过用C++、Java、JavaScript和Go手工编写解决方案来评估多语言模型。 此外,我们在Visual Studio Code、JetBrains和Cloud Studio上构建了基于CodeGeeX的扩展,每周为数以万计的活跃用户生成47亿个tokens。
我们的用户研究表明,CodeGeeX可以帮助83.4%的用户提高编码效率。最后,CodeGeeX可以公开访问,2022年9月,我们在github上开源了其代码、模型权重(850B令牌的版本)、API、扩展和HumanEval-X。
# StarCoder
[2305.06161] StarCoder: may the source be with you! (arxiv.org) (opens new window)
BigCode Project
BigCode社区是一个开放的科学合作组织,致力于负责任地开发大型代码语言模型(Code LLM),引入了StarCoder和StarCoderBase:15.5B参数模型,具有8K上下文长度、填充功能和多查询注意力支持的快速大批量推理。StarCoderBase是在来自The Stack的1B tokens上进行训练的,这是一个拥有检查工具和选择退出流程的许可GitHub存储库的大型集合。我们在35B Python令牌上对StarCoderBase进行了微调,从而创建了StarCoder。
我们对代码LLM进行了迄今为止最全面的评估,并表明StarCoderBase优于所有支持多种编程语言的开放代码LLM,并且匹配或优于OpenAI代码-cushman-001模型。此外,StarCoder的性能优于所有在Python上微调的模型,可以提示达到40%pass@1在HumanEval上,并且仍然保留其在其他编程语言上的性能。我们采取了几个重要步骤来实现安全的开放访问模型发布,包括改进的PII编辑管道和新颖的归因追踪工具,并在更具商业可行性的开放责任人工智能模型许可证版本下公开StarCoder模型。
# WizardCoder
# 出发点
代码大型语言模型(Code-LLM),如StarCoder,在与代码相关的任务中表现出了卓越的性能。然而,大多数现有模型仅在大量原始代码数据上进行预训练,而没有指令微调。
【相关工作】
指令调整的引入最初旨在增强LM在不同任务中的泛化能力。虽然用不同的NLP任务对LM进行微调显示出了有希望的结果,但它往往无法与现实世界用户的意图保持一致。
OpenAI采用了一种不同的方法,邀请人类注释者提供大量人类指令,包括各种形式和广泛的任务类型。在这个数据集的基础上,OpenAI训练了其GPT3模型,以创建更符合用户输入的InstructGPT。这条发展路线甚至导致了被称为ChatGPT的令人印象深刻的工作。
Alpaca采用了自指令
(self-instruct)
方法,其中ChatGPT生成指令数据。Vicuna利用了从ShareGPT.com收集的用户共享对话。
WizardLM引入了Evol instruction方法,该方法涉及对现有指令数据进行进化,以生成更复杂、更多样的数据集。
【方法】
提出了WizardCoder,它通过将Evol instruction方法应用于代码领域,为代码LLM提供了复杂的指令微调功能。
【效果】
通过对HumanEval、HumanEval+、MBPP和DS1000四个突出的代码生成基准进行全面实验,我们展示了我们模型的卓越功能。它大大超过了所有其他开源代码LLM。此外,在HumanEval和HumanEval+上,我们的模型甚至优于最大的闭源LLM,Anthropic的Claude和谷歌的Bard。
# 详细介绍
应用Evol instruction方法来进化Alpaca使用自我指令生成的代码
用进化的数据微调预训练的代码LLM StarCoder。
# Evol-Instruct Prompts for Code
受WizardLM提出的Evol Instruction方法的启发,这项工作还试图使代码指令更加复杂,以增强代码预训练的大型模型的微调效果。为了使Evol指令适应代码领域,我们对进化提示进行了以下修改:
通过删除深化、复杂的输入和广度进化,简化进化指令。
通过统一进化提示模板,简化了进化提示的形式。
针对代码域的具体特征,我们添加了两个进化指令:代码调试和代码时空复杂性约束
统一的代码进化提示模板如下:
Please increase the difficulty of the given programming test question a bit.
You can increase the difficulty using, but not limited to, the following methods:
{method}
{question}
2
3
4
5
6
这里,{question}表示当前等待进化的代码指令,{method}是进化的类型。我们使用的五种类型如下所示:
Add new constraints and requirements to the original problem, adding approximately 10 additional words.
Replace a commonly used requirement in the programming task with a less common and more specific one.
If the original problem can be solved with only a few logical steps, please add more reasoning steps.
Provide a piece of erroneous code as a reference to increase misdirection.
Propose higher time or space complexity requirements, but please refrain from doing so frequently.
2
3
4
5
6
7
8
9
# Training WizardCoder
我们采用以下程序来训练WizardCoder。最初,我们使用StarCoder 15B作为基础,并使用通过Evol instruction进化而来的代码指令后续训练集对其进行微调。微调的提示格式概述如下:
Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.
###Instruction: {instruction}
###Response:
2
3
4
5
【总的来说】
为了构建训练数据集,使用名为Code Alpaca5的20K指令集对其进行了初始化。我们在这个由20000个样本组成的数据集上反复使用Evol Instruction技术来产生进化数据。在每一轮数据进化之后,我们将前几轮的进化数据与原始数据集合并,以微调StarCoder并评估pass@1HumanEval的度量。一旦我们观察到pass@1度量下降,我们将停止使用Evol Instruction,并选择最高的型号pass@1作为终极模型。
# 实验
# 实现细节
StarCoder是基本基础模型。进化数据集由大约78k个样本组成。为了微调基本模型,我们采用了特定的配置,包括512的批量大小、2048的序列长度、200个微调步骤、30个预热步骤、2e-5的学习速率、余弦学习速率调度器和fp16混合精度。
# Evaluation on HumanEval, HumanEval+, and MBPP
这些任务的提示格式如下:
Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.
###Instruction:
Create a Python script for this problem:
{Question}
###Response:
2
3
4
5
6
7
8
9
【单次尝试HumanEval(164个问题)的通过率百分比】
所有基线分数均从LLM Humaneval Benchmarks中检索。我们的WizardCoder通过贪婪解码生成一个答案。

【在HumanEval和MBPP上的pass@1(%)结果】
大多数分数来自StarCoder和CodeT5+的论文。我们遵循前面的工作(Codex)生成n个样本来估计pass@1使用同一组超参数得分:temperate=0.2,top_p=0.95。*:我们自己评估这个模型。

根据实验结果得出以下结论:
WizardCoder的性能优于最大的闭源LLM,包括Claude、Bard、PaLM、PaLM-2和LaMDA,尽管它们明显更小。
WizardCoder的性能大大优于所有开源代码LLM(在HumanEval上为+22.3),包括StarCoder、CodeGen、CodeGee和CodeT5+。
WizardCoder在指令微调方面显著优于所有开源代码LLM,包括InstructionCodeT5+、StarCoder GPTeacher和Instruction-Codegen-16B。
# Evaluation on DS-1000
DS-1000上的WizardCoder和基准型号的性能。所有模型都使用相同的超参数集进行评估:温度=0.2,顶部=0.5,最大长度=1024。分数一般pass@1精度超过40个样本。Matplotlib(plt)任务没有正确的上下文,因此插入和完成分数是相同的。

# 消融实验
该研究调查了数据进化轮数的影响。第一轮进化数据包含38k个样本。第二轮包含58k。第三轮包含78k。第四轮包含98k。为了保持一致性,所有模型都经过了200步的微调。结果显示pass@1经过三轮数据进化后,获得了人类评估的分数。基于这一观察结果,我们选择第三轮期间演变的数据作为最终数据集。

# 示例
展示了与我们的WizardCoder交互的示例。这些例子表明,我们的模型始终能产生准确的反应,并给出明确的解释。

# phi-1
[2306.11644] Textbooks Are All You Need (arxiv.org) (opens new window)
Microsoft Research
我们介绍了phi-1,这是一种新的大型代码语言模型,其大小明显小于竞争模型:phi-1是一种基于Transformer的模型,具有1.3B参数,在8个A100上训练了4天,使用了来自网络的“教科书质量”数据(6B令牌)和GPT-3.5(1B令牌)的综合生成教科书和练习。尽管规模很小,但phi-1达到pass@1HumanEval和MBPP的准确率分别为50.6%和55.5%。 与phi-1-base和phi-1-small相比,它还显示出令人惊讶的涌现特性,phi-1-base是我们在编码练习数据集上微调阶段之前的模型,phi-1-small是一个较小的模型,使用与phi-1相同的管道训练了350M个参数,在HumanEval上仍能达到45%。

# 实验评估
# 数据集
HumanEval、HumanEval+和MBPP是代码LLM领域中广泛使用的基准测试。这些基准测试包含大量Python编程问题,使用测试用例来验证Code LLM生成的代码。
# HumanEval
HumanEval由164个原始编程问题组成,每个问题平均分配9.6个测试用例。
# HumanEval+
为了确保全面评估LLM合成代码的功能正确性,HumanEval+显著扩展了测试用例的数量,平均每个问题774.8个测试用例。
# MBPP
MBPP提供了一组500个测试编程问题,每个问题附带三个自动测试用例。
# DS-1000
DS-1000基准包括跨越七个库的1000个不同的数据科学工作流程。它根据测试用例评估代码生成的性能,并支持两种评估模式:完成和插入。在我们的实验中,我们只报告支持的模型的插入分数。DS-1000基准测试根据所使用的库对问题进行了进一步分类,包括Matplotlib(plt)、NumPy(np)、Pandas(pd)、SciPy(scp)、Scikit-Learn(sk)、PyTorch(py)和TensorFlow(tf)。
# 评价指标
# pass@k
代码的生成模型主要通过将样本与参考解决方案进行匹配来进行基准测试,其中匹配可以是精确的,也可以是模糊的(如BLEU分数)。然而,最近的工作却暴露了基于匹配的代码度量的不足。例如,BLEU在捕获特定于代码的语义特征方面存在问题,并建议对分数进行一些语义修改。
更根本的是,基于匹配的度量无法计算与参考解决方案功能等效的程序的大而复杂的空间。因此,最近在无监督代码翻译和伪代码到代码翻译方面的工作转向了功能正确性,即如果样本通过一组单元测试,则认为其是正确的。
也许评估函数正确性最令人信服的原因是它被人类开发人员用来判断代码。一个被称为测试驱动开发dic的框架规定,在任何实现开始之前,软件需求都要转换为测试用例,而成功是由通过这些测试的程序来定义的。虽然很少有组织采用完全的测试驱动开发,但新代码的集成通常取决于创建和通过单元测试。
Kulal等人使用度量,其中每个问题生成k个代码样本,如果任何样本通过单元测试,则认为问题已解决,并报告已解决问题的总分数。然而,计算
以这种方式可以具有高的方差。相反,要评估
,我们每个任务生成n≥k个样本(在本文中,我们使用n=200和k≤100),计算通过单元测试的正确样本c≤n的数量,并计算无偏估计量:
计算这个估计量直接导致非常大的数量和数值不稳定性。下面包含了一个数字稳定的numpy实现,它简化了表达式并逐项计算乘积。
def pass_at_k(n, c, k):
"""
:param n: total number of samples
:param c: number of correct samples
:param k: k in pass@k
"""
if n - c < k:
return 1.0
return 1.0 - np.prod(1.0 - k / np.arange(n - c + 1, n + 1))
2
3
4
5
6
7
8
9