AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


微软最强小模型:打败大模型,你只需要“教科书级质量”的数据 I
发布日期:2024-07-15 13:59:47 浏览次数: 1716


摘要

我们推出了phi-1,这是一款全新的大型代码语言模型,其规模显著小于市面上的其他竞品模型。phi-1是一款基于Transformer的模型,拥有13亿个参数。它利用8个A100 GPU,在仅4天的时间内完成了训练。训练数据包括从网络上精选的“教科书级质量”的数据(60亿个词元)以及通过GPT-3.5生成的合成教科书和练习题(10亿个词元)。尽管phi-1的规模相对较小,但它在HumanEval基准测试中达到了50.6%的pass@1准确率,在MBPP基准测试中达到了55.5%的准确率。
与我们在编码练习题数据集上进行微调之前的模型phi-1-base相比,以及与我们采用相同训练流程但规模更小的3.5亿参数模型phi-1-small(在HumanEval基准测试中仍能达到45%的准确率)相比,phi-1展现出了令人惊讶的涌现特性。

1 引言

过去十年间,训练大型人工神经网络的技术取得了非凡的进步,尤其是在Transformer架构被发现之后。然而,支撑这一成功的科学原理仍相当有限。在Transformer架构被引入的同时,大量纷繁复杂的研究结果中逐渐显现出一种秩序,即随着计算量的增加或网络规模的扩大,性能会呈现出一定程度的可预测性提升,这一现象现在被称为“扩展定律”。随后的深度学习扩展探索便是在这些扩展定律的指导下进行的,而对这些定律变体的发现则迅速推动了性能的提升。
在本研究中,我们追随Eldan和Li的脚步,探索了沿着另一个维度——数据质量所能获得的改进。长期以来,人们一直知道高质量的数据能带来更好的结果,例如,数据清洗是现代数据集创建的重要组成部分,它还能带来其他附带好处,如数据集规模相对较小或允许数据多次传递。Eldan和Li最近在TinyStories(一个为神经网络学习英语而合成的高质量数据集)上的工作表明,高质量数据的影响远不止于此:提高数据质量可以极大地改变扩展定律的形状,从而有可能用更精简的训练/模型来匹配大规模模型的性能
在本研究中,我们超越了Eldan和Li的初步尝试,展示了高质量数据甚至可以改善大型语言模型(LLMs)的最先进水平,同时大幅度减少数据集大小和训练计算量。重要的是,需要较少训练的小型模型可以显著降低LLMs的环境成本。
我们专注于训练用于代码的LLMs,特别是根据文档字符串编写简单的Python函数,如[CTJ+21]所述。后者工作中提出的HumanEval评估基准已被广泛用于比较LLMs在代码上的性能。我们通过训练一个名为phi-1的13亿参数模型,展示了高质量数据在打破现有扩展定律方面的强大能力。该模型在大约70亿词元(总共略超过500亿词元)的数据上进行了大约8次遍历训练,随后在不到2亿词元的数据上进行了微调。简而言之,我们首先在“教科书质量”的数据上进行预训练,这些数据既包括通过GPT-3.5生成的合成数据,也包括从网络来源筛选的数据,然后我们在“类似教科书练习题”的数据上进行微调。
尽管在数据集和模型规模上,phi-1都比竞品模型小几个数量级(见表1),但我们在HumanEval基准测试中达到了50.6%的pass@1准确率,在MBPP(主要是基础Python程序)基准测试中达到了55.5%的pass@1准确率,这是使用单个LLM生成器时自报的最佳成绩之一。

更多相关工作:我们的工作是最近使用LLMs进行程序合成计划的一部分。我们的方法也是利用现有LLMs合成数据以训练新一代LLMs这一新兴趋势的一部分。目前,关于这种“递归训练”是否可能导致生成的LLMs适用范围变窄,学界存在争议,而也有人则提出了相反的观点。本文我们专注于一个狭义的任务,在这种情况下,在特定任务上获得比教师LLM更好的性能似乎是合理的。

2 训练细节和高质量数据的重要性

