导语
phi-系列模型是微软研究团队推出的轻量级人工智能模型,旨在实现"小而精"的目标,能够实现在低功耗设备上例如智能手机和平板电脑上部署运行。截止目前,已经发布到了phi-3模型,接下来的几篇博客将沿着最初的phi-1到phi-1.5,再到phi-2和phi-3模型展开介绍,本文介绍最初的phi-1模型。
- 标题:Textbooks Are All You Need
- 链接:https://arxiv.org/pdf/2306.11644.pdf
1 简介
深度学习领域对缩放定律(Scaling Law)的探索导致了现有大语言模型(LLM)性能的迅速提升。本文探索了另一个可以改进的方向:数据的质量。 Eldan 和 Li 最近在 TinyStories(一个高质量的合成数据集,用于教导神经网络英语)上的工作表明,高质量数据可以显著改变缩放定律的形态,潜在地使得可以用更精简的训练/模型来达到大规模模型的性能。本文展示了高质量数据甚至可以改进大型语言模型 (LLMs) 的最先进水平,同时大幅减小数据集规模和训练计算。重要的是,需要较少训练的较小模型可以显著降低LLMs的成本。
本文关注于代码训练的LLMs(Code LLMs)上,即从文档字符串中编写简单的Python函数,通过训练一个包含13亿参数的模型(称之为phi-1),大约进行了8次遍历,每次处理了7B词元(即token,总共约为50B词元),然后对不到200M词元进行微调,来展示高质量数据在打破现有缩放定律方面的威力。粗略地说,本文在"教科书质量"数据上进行预训练,包括合成生成的数据(使用GPT-3.5)和来自网络来源的过滤数据,并在"教科书练习类"数据上进行微调。尽管在数据集和模型大小方面与竞争模型相比要小几个数量级(表1),但在HumanEval上达到了50.6%的Pass@1准确率,在MBPP上达到了55.5%的Pass@1准确率。
文章后续组织如下:第2节提供了训练过程的一些细节,并讨论了数据选择过程在实现这一结果方面的重要性的证据。此外,尽管与现有模型相比,phi-1在训练的词元数量要少得多,但仍显示出涌现能力(emergent properties)。第3节中讨论了这些涌现能力,特别是通过将phi-1的输出与phi-1-small(使用相同流程但只有350M参数的模型)的输出进行比较,作者确认了参数数量在 emergent 中起到了关键作用。第4节中,讨论了评估模型的替代基准。第5节研究了训练数据可能与HumanEval存在的污染。
2 训练细节与高质量数据的重要性
本文的核心要素依赖于教科书质量的训练数据。与以往使用标准文本数据进行代码生成的工作不同,例如The Stack(包含仓库源代码和其他基于网络的数据集,例如StackOverflow和CodeContest)。本文认为这些来源并非最佳选项,无法有效地教会模型如何进行算法推理和规划。另一方面,本文的模型架构和训练方法相当常规(见第2.3节),因此主要在本节解释本文如何策划数据。
标准的代码数据集中许多片段并不适合用于学习编码的基础知识,并存在以下几个缺点:
- 许多样本不是自包含的,它们依赖于其他模块或文件,这些模块或文件是与片段外部相关的,使得它们难以在没有额外上下文的情况下理解。
- 典型的示例不涉及任何有意义的计算,而是由一些微不足道的或样板式的代码组成,例如定义常量、设置参数或配置GUI元素。
- 包含算法逻辑的示例通常被埋藏在复杂或文档不完整的函数内部,使其难以理解或学习。
- 这些示例偏向于某些主题或用例,导致数据集中编码概念和技能的分布不平衡。
一个人类学习者试图从这些数据集中获取编码技能是低效的,因为必须在数据中处理大量的噪音、歧义和不完整性。作者假设这些问题也会影响语言模型的性能,因为它们降低了将自然语言映射到代码的信号的质量和数量。因此,作者推测语言模型将受益于一个具有与优秀"教科书"相同特点的训练集:它应该清晰、自包含、具有教学性并且平衡。本文展示通过有意选择和生成高质量数据,可以用比现有方法更小的模型和更少的计算量达到代码生成任务的最新结果。本文的训练依赖于三个主要数据集:
- D1. 过滤后的代码语言数据集,这是The Stack和StackOverflow的子集,通过使用基于语言模型的分类器获得(包含约6B词元)。
- D2. 一个合成的教科书数据集,由GPT-3.5生成的Python教科书的不到1B词元组成。
- D3. 一个小型的合成练习数据集,由大约180M个Python练习和解决方案的词元组成。
以上数据集共包含不到7B词元。本文将D1和D2的组合称为"CodeTextbook",并在预训练阶段使用它来获得基本模型phi-1-base。然后,使用合成练习数据集D3,称为"CodeExercises",对phi-1-base模型进行微调以获得phi-1。尽管"CodeExercises"数据集的规模较小,但使用该数据集进行微调对于生成简单的Python函数的大幅改进至关重要,如图2.1所示,而且更广泛地说,微调还可以解锁phi-1模型中许多有趣的涌现能力,这些能力在phi-1-base中没有观察到(见第3节)。
2.1 使用基于Transformer的分类器对现有代码数据集进行过滤
本文使用The Stack和StackOverflow的去重版本中的Python子集,共包含超过3500万个文件/样本,超过35B个词元。使用GPT-4对这些文件的一个小子集(约10万个样本)进行质量注释:给定一个代码片段,模型被提示"确定其对于一个目标是学习基本编码概念的学生的教育价值"。然后,使用这个带有注释的数据集来训练一个随机森林分类器,该分类器使用预训练代码生成模型的输出嵌入作为特征,来预测文件/样本的质量。
2.2 创建合成的教科书质量数据集
在为代码生成创建高质量数据集时,确保示例具有多样性和非重复性是一个主要挑战。多样性包括广泛的编码概念、技能和场景,以及在难度、复杂度和风格上的变化。受到之前工作的启发,可以通过在提示中包含从某个固定词汇表中选择的一组随机单词的随机子集,并要求它们在生成的文本中以某种方式组合起来,创建了一组多样化的短故事,本文探索将随机性注入到提示中的方法,旨在通过注入随机性和约束来提供多样性,以帮助模型更好地学习和泛化。为了实现多样性,本文设计了两个合成数据集:合成的教科书数据集和CodeExercises数据集。
合成的教科书数据集
该数据集包含不到1B个由GPT-3.5生成的Python教科书词元,经过合成以提供自然语言文本与相关代码片段交织在一起的高质量来源。以下是合成教科书的一个示例文本:
CodeExercises 数据集
这是一个小型的合成练习数据集,由不到180M个Python练习和解决方案词元组成。每个练习都是一个需要完成的函数的文档字符串。该数据集的目标是通过自然语言说明来对齐模型执行函数完成任务。以下片段说明了一个合成生成的练习:
2.3 模型架构和训练
本文使用了FlashAttention实现的多头注意力(MHA)的解码器Transformer模型,还采用了MHA和MLP层并行配置的结构。1.3B参数的phi-1模型的架构包括24层,隐藏维度为2048,MLP内部维度为8192,以及32个维度为64的注意力头。而较小的350M参数的phi1-small模型包括20层,隐藏维度为1024,MLP内部维度为4096,以及16个维度为64的注意力头。使用旋转位置嵌入,旋转维度为32。使用与 codegen-350M-mono相同的分词器。
对于预训练和微调,将各自的数据集连接成一个单一的一维数组,使用"⟨∣endoftext∣⟩"标记用于分隔文件。从数据集数组中切片出长度为2048的序列,并使用下一个标记预测损失进行训练。
预训练
phi-1-base 在 CodeTextbook 数据集(过滤后的代码语言语料库和合成教科书)上进行了训练。批次大小1024(包括数据并行和梯度积累),最大学习率1e-3,750步的warmup,权重衰减0.1,总共训练了36,000步。使用24,000步处的检查点作为phi-1-base。
微调
phi-1是通过在CodeExercises数据集上微调phi-1-base获得的。对于微调,使用与预训练相同的设置,但不同的超参数:使用256的有效批次大小,最大学习率1e-4,50步的warmup,权重衰减0.01。总共训练了6,000步,并选择了最佳的检查点(每1000步保存一个检查点)。
3 微调后模型能力的突增
如图2.1中展示,在小型的CodeExercises数据集上进行微调导致了HumanEval中最大的改进。本节中展示了令人惊讶的发现,在微调后的模型也在执行未在微调数据集中展示的任务方面表现出了显著改进。这包括处理复杂的算法任务和使用外部库。这表明微调过程可能已经帮助模型重新组织和巩固了预训练期间获得的知识,即使这种知识在CodeExercises数据集中并不存在。本节将重点定量比较和对比微调模型 phi-1 和其预训练的1.3B参数基础模型 phi-1-base 的能力。
3.1 微调提高了模型的理解能力
在微调后,模型在理解和遵循指令方面表现出了更高的水平。作者发现 phi-1-base 在提示中的逻辑关系方面存在困难,而 phi-1 能够正确解释问题并生成答案。在这个例子中,即使350M phi-1-small模型显示出了一定程度的问题理解,但生成的解决方案仍然是错误的。
3.2 微调提高了模型使用外部库的能力
这里展示3个例子,尽管微调数据集不包含Pygame和Tkinter等外部库,但在CodeExercises上进行微调意外地提高了模型使用外部库的能力。这表明微调不仅改进了针对的任务,还使与之无关的任务更容易从预训练中提取。供参考,图3.1显示了CodeExercises数据集中包的导入分布。
三个模型的完成显示出了它们在提示理解方面的巨大差距。phi-1-base和phi-1-small都未能使用正确的Tkinter API,并进行了无意义的函数调用。另一方面,phi-1正确实现了GUI和所有函数(除了未正确复制"pewpewpew?")。
4 使用LLM评分对非常规问题进行评估
phi-1在HumanEval上表现出的惊人良好性能可能存在一个潜在问题(见表1和图2.1),即合成的CodeExercises数据集可能导致了记忆效应。第5节直接研究了这种潜在的污染,而本节则开发了一个新的评估数据集。这些问题由一个专门的团队创建,没有访问CodeExercises数据集或最终模型。他们以与HumanEval相同的格式创建了50个新问题,并指示设计那些不太可能出现在实际代码库或编码练习中的问题。以下是这样一个问题的示例:
对于在编码任务上评估语言模型的一个挑战是,模型的输出通常是二元的:要么代码通过了所有的单元测试,要么失败了。然而,这并没有捕捉到模型性能的微妙之处,因为它可能产生了几乎正确但有小错误的代码,或者一个完全错误但巧合地通过了一些测试的代码。可以说,评估模型编码技能的一种更具信息量的方式是将其输出与正确解决方案进行比较,并根据其与预期逻辑的匹配程度对其进行评分。这类似于在编码面试中评估人类的方式,面试官不仅运行代码,还检查解决方案的推理和质量。
因此,为了评估候选解决方案,本文采用了使用GPT-4来对解决方案进行评分的方法。这种方法有两个明显的优势:(1)通过使用GPT-4作为评分器,可以利用其知识和生成能力来获得对学生模型编码能力更精细和更有意义的信号,以及(2)它消除了测试的需要。提示指示LLM首先对学生的解决方案进行简短的口头评价,然后给出0到10分的成绩。
表2展示了对phi-1和竞争模型的结果。在新的非常规问题上的成绩与HumanEval相同(见表1)。phi-1再次取得了比StarCoder明显更高的分数,就像在HumanEval上一样。考虑到新问题没有机会污染训练数据,并且更重要的是,它们被设计为超出训练分布,这些结果极大地增强了对phi-1性能有效性的信心。
5 数据修剪以进行无偏性性能评估
图2.1中可以看到在CodeExercises上进行训练显着提高了模型在HumanEval基准上的性能。为了调查这种提升,作者通过移除与HumanEval中的文件"相似"的文件来修剪CodeExercises数据集。这个过程可以看作是"强形式"的数据去污染。然后,在这样修剪后的数据上重新训练phi-1模型,并且仍然观察到在HumanEval上的强劲性能。特别地,即使在激进地修剪了超过40%的CodeExercises数据集之后(这甚至修剪了与HumanEval仅有些许相似的文件,参见附录C),重新训练的phi-1仍然优于StarCoder。
作者认为这种数据修剪实验是评估性能的公平方式,比文献中通常基于训练和测试数据之间重叠度量的标准"污染"研究更有见地。为完整起见,作者首先进行了一个标准的污染实验,结果显示在这个标准意义上,CodeExercises并未受到HumanEval的污染。
5.1 N-gram重叠
N-gram度量基于共享的n个单词序列来衡量文本段的相似性。N-gram重叠分析表明,本文的数据集与HumanEval之间几乎没有字母级别的重叠。
5.2 嵌入和基于语法的相似性分析
作者还使用嵌入和基于语法的距离的组合。嵌入从预训练CodeGen-Mono 350M模型中导出,计算代码片段的嵌入之间的L2距离。作者观察到,嵌入距离成功捕获了整体代码语义相似的代码对。对于基于语法的距离,作者计算了两个给定代码片段的抽象语法树(AST)之间的(字符串)编辑距离。AST距离成功地识别了代码对之间的重叠部分,同时对非语法文本(例如变量/函数命名、注释和Python Docstring)保持了不可知性。对于CodeExercises的修剪,作者固定了嵌入距离的阈值,并测试了几个AST距离的匹配率τ。将τ从0.95变化到0.8,这对应于在CodeExercises的879.5K总问题中删除了42.5K到354K。
表3总结了重新训练的phi-1在修剪数据集上的性能。将HumanEval问题分为两个子集("相似"和"非相似"),基于它们是否在原始CodeExercises数据集中至少有一个接近匹配(对于给定的τ),分别报告了模型在每个HumanEval子集上的准确率。可以看到,即使在大幅修剪数据集之后,phi-1仍然大幅优于StarCoder-Prompted,这验证了性能提升不是由于数据集的"污染",即使后者术语的含义宽泛。
6 总结
本文研究表明,高质量数据对于语言模型在代码生成任务中的性能至关重要。通过创建"教科书质量"的数据,训练出的模型在模型大小和数据集大小上都远远领先于其他开源模型,如HumanEval和MBPP。作者相信,高质量数据能够极大地提高语言模型对于代码的学习效率,因为它们提供了清晰、自包含、富有教育性和平衡的编码示例。尽管phi-1模型仍然存在一些限制,如专门用于Python编码、缺乏领域特定知识和对风格变化的较低容忍度,但这些限制并非不可克服。更多的工作可以解决这些限制,并提高模型的性能。