【自然语言处理】【大模型】CodeGen:一个用于多轮程序合成的代码大语言模型

CodeGen:一个用于多轮程序合成的代码大语言模型
《Code Gen: An Open Large Language Model For Code with Multi-Turn Program Synthesis》

论文地址:https://arxiv.org/pdf/2203.13474.pdf?trk=public_post_comment-text

相关博客
【自然语言处理】【大模型】RWKV:基于RNN的LLM
【自然语言处理】【大模型】CodeGen:一个用于多轮程序合成的代码大语言模型
【自然语言处理】【大模型】CodeGeeX:用于代码生成的多语言预训练模型
【自然语言处理】【大模型】LaMDA:用于对话应用程序的语言模型
【自然语言处理】【大模型】DeepMind的大模型Gopher
【自然语言处理】【大模型】Chinchilla:训练计算利用率最优的大语言模型
【自然语言处理】【大模型】大语言模型BLOOM推理工具测试
【自然语言处理】【大模型】GLM-130B:一个开源双语预训练语言模型
【自然语言处理】【大模型】用于大型Transformer的8-bit矩阵乘法介绍
【自然语言处理】【大模型】BLOOM:一个176B参数且可开放获取的多语言模型
【自然语言处理】【大模型】PaLM:基于Pathways的大语言模型
【自然语言处理】【chatGPT系列】大语言模型可以自我改进
【自然语言处理】【ChatGPT系列】FLAN:微调语言模型是Zero-Shot学习器
【自然语言处理】【ChatGPT系列】ChatGPT的智能来自哪里?

一、简介

在这里插入图片描述

​ 程序合成(program synthesis)的目标是自动化编程过程,从而生成能够满足用户意图的计算机程序。程序合成面临两个关键的挑战:(1) 搜索空间难以处理;(2) 难以确定用户意图。为了解决搜索空间的问题,本文将程序合成任务形式化为语言建模过程,即基于前面的tokens预测下一个token的条件概率分布。

程序合成需要理解用户的意图。用户通常通过逻辑表达式、伪代码、输入-输出示例、或者自然语言表达意图。逻辑表达式伪代码通常需要用户具有相关领域知识,成本比较高。输入-输出示例的代价更低一些,但可能没办法准确传递用户意图。因此,作者认为自然语言表达用户意图的最好形式。

​ 本文提出了多轮程序合成方法,用户通过自然语言来逐步与合成系统进行沟通。采用多轮的方式有两个动机:

  1. 将长且复杂的用户意图分解为多个步骤,简化模型理解,从而增强程序合成。在多轮的方法中,模型可以专注在与子程序相关的意图上,避免费力的跟踪子程序之间复杂的依赖关系。
  2. 通常,代码会存在自然语言与编程语言交错的弱模式。这种模式就是通过程序员为代码添加注释形成的。使用语言建模的目标函数,这种交错模式可以为多轮程序合成提供弱监督信号。这种信号通常是有噪音且比较弱的,因此仅有部分数据有这种模式且注释可能不正确或者信息量不足。扩大模型和数据的规模可能会克服这种弱监督的不足。

​ 本文还提出了一个多轮程序合成基准来衡量模型的多轮程序合成能力。针对该基准中的问题,模型需要多个步骤来合成程序,每个步骤都需要用户使用自然语言来指定意图。上图展示了一个从邮件地址抽取用户名的合成过程。

​ 本文采用语言模型进行程序合成的基础想法。此外,还有4方面的贡献:

  • 研究了自回归模型在scaling law下多轮程序合成的涌现;
  • 利用这个能力引入了多轮程序合成范式;
  • 利用一个新颖的多轮编程基准来定量研究其性质;
  • 开源了模型的checkpoints以及自定义的训练库JAXFORMER

​ 对于程序合成,没有开源的大模型能够与Codex竞争。这阻碍了进步,考虑到训练这些模型需要的昂贵计算资源,仅有少量的机构可以使用。本文的开源贡献允许广大的研究者学习和改进这些模型,这极大的促进了研究的进步。

二、模型训练

​ 模型采用标准的基于transformer的自回归语言模型,仅对模型参数量和训练语料的token数量进行改变动

1. 数据集