正如论文标题所暗示的,我们模型的核心要素是依赖教科书质量的训练数据。与以往使用标准文本数据源进行代码生成的工作不同,如The Stack(包含具有宽松许可证的存储库中的源代码)和其他基于网络的数据集(如StackOverflow和CodeContest),我们认为这些数据源并不是教授模型如何算法性地推理和规划的最佳选择。另一方面,我们的模型架构和训练方法相当传统,因此本节我们主要解释我们是如何筛选和整理我们的数据的。
标准的代码数据集构成了一个庞大且多样化的语料库,涵盖了广泛的主题和用例。然而,通过对手动随机抽取的样本进行检查,我们观察到其中许多代码片段对于学习编程基础知识来说并不十分具有启发性,并且存在以下几个缺点
  • 许多样本不是自包含的,这意味着它们依赖于片段之外的其他模块或文件,这使得在没有额外上下文的情况下很难理解。
  • 典型的示例并不涉及任何有意义的计算,而是由一些琐碎或模板化的代码组成,如定义常量、设置参数或配置GUI元素。
  • 包含算法逻辑的样本通常被埋藏在复杂或文档不完善的函数中,这使得它们难以跟踪或从中学习。
  • 示例偏向于某些主题或用例,导致数据集中编码概念和技能的分布不均衡。
人们只能想象,对于一个人类学习者来说,尝试从这些数据集中学习编程技能会有多么令人沮丧和低效,因为他们必须处理数据中的大量噪声、歧义和不完整性。我们假设这些问题也影响了语言模型的性能,因为它们降低了将自然语言映射到代码的信号的质量和数量。我们推测,语言模型将受益于一个具有与优秀“教科书”相同品质的训练集:它应该清晰、自包含、具有启发性且内容均衡。
在这项工作中,我们直接应对这一挑战,并展示通过有意选择和生成高质量数据,我们可以在代码生成任务上实现最先进的结果,同时使用的模型规模远小于现有方法,且计算量也更少。我们的训练依赖于三个主要数据集:
  • 一个过滤后的代码语言数据集,它是The Stack和StackOverflow的子集,通过基于语言模型的分类器(包含约60亿个标记)获得。
  • 一个合成教科书数据集,包含GPT-3.5生成的Python教科书中的不到10亿个标记。
  • 一个小型合成练习题数据集,包含约1.8亿个Python练习题和解答的标记。
综合起来,上述数据集包含的标记总数不到70亿。我们将过滤后的代码语言数据集和合成教科书数据集组合称为“CodeTextbook”,并在预训练阶段使用它来获得我们的基础模型phi-1-base——该模型在HumanEval任务上已经达到了具有竞争力的29%的性能然后,我们使用包含约1.8亿个标记的合成练习题数据集(称为“CodeExercises”)对phi-1-base模型进行微调,以获得phi-1模型尽管“CodeExercises”数据集规模较小,但使用它进行微调不仅对于如图2.1所示在生成简单Python函数方面取得大幅提升至关重要,而且更广泛地来说,它解锁了我们phi-1模型中许多在phi-1-base中未观察到的有趣的新兴能力。

2.1 使用基于Transformer的分类器过滤现有代码数据集

我们从公开可用的Python代码数据集开始:我们使用The Stack和StackOverflow去重版本的Python子集,这两个数据集合计包含超过3500万个文件/样本,总计超过350亿个标记我们使用GPT-4对其中一小部分文件(约10万个样本)的质量进行标注:给定一个代码片段,模型被提示“确定它对于一个旨在学习基本编码概念的学生来说的教育价值”。

然后,我们使用这个已标注的数据集来训练一个随机森林分类器该分类器使用预训练的codegen模型的输出嵌入作为特征来预测文件/样本的质量。我们注意到,与我们在下文中广泛使用的用于生成合成内容的GPT-3.5不同,我们仅将GPT-4用于对The Stack和StackOverflow样本的一小部分进行质量标注,且使用频率极低。因此,我们认为我们对GPT-4的使用仅仅是为了避免繁琐的人工标注工作。

即使不使用下面讨论的合成数据集,我们的过滤方法也显著提高了模型性能:对于在未经过滤的Stack(去重后的Python代码)和StackOverflow上训练的3.5亿参数模型,即使在训练了96,000步(约2000亿个标记)后,HumanEval的性能也仅达到12.19%的饱和水平而在经过过滤的子集上训练后,HumanEval的性能在36,000步后就达到了17.68%。通过在下文讨论的过滤数据集和合成教科书数据集的组合上进行训练,我们进一步将这一性能提升至20.12%(如图2.1所示)。

2.2 合成教科书数据集的创建

在创建高质量代码生成数据集时,一个主要挑战是确保示例的多样性和非重复性。这里的多样性意味着示例应涵盖广泛的编码概念、技能和场景,并且在难度、复杂度和风格上应有所不同。多样性之所以重要,有几个原因:它使语言模型接触到代码中以不同方式表达和解决问题的方法,降低了过拟合或记忆特定模式或解决方案的风险,并提高了模型对未见或新任务的泛化能力和鲁棒性。然而,实现多样性并非易事,尤其是在使用另一个语言模型生成的合成数据时。简单地提示模型生成一本编程教科书或一系列练习题,即使指令或参数有所变化,也很可能导致数据集非常单一和冗余,其中相同的概念和解决方案以微小的变化反复出现。这是因为语言模型倾向于根据其训练数据和先验知识遵循最可能或最常见的路径,并且缺乏创造力或动力去探索生成代码的替代或新颖方式。因此,需要找到合适的“技巧”,使语言模型在保持示例质量和连贯性的同时,在输出中更具创造性和多样性。受到[EL23]的启发,该研究中通过在提示中包含从固定词汇表中随机选择的单词子集,并要求这些单词以某种方式组合在生成的文本中,从而创建了一系列多样化的短篇故事。我们也寻找在提示中注入随机性的方法,以生成多样化的数据集。

合成教科书数据集:该数据集由GPT-3.5生成的Python教科书组成,包含不到10亿个标记,这些教科书是合成的,旨在为自然语言丰富的文本与相关的代码片段交替出现提供一个高质量的资源。我们进一步针对这些教科书的内容,涵盖了促进推理和基础算法技能的主题。在这里,多样性是通过为生成的教科书提供主题和目标受众的约束来实现的。以下是合成教科书中的一个示例文本:

CodeExercises 数据集:这是一个小型的合成练习题数据集,包含不到1.8亿个Python练习题和解决方案的标记。每个练习题都是一个需要完成的函数的docstring(文档字符串)。该数据集的目标是使模型能够根据自然语言指令执行函数补全任务。这个数据集也是由GPT-3.5生成的,其中实现多样性的主要手段是通过限制函数名称。对于这个特定的数据集,我们在后续章节中进行了明确的去污染和替代评估,以确保在微调过程中不会遇到与HumanEval基准测试中类似的问题。以下是一个合成生成的练习题的示例片段:

2.3 模型架构和训练

我们使用了仅解码器的Transformer模型,该模型采用了FlashAttention实现的多头注意力机制。我们还并行配置了MHA和MLP层,这一做法遵循了近期的一些模型,如CodeGen、PaLM和GPT-NeoX。我们的13亿参数phi-1模型架构包含24层,隐藏维度为2048,MLP内部维度为8192,以及32个每个维度为64的注意力头。较小的3.5亿参数phi-1-small模型包含20层,隐藏维度为1024,MLP内部维度为4096,以及16个每个维度为64的注意力头。此外,我们还使用了旋转位置嵌入,旋转维度为32。我们还使用了与codegen-350M-mono相同的分词器。除了FlashAttention外,我们的模型没有使用其他技术,如Fill-In-the-Middle(FIM)或多查询注意力(MQA),这些技术可能会进一步提升性能和效率。

在预训练和微调阶段,我们将各自的数据集连接成一个一维数组,并使用“⟨∣endoftext∣⟩”标记来分隔文件。我们在从数据集数组中切出的长度为2048的序列上进行模型训练,采用下一个标记预测损失。我们使用fp16训练和AdamW优化器,采用线性预热-线性衰减的学习率计划,以及0.1的注意力和残差丢弃率。我们使用deepspeed在8个Nvidia-A100 GPU上进行训练。我们的预训练基础模型phi-1-base在不到4天的时间内完成训练。在同一硬件上,对phi-1进行微调又额外花费了7小时。