​ CodeGen模型族会在三个数据集上顺序训练:THEPILEBIGQUERYBIGPYTHON

THEPILE是一个用于语言建模的825.18GB英文数据集。该数据集是基于22个高质量子集构造的,其中一个是从GitHub上收集的编程语言数据,占整个数据集的7.6%。基于该数据集训练的模型称为自然语言CodeGen模型(CodeGen-NL)。

​ 多语言数据集BIGQUERY是Google公开数据集BigQuery的子集,其是由多种编程语言构成的。选择6种编程语言C、C++、Go、Java、JavaScript和Python进行多语言训练。称在BIGQUERY上训练的模型为多语言CodeGen模型(CodeGen-Multi)。

​ 单语言数据集BIGPYTHON包含了大量python的数据。该数据集中包含了至2021年10月的公开、可获取且非个人的python代码。称在BIGPYTHON上训练的模型为单语言CodeGen模型(CodeGen-Mono)。

​ 数据预处理:(1) 过滤;(2) 去重;(3) tokenization;(4) shuffling;(5) 拼接。

2. 模型

​ CodeGen使用自回归形式的transformer在自然语言和编程语言数据集上进行训练。模型尺寸包括:350M、2.7B、6.1B和16.1B。前3种尺寸允许直接与开源的大语言模型进行比较,GPT-NEO(350M,2.7B)和GPT-J(6B)。

​ CodeGen在数据集上按顺序训练。CodeGen-NL在THEPILE上第一个训练;CodeGen-Multi使用CodeGen-NL进行初始化,并在BIGQUERY上训练;CodeGen-Mono使用CodeGen-Multi进行初始化,并在BIGPYTHON上训练。

​ 基于自然语言描述为条件的程序合成能力涌现,可能来源于模型和数据的尺寸、训练目标函数和训练数据本身。之所以称为"涌现",是因为没有在"注释-代码对"数据上进行训练。在自然语言任务上也观察到类似的现象,大规模无监督语言模型可以通过zero-shot的方式来解决未见过的任务。

三、单轮评估

​ 现有程序合成基准 HumanEval包含164个手写Python编程问题。每个问题都会提供一段自然语言的prompt以及函数的签名和示例测试用例。模型需要根据prompt来补全函数,且该函数需要通过所有的测试用例。因为用户的意图被指定在单个prompt内并一次性提供给模型,将HumanEval看作是单论评估,以区别于后续的多轮评估。

1. HumanEval的效果是模型尺寸和数据尺寸的函数

在这里插入图片描述

​ 比较在HumanEval上的SOTA方案。此外,还比较了开源大语言模型GPT-NEO、GPT-J。这些大模型都是在THEPILE上训练的,因此类似于CodeGen-NL模型。

​ 结果如上表1所示。CodeGen-NL模型优于或者相当于GPT-NEO和GPT-J模型。GodeGen-Multi大幅度超越了GPT-NEO、GPT-J和CodeGen-NL。在纯Python数据集上的微调模型CodeGen-Mono,程序合成能力显著改善。

2. 更好的用户意图理解可以产生更好的合成程序

在这里插入图片描述

​ 成功的程序合成系统高度的依赖于其是否很好的理解了用户意图。因为系统是基于语言模型的,prompt的困惑度可以作为系统对用户意图理解的一种代理。一个用户意图在模型下具有低困惑度,则用户描述的意图与模型预训练数据学习到的知识相兼容。

​ 具体来说,将所有的问题划分为passnon-pass。pass问题表示,200个样本中至少有一个样本通过了所有的测试用例;non-pass则是200个样本中没有样本能通过所有的测试用例。基于CodeGen-Mono模型,计算所有pass问题的平均困惑度,以及no-pass问题的困惑度。如上表2所示,pass问题要比non-pass问题具有更低的困惑度。这意味着,当用户的意图被模型更好的理解后,程序合成的效果会更好。

四、多轮评估

​ 本小节提出并研究了多轮程序合成范式。程序合成被分解为多个步骤,合成系统在每个步骤中完成子程序的合成。为了测试这种范式,开发了新基准Multi-Turn Programming Benchmark(MTPB)。MTPB包含115个问题,每个问题包含多步骤自然语言描述。

1. 基准构造