预训练:phi-1-base模型在CodeTextbook数据集(经过筛选的代码-语言语料库和合成教科书)上进行训练。我们使用了有效批量大小为1024(包括数据并行和梯度累积),最大学习率为1e-3,并在750步内进行预热,权重衰减为0.1,总共训练了36,000步。我们选择第24,000步的检查点作为我们的phi-1-base——这相当于在我们的CodeTextbook数据集上进行了大约8个周期的训练,总共训练了超过500亿个标记尽管这个模型的大小和计算量都不大,但它已经在HumanEval上达到了29%的准确率。

微调:phi-1是通过在CodeExercises数据集上对phi-1-base进行微调得到的。对于微调,我们使用了与预训练相同的设置,但超参数不同:我们使用了有效批量大小为256,最大学习率为1e-4,并在50步内进行预热,权重衰减为0.01。我们总共训练了6,000步,并选择了最佳检查点(每1,000步保存一次)。

3 在CodeExercises微调后模型能力的显著提升

图2.1显示,在小型CodeExercises数据集(<2亿标记)上进行微调后,HumanEval的改进幅度最大。CodeExercises完全由使用基本Python库的简短Python任务组成。在本节中,我们将展示一个相当显著的现象,即微调后的模型在执行微调数据集中未出现的任务时也表现出实质性的改进。这包括管理复杂的算法任务和使用外部库。这表明,我们的微调过程可能有助于模型重新组织和巩固在预训练期间获得的知识,即使这些知识在CodeExercises数据集中并未明确体现。在本节中,我们将重点定性地比较和对比我们微调后的模型phi-1与其预训练的13亿参数基础模型phi-1-base的能力。

3.1 微调提高了模型的理解能力

通过我们自己创建的一个简单的Python函数,我们观察到微调后的模型在理解和遵循指令方面表现出了更高的水平。特别是,我们发现phi-1-base在处理提示中的逻辑关系时遇到了困难,而phi-1能够解释问题并正确生成答案。在这个例子中,即使我们的3.5亿参数的phi-1-small模型也显示出了一定程度的问题理解能力,尽管它给出的解决方案是错误的。我们在交互过程中始终观察到这样的趋势。

3.2 微调提高了模型使用外部库的能力

我们在这里展示,尽管我们的练习题中没有包含Pygame和Tkinter等外部库,但在CodeExercises上进行微调却意外地提高了模型使用这些外部库的能力。这表明我们的微调不仅改进了我们针对的任务,还使得从预训练中提取不相关任务变得更加容易。作为参考,图3.1显示了我们的CodeExercises数据集中包导入的分布情况。

PyGame示例:我们从一个PyGame示例开始,该示例要求模型生成代码来移动一个球:

上面的代码片段展示了一个简单PyGame程序的主循环,该程序使球在屏幕上弹跳。phi-1正确地应用了PyGame函数来更新和绘制球,按照提示进行操作。phi-1-base和phi-1-small生成的函数调用在语法上是正确的,但在语义上与任务无关。我们可以看到,phi-1-base显示出一些使用适当API调用的能力,但它未能遵循任务的逻辑,而经过微调后的phi-1-small理解了逻辑,但由于容量不足,无法学习正确的函数调用。

Tkinter示例:我们的第二个示例是一个Tkinter应用程序,我们要求模型在用户点击按钮时相应地更新文本框。

这三个模型的完成情况在理解提示方面存在巨大差距。phi-1-base和phi-1-small都没有使用正确的Tkinter API,而是编造了无意义的函数调用。另一方面,phi-1正确地实现了图形用户界面(GUI)和所有函数(只是没有正确复制“pewpewpew?”)。我们在附录A中提供了另外两个关于pytorch和pyplot的示例。

聊天模式示例:最后,我们展示了尽管聊天数据仅在预训练中使用,并未在微调中使用,但phi-1的聊天能力仍优于phi-1-base。

4 使用大型语言模型评分的非传统问题评估