​ 本文的4位作者定义了115个问题。这些问题需要各种编程知识,包括:数学、数组操作、字符串操作、算法、数据科学等,这样每个类图的问题大致平衡。每个问题都构建一个三元组,包含:多轮的prompt P P P、测试用例的输入 I I I、测试用例的输出 O O O。设计多轮prompt P P P需要遵循两个约束:(1) 问题被分解为至少3轮;(2) 单轮无法解决这个问题。每个问题的作者都需要准备5个测试用例的输入 I I I和输出 O O O

​ HumanEval要求补全部分定义的函数,而MTPB仅通过prompts,因此模型必须从头生成解决方案。这种自由形式的生成允许更有潜力的解决方案,但是需要模型能够生成测试用例输入的入口。例如,prompt:“Define a string named ‘s’ with value {var}”,测试用例输入var = 'Hello'将被形式化为"Define a string named ‘s’ with the value ‘Hello’"。

2. 多步编程能力随模型大小和数据大小而改变

在这里插入图片描述

4. 通过多轮分解更好的理解用户意图

在这里插入图片描述

​ 本文假设多轮分解能够增强模型理解用户意图的能力,并带来更好的程序合成能力。为了测试这个假设,我们通过拼接的方式将多轮指令形式化为单轮的形式。仍然使用prompt困惑度作为用户意图理解的代理。因此,比较了4个CodeGen-Mono模型在单轮和多轮prompt的困惑度。

​ 上表4展示了单轮prompt和多轮prompt的困惑度(左)和通过率(右)。所有单轮的困惑度都比多轮的高,意味着多轮的方式能够更好的理解用户的意图。多轮方式的通过率比单轮高平均百分之十个点

### CodeGen模型预训练方法 CodeGen系列模型通过分阶段的方式逐步增强其编码能力。具体来说: - **初始阶段**:CodeGen-NL基于THEPILE数据集进行了首次训练,该数据集涵盖了多种自然语言处理任务所需的广泛文本[^1]。 - **多语言扩展**:随后,CodeGen-Multi利用已经获得的知识,在BIGQUERY数据集上进一步学习,此过程不仅增强了对SQL查询的理解和支持,还提升了跨不同编程范式的适应性[^4]。 - **特定领域精炼**:最终,为了专注于Python编程环境下的表现力提升,CodeGen-Mono继承自CodeGen-Multi,并专门针对BIGPYTHON数据集进行了微调,从而实现了更精准高效的Python代码生成功能。 这些连续性的训练策略使得CodeGen能够在保持通用性的同时,也具备了应对特定编程场景的能力。 #### 数学建模基础 在实现上述各阶段的过程中,CodeGen依赖于两种核心架构来捕捉并生成结构化的程序逻辑: - 序列到序列(Seq2Seq)模型用于处理线性的输入输出转换问题,适用于大多数简单的语法解析和短片段代码合成任务[^2]。 - 对于更加复杂的结构性映射,则采用了树到树(Tree2Tree)的方法论,这有助于更好地理解和重现具有层次关系的数据流图或抽象语法树等高级概念。 这两种模式的选择取决于具体的上下文需求以及预期的应用范围。 #### 实践指南与资源推荐 对于希望深入了解或者实际操作CodeGen的人来说,建议关注以下几个方面: - 官方文档通常是最权威的信息来源之一,里面会详细介绍各个版本的具体参数配置、API接口说明等内容; - GitHub上的开源项目页面也是不可忽视的重要平台,这里不仅可以找到完整的源码文件,还能参与社区讨论获取最新进展和技术支持; - 此外,一些在线教育网站如Coursera、Udemy也会提供有关Transformer框架及其变体应用的教学视频课程,虽然不是专门为CodeGen设计,但对于理解背后的原理非常有帮助。 ```python # 示例:如何加载预训练好的CodeGen模型 from transformers import AutoModelForCausalLM, AutoTokenizer model_name = "Salesforce/codegen-mono" tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModelForCausalLM.from_pretrained(model_name) text = "<|file_sep|>def hello_world():\n print('Hello world!')" inputs = tokenizer(text, return_tensors="pt") outputs = model.generate(**inputs) print(tokenizer.decode(outputs[0], skip_special_tokens=True)) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BQW_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值