对于phi-1在HumanEval上出人意料的良好表现(见表1和图2.1),一个潜在的担忧是,这可能源于合成CodeExercises数据集的污染所导致的记忆现象。我们在第5节中直接研究了这种潜在的污染,而本节则通过设计一种非常规的新评估来应对这一担忧,这种评估不太可能出现在我们的训练数据集中。为了最大限度地减少偏见和泄漏,新的评估问题由一个专门团队创建,他们没有访问CodeExercises数据集或最终模型。他们按照HumanEval的相同格式创建了50个新问题,并指示设计在现实世界代码库或编程练习中不太可能出现的问题。以下是此类问题的一个示例:

评估语言模型在编码任务上的表现时的一个挑战是,模型的输出往往是二元的:要么代码通过了所有单元测试,要么失败了。然而,这并不能全面反映模型的表现,因为它可能生成了几乎正确但存在微小错误的代码,或者生成了完全错误的代码却恰巧通过了某些测试。可以说,一种更有信息量的评估模型编码能力的方法是将其输出与正确解决方案进行比较,并根据其与预期逻辑的匹配程度进行评分。这与人类在编程面试中的评估方式类似,面试官不仅会运行代码,还会检查推理过程和解决方案的质量。

为了评估候选解决方案,我们采用了使用GPT-4进行评分的方法。这种方法有两个显著的优势:(1)通过使用GPT-4作为评分者,我们可以利用其知识和生成能力来获得对学生模型编码能力的更细致和有意义的信号;(2)它省去了编写测试的需要1。我们的提示首先要求大型语言模型(LLM)用简短的口头评价来评估学生的解决方案,然后给出0到10的分数。

请参阅表2,以了解phi-1和竞争模型的结果。我们针对新的非传统问题给出的评分与HumanEval的排名相同。phi-1再次在HumanEval上取得了显著高于StarCoder的分数。鉴于这些新问题没有机会污染训练数据,并且进一步设计为超出训练分布之外,这些结果极大地增强了我们对phi-1性能有效性的信心。

5 用于无偏性能评估的数据修剪

在图2.1中,我们看到在CodeExercises数据集上的训练显著提高了模型在HumanEval基准测试上的性能。为了研究这种提升,我们提出对CodeExercises数据集进行修剪,删除与HumanEval中“相似”的文件。这个过程可以被视为数据去污染的一种“强化形式”。然后,我们在这样的修剪后的数据上重新训练我们的模型,并仍然观察到HumanEval上的强劲性能。特别是,即使在积极修剪了超过40%的CodeExercises数据集(这甚至包括与HumanEval只有模糊相似性的文件)之后,重新训练的phi-1仍然优于StarCoder。

我们相信,这种数据修剪实验是一种公平的性能评估方式,并且比文献中通常基于训练数据和测试数据之间重叠度量的标准“污染”研究更有洞察力。为了完整性起见,我们首先进行了一项标准的污染实验,该实验表明,CodeExercises数据集在这种标准意义上并未被HumanEval污染。

5.1 N-gram重叠

N-gram基于共享的n个词序列来衡量文本片段的相似性。我们计算了HumanEval中每个问题的docstring与生成的CodeExercises数据集中每个练习的docstring之间的n-gram重叠。我们发现,有4个HumanEval问题与数据集中至少一个条目的13-gram存在重叠。进一步调查后,我们发现这4个13-gram重叠案例均为误报,例如以下示例所示。我们的n-gram重叠分析表明,我们的数据集与HumanEval在逐字上的重叠非常小。

正如我们刚才所看到的,n-gram分析在发现HumanEval和CodeExercises之间相似的代码片段方面不够精细。因此,我们采用了一种结合嵌入和基于语法的距离的方法。对于嵌入距离,我们计算了代码片段嵌入之间的L2距离,这些嵌入来自于预训练的CodeGen-Mono 350M模型。我们观察到,嵌入距离成功地捕捉到了整体代码语义相似的代码对,这可以通过Python文档字符串、函数/类名以及代码结构来推断。

对于基于语法的距离,我们计算了两个给定代码片段的抽象语法树(AST)之间的(字符串)编辑距离。AST距离能够成功识别代码对之间的重叠部分,同时不受非语法文本(如变量/函数命名、注释和Python文档字符串)的影响。在修剪CodeExercises时,我们为嵌入距离设定了一个阈值,并测试了多个AST距离的匹配率τ。我们将τ在0.95到0.8之间变化,这对应于从CodeExercises中的879.5K个总问题中移除42.5K到354K个不等的问题。

表3总结了我们在修剪后的数据集(τ = 0.95, 0.9, 0.85 和 0.8)上重新训练的phi-1模型的性能,并将其与在完整CodeExercises数据集上训练的原始phi-1模型以及拥有155亿参数的StarCoder-Prompted模型进行了比较。我们根据HumanEval问题是否在原始CodeExercises数据集中至少有一个接近的匹配项(对于给定的τ值),将HumanEval问题分为两个子集:“相似”和“非相似”。然后,我们分别报告了模型在每个HumanEval子集上的准确率。可以看出,即使在大幅修剪数据集之后,phi-1模型仍然以较大的优势(13个百分点)超越了StarCoder-Prompted模型,这验证了我们的性能提升并非由于数据集“污染”所致,即使这里的“污染”一词被宽泛地理解。此外,还注意到所有模型在HumanEval的“非相似”子集上的准确率都低于“相似”子集。

6 结论

正如一本全面且精心编写的教科书可以为学生提供掌握新学科所需的知识一样,我们的工作展示了高质量数据在磨练语言模型在代码生成任务中能力方面的显著影响。通过打造“教科书级别”的数据,我们能够训练出一个模型,尽管其模型大小仅为其他开源模型的十分之一,数据集大小更是小了百倍,但在HumanEval和MBPP等编码基准测试中,该模型的表现却超越了几乎所有开源模型。我们假设,这样高质量的数据极大地提高了语言模型在代码学习方面的效率,因为它们提供了清晰、独立、富有指导性和均衡的编码概念和技能示例。

然而,与更大的代码模型相比,我们的模型仍存在一些局限性。首先,phi-1专注于Python编程,这限制了其相对于多语言模型的通用性。其次,phi-1缺乏大型模型所拥有的特定领域知识,如使用特定API编程或使用不太常见的包。最后,由于数据集的结构化特性和在语言及风格方面的缺乏多样性,phi-1对于风格上的变化或提示中的错误(例如,当提示中存在语法错误时,其性能会大幅下降)的鲁棒性较差。我们在附录B中详细讨论了这些局限性,并给出了phi-1失败模式的示例。

这些局限性似乎都不是根本性的,通过进一步的研究,我们的方法可以用来解决每一个问题,尽管目前尚不清楚为了克服这些局限需要多大的规模扩展(无论是模型大小还是数据集大小)。我们还认为,如果使用GPT-4而不是GPT-3.5来生成合成数据,可能会取得显著的进步,因为我们注意到GPT-3.5生成的数据错误率较高。有趣的是,尽管存在这些错误,phi-1仍然能够达到如此高的编码熟练度(在[AZL23]中也观察到了类似的现象,即语言模型可以在100%错误率的数据上进行训练,并在测试时生成正确答案)。

更一般地说,我们的工作为开发高质量数据集的良好方法提供了证据,这是推动自然语言处理及相关领域研究的核心方向然而,创建高质量数据集并非易事,它面临着需要解决的多个挑战。一个挑战是确保数据集涵盖了模型需要学习的所有相关内容和概念,并且以平衡和具有代表性的方式做到这一点。另一个挑战是确保数据集真正具有多样性和非重复性,以便模型不会简单地过拟合数据或记忆特定的模式或解决方案。这需要在数据生成过程中找到注入随机性和创造性的方法,同时保持示例的质量和连贯性。此外,即使在创建了这样的数据集之后,我们也缺乏一种良好的方法来测量和评估数据的多样性和冗余性。例如,如果我们有一个包含编程练习的数据集,那么很难确定每个练习存在多少种不同的变体,以及它们在数据集中的分布情况。最后,由于语言模型本身将用于为未来的语言模型整理数据,这进一步加剧了训练此类模型的伦理和社会影响方面的紧迫性,如参与此过程的数据和模型的责任感、透明度和偏见。



53AI,企业落地应用大模型首选服务商

产品:大模型应用平台+智能体定制开发+落地咨询服务

承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

与创始人交个朋友

回到顶部

 
扫码咨询