To Code, or Not To Code? Exploring Impact of Code in Pre-training翻译

摘要

在预训练数据混合中包含代码,即使对于并非专门为代码设计的模型,也已成为 LLM 预训练中的常见做法。虽然从业者普遍认为代码数据在通用 LLM 的性能中起着至关重要的作用,但分析代码对非代码任务的精确影响的工作却非常有限。在这项工作中,我们系统地研究了代码数据对通用性能的影响。我们的问题是:预训练中使用的代码数据对代码生成以外的各种下游任务有何影响?我们对广泛的自然语言推理任务、世界知识任务、代码基准和 LLM-as-a-judge 胜率进行了广泛的消融和评估,模型的大小从 4.7 亿到 28 亿参数不等。在各种设置中,我们发现一致的结果是,代码是泛化的关键构建块,远远超出了编码任务的范围,并且代码质量的改进对所有任务都有巨大的影响。具体而言,与纯文本预训练相比,添加代码可使自然语言 (NL) 推理相对提高 8.2%,世界知识相对提高 4.2%,生成胜率提高 6.6%,代码性能提高 12 倍。我们的研究表明,在预训练期间提高代码质量和保留代码会产生积极影响。

1.介绍

在最近的突破中,数据的作用至关重要。最先进的模型强调了预训练数据混合、数据源多样性以及计算可用性作为性能关键驱动因素的重要性。一个关键问题是,数据的哪些属性可以带来最佳的总体性能?
  令人惊讶的是,即使模型并非明确旨在生成高质量代码,预训练中也经常包含代码。代码数据集在结构和文本特征方面与高质量网络数据集有很大不同。尽管如此,之前几代 LLM(如 PaLM、Gopher 和 Bloom)并未明确旨在支持代码生成,但它们在预训练混合中包含了一定比例的代码数据和高质量的自然语言数据。
  在当前最先进的模型中,不仅包含代码数据而且进一步增加代码比例已成为一种公认的规范——例如,Llama 3 的代码数据在预训练混合物中所占比例是 Llama 2 的四倍(Llama 3 为 17%,Llama 2 为 4.5%)。虽然从业者一致认为代码数据在 LLM 的性能中起着至关重要的作用,但分析代码对非代码任务的确切影响的研究却非常有限。先前的研究表明,包含代码数据具有特殊的附带好处,例如在有限数据范围内对泛化的影响、实体跟踪能力和数学推理。然而,迄今为止还没有详尽的研究系统地调查代码数据对总体性能的影响。在这项工作中,我们的问题是:预训练中使用的代码数据对代码生成之外的各种下游任务有何影响?
  我们着手进行一系列详尽的大规模可控预训练实验。这包括考虑在训练过程中添加代码是否有益、代码比例、扩展的作用以及添加的代码的质量和属性。虽然以严格的方式执行这些消融是一项昂贵的努力,但我们发现一致且有价值的结果,即代码为非代码性能提供了关键的改进。特别是,与纯文本预训练相比,对于我们的最佳变体,添加代码分别导致自然语言推理(NL)相对增加 8.2%、世界知识增加 4.2%、生成胜率提高 6.6% 和代码性能提高 12 倍。进一步执行带有代码的退火,与没有代码的退火相比,NL 推理提高 3.7%、世界知识提高 6.8% 和代码提高 20%,并导致额外的胜率增加 4.1%。
  这里有几个因素很重要,包括确保代码比例正确、通过包含合成代码和代码相关数据(例如提交)来提高代码质量,以及在退火期间等多个训练阶段利用代码。我们的结果表明,代码是泛化的关键构建块,远远超出了编码任务的范围,代码质量的提高对性能有巨大的影响。我们对广泛的基准进行了广泛的评估,涵盖世界知识任务、自然语言推理和代码生成,以及 LLM 作为评判者的胜率。在对 4.7 亿到 28 亿参数模型进行实验后,我们发现了以下详细结果:

  1. Code provides critical improvements to non-code performance。使用代码预训练模型进行初始化可提高自然语言任务的性能。具体而言,与纯文本预训练相比,对于我们的最佳变体,添加代码可使自然语言推理相对提高 8.2%,世界知识相对提高 4.2%,生成胜率提高 6.6%,代码性能提高 12 倍。
  2. Code quality and properties matter。使用标记式编程语言、代码相关数据集(例如 GitHub 提交和合成生成的代码)可提高预训练的性能。具体而言,与预训练中的基于 Web 的代码数据相比,使用更高质量的合成生成的代码数据集进行训练可分别使自然语言推理和代码性能提高 9% 和 44%。此外,与从不包含代码数据的代码模型进行初始化相比,从包含合成数据的代码模型进行持续预训练可分别使自然语言推理和代码性能相对提高 1.9% 和 41%。
  3. Code in cooldown enables further improvement across all tasks。在训练前退火阶段加入代码数据,即高质量数据集被提升权重,与退火前的模型相比,NL 推理能力提升 3.6%,世界知识能力提升 10.1%,代码性能提升 20%。更重要的是,带代码的退火阶段胜率比基线(无退火阶段的模型)高出 52.3%,与无代码的退火阶段相比,胜率高出 4.1%。

2.Methodology

在这里插入图片描述
  我们描述了预训练数据(第 2.1 节)、评估(第 2.2 节)、训练和模型细节(第 2.3 节)。图 1 显示了高级实验框架。第 3 节介绍了每个实验及其结果的详细细节。

2.1 Pre-training Data

在本节中,我们将描述预训练和退火数据集的详细信息。我们的目标是根据当前SOTA设置来评估代码在预训练中的作用。因此,我们考虑由两个阶段组成的预训练运行:1) continued pretraining and 2) cooldown。继续预训练是指训练从预训练模型初始化并针对固定token预算进行训练的模型。退火涉及在训练的最后阶段增加高质量数据集的权重并针对相对较少的token数量退火学习率。在训练结束时以较少的步骤增加高质量数据集的权重可以显著提高模型质量。
  Text dataset。我们使用 SlimPajama 预训练语料库作为自然语言文本数据的来源。SlimPajama 是一个基于 RedPajama-1.2T 的去重、质量过滤、多语料库开源数据集。SlimPajama 包含来自 CommonCrawl、C4、GitHub、Books、ArXiv、Wikipedia 和 StackExchange 的文档。我们过滤掉来自 GitHub 和 StackExchange 的所有文档,以删除代码和代码相关的数据源,并确保这是一个纯文本源。SlimPajama 总共有 6270 亿个token。删除所有代码源后,我们的文本预训练语料库总共有 5030 亿个token。
  Code datasets。为了探索代码数据不同属性的影响,我们在实验中使用了多个代码源:

  1. Web-based Code Data:对于我们的主要代码数据来源,我们从用于训练 StarCoder 的 Stack 数据集开始。Stack 由从 GitHub 抓取的经过许可的代码数据组成。我们应用质量过滤器,并根据文档数量限制为前 25 种编程语言。经过所有过滤步骤后,仅代码和markup子集的大小为 139B 个token。
  2. Markdown data:我们还分别处理了 Markdown、CSS 和 HTML 等markup风格的语言。经过所有的过滤步骤后,这个markup子集的大小为 180B 个 token。
  3. Synthetic Code Data:为了提高代码数据集的质量,我们使用专有的合成代码数据集,该数据集由经过形式化验证的 Python 编程问题组成。我们将其视为高质量的代码数据源(请参阅第 3.4 节中的详细信息)。最终的合成数据集包含 3.2 B 个代码token。
  4. Code Adjacent Data:最后,为了探索代码数据的不同属性,我们包含了一个代码数据版本,其中包括辅助数据,例如 GitHub 提交、jupyter 笔记本、StackExchange 线程。对于 GitHub 提交和 jupyter 笔记本,我们使用作为 Stack 一部分提供的数据集。我们使用 SlimPajama 的一部分的 StackExchange 版本。我们总共有 21.4 B个代码相关的数据token。

Pre-training cooldown datasets。退火涉及为预训练的最后步骤增加更高质量的数据集的权重。最近的研究发现它可以提高下游任务的性能,特别是有助于提供遵循指令的能力。我们选择了一种预训练冷却混合,包括高质量的文本、数学、代码和指令式文本数据集。

2.2 Evaluation

在这里插入图片描述
  我们的目标是系统地了解代码对总体性能的影响,这需要一套广泛的评估套件,该套件可扩展到代码生成以外的各种下游任务。为了实现这一目标,我们根据基准来评估模型,这些基准是模型在 1) 世界知识、2) 自然语言推理和 3) 代码性能方面能力的合理代表。此外,我们报告了由 LLM-as-a-judge 评估的胜率。表 1 显示了完整的评估套件及其各自的分组,以及使用的指标。
  我们在下面简要描述每个类别所使用的复合数据集:

  1. World knowledge。这些基准旨在衡量世界知识,测试知识记忆、检索和在给定上下文中回答问题的能力。我们将 Natural Questions Open 和 TriviaQA 作为数据集。我们报告了这两个基准的平均精确匹配分数。
  2. Natural language reasoning。自然语言 (NL) 推理包含 11 个基准,涉及基于自然语言的推理,例如问答、自然语言推理 (NLI)、句子补全、共指解析和通用智能。我们在表 1 中列出了组成基准的完整列表。我们报告了所有基准的平均准确度得分。
  3. Code。虽然我们主要关注的是总体性能,但我们也希望衡量代码生成性能的任何变化。对于代码基准测试,我们专注于函数完成任务。我们在 HumanEval-Python 和 MBPP 上进行评估。我们报告了这些基准测试的平均 pass@1 分数。

我们评估不同规模的性能:470 M 到 2.8 B 参数的模型。在我们较小的 470 M 参数规模下,模型能力有限,因此为了确保公平比较,我们仅比较所有模型均能实现高于随机性能的基准。这与 Muennighoff 等人 [2023a];Lozhkov 等人 [2024] 的先前研究一致。
  LLM-as-a-judge win-rates。除了特定任务的判别性能外,我们还使用 LLM-as-a-judge 的胜率来评估生成性能。LLM-as-a-judge 的基准已获得广泛认可,成为人工评估的自动化替代方案,而人工评估往往既费力又昂贵。LLM-as-a-judge,根据详细的提示比较两个补全情况,这些提示是特定任务的宝贵代理(例如,在两个候选答案之间进行选择,根据给定属性进行评分)。先前的研究表明,使用 LLM-as-a-judge 是合理的,并且符合人类的偏好。
  我们使用 Dolly-200 英语数据集,该数据集包含从 Dolly-15K 数据集中精心挑选的 200 个示例。这些提示是开放式的,可捕获通用的非代码用例。因此,使用此数据集进行评估是代码如何影响更流畅且常见开放式的问题的宝贵代理。考虑到模型在专业基准和更开放的生成上的表现之间的已知矛盾,这一点尤其有价值——最近的研究表明,随着开放式生成上的表现提高,传统专业任务的表现会下降。发生这种情况的原因是,大型语言模型的有监督微调会使模型在多个目标之间徘徊:1)改进传统的专业基准和2)训练 LLM 遵循指示、3)获得对话能力以及4)提供帮助和无害。因此,为了能够更全面地了解所有性能指标,我们还报告了胜率。
  对于我们的胜率评估,我们使用 Cohere Command-R+ 作为 LLM 评判标准。有关提示的详细信息,请参阅附录 B。

2.3 Training and Model Details

对于预训练模型,我们使用 470M 和 2.8B 参数解码器的自回归 Transformer 模型,这些模型使用标准语言建模目标进行训练。我们使用并行注意力层、SwiGLU 激活、MLP层中无bias以及词表为 256,000 的字节对编码 (BPE) tokenizer。所有模型均使用batch size为 512 的 AdamW 优化器和warm-up为 1325 步的余弦学习率进行预训练。我们使用的最大序列长度为 8192。
  Infrastructure。我们使用 TPU v5e 芯片进行训练和评估。所有模型均使用 FAX 框架进行训练。为了严格评估每次消融,我们总共预训练了 64 个模型。考虑到所需的规模和计算资源,这是一项艰巨的任务。每次针对 200B token的预训练运行,对于470M 模型需要 4,736 TPU 芯片小时,而针对 2.8B 参数模型则需要 13,824 TPU 芯片小时。每次对 40B token的退火运行,对于470M 模型需要 1,024 TPU 芯片小时。

3.Results and Discussion

在本节中,我们将报告每个实验变体的描述和总体结果。我们系统地研究了:(1)使用代码预训练模型初始化 LLM(第 3.1 节),(2)模型规模的影响(第 3.2 节),(3)预训练数据中代码的比例变化(第 3.3 节),(4)代码数据的质量和属性(第 3.4 节),(5)预训练退火中的代码数据(第 3.5 节)。最后,我们比较了得到的预训练配方(第 3.6 节)。图 1 显示了我们实验设计的关键杠杆。

3.1 Initializing an LLM with Code Pre-trained Models

在这里插入图片描述
  我们探索了预训练模型的不同初始化方法,以了解使用包含大量代码数据的 LM 作为初始化方法是否会提高性能。表 2 总结了这些关键的消融方法及其 token 计数。我们在下面简要介绍:

  • Text LM (text-only baseline):使用 glorot-normal 初始化对 400B 个token的纯文本数据从头开始预训练模型。
  • Balanced LM (balanced-only):在对 400B token进行预训练时,模型以相等比例的代码和文本数据(50% 文本和 50% 代码)进行训练。
  • Balance-initialized Text LM (balanced → text):该模型通过Balanced LM(50% 文本和 50% 代码)进行初始化,并使用 200B token的文本数据继续进行预训练。
  • Code-initialized Text LM (code → text):与其他变体不同,此模型使用代码语言模型进行初始化,该模型在 200B token的代码数据集上进行了预训练。代码数据集包含 80% 的代码数据和 20% 的markup 样式代码数据。然后,我们继续在文本上为另外 200B token对该模型进行预训练(我们在代码初始化模型(balanced → text,code → text)的继续预训练期间使用文本混合数据中 10% 的代码,以避免完全分布转变并在继续预训练期间保持代码的优势。)。
    在这里插入图片描述
      Natural Language Reasoning。如图 2 所示,使用 100% 代码预训练模型(code→text)进行初始化在自然语言 (NL) 推理基准测试中具有最佳性能,其次是balanced→text模型。code→text模型和balanced→text模型在 NL 推理任务上分别比纯文本基线高出 8.8% 和 8.2% 的相对改进。balanced-only 模型比基线提高了 3.2%。这表明,使用混合代码的预训练模型进行初始化对 NL 推理任务具有强烈的积极影响。进一步使用包含少量代码的文本混合进行继续预训练可获得最佳性能,code→textbalanced→text 模型均证明了这一点。
      World Knowledge。对于世界知识任务,我们发现balanced→text模型的性能优于所有其他变体,相对改进比code→text高出 21%,比text-only高出 4.1%。这表明,世界知识任务的性能似乎取决于初始化时更平衡的数据混合和继续预训练阶段的更大比例的文本。总体而言,与text-only预训练相比,代码数据对于世界知识任务仍然有益。
      Trade-offs between NL tasks and code generation。在代码生成任务中,balanced-only 模型取得了最佳性能,与balanced→textcode→text模型相比,我们看到了 46.7% 和 54.5% 的相对改进。这是意料之中的,因为balanced-only模型在整个预训练过程中包含 50% 的代码。然而,这种模型在更好的代码生成和更低的 NL 任务性能之间寻找平衡。与balanced-only模型相比,code→textbalanced→text分别在 NL 推理方面实现了 2.9% 和 2.3% 的相对增长,在世界知识方面实现了 17.3% 和 22.2% 的相对增长。
      Generative quality win-rates comparison。此外,我们将每种代码变体(code→textbalanced-only)的生成性能与text-only模型进行比较。我们报告了胜率,并观察到代码的存在对生成质量有强烈的积极影响。code→textbalanced-only模型的胜率都比text-only变体高出 6.6%。我们再次注意到,我们用于胜率计算的 Dolly-200-English 评估集是经过精心设计以反映开放领域问题并且是非代码评估。这证实了预训练组合中的代码数据不仅可以提高推理能力,还可以帮助模型产生更高质量的生成。我们在附录 C.1 中列出了这些实验的胜率。

3.2 Impact of Scale

在这里插入图片描述
  为了了解第 3.1 节的发现是否适用于更大的模型,我们使用在 470M 大小时的配置,使用相同的 token 预算训练了 2.8B 参数模型。图 9 显示了 2.8B 模型的结果与 470M 结果的比较。
  Comparison between 2.8B and 470M models。与 470M 结果相比,将模型大小扩展到 2.8B 参数可使所有任务类别的所有模型获得更高的性能。就自然语言推理和世界知识的平均性能而言,balanced→text 模型相对于 470M 大小的相同模型,扩展后的性能提高了 33.1%。code→textbalanced-only 模型的改进分别提高了 31.7% 和 30%。
  我们发现,自然语言推理的改进相对较小,balanced→textcode→textbalanced-only的相对增益分别为 5.3%、9.2% 和 5.2%。然而,所有模型变体的世界知识和代码性能几乎增加了三倍。特别是,与 470M 相比,2.8 B balanced→text 结果在世界知识方面增加了 2.7 倍,在代码评估方面增加了 2.5 倍。
  Trends between model variants in 2.8B。值得注意的是,在使用代码预训练模型进行初始化时,470M 参数规模中看到的相同趋势在 2.8B 模型中也成立。code→textbalanced→text模型比balanced-only模型提高了 6.9% 和 6.1% 的相对增益,但在代码生成性能方面却落后很多,相对下降了 43.1% 和 46.3%。这些结果表明,自然语言任务和代码生成之间的权衡随着模型大小的增加而增加。
  总体而言,我们扩大到更大尺寸的实验表明,我们的结果是正确的,并且与我们在 470M 参数消融时观察到的趋势一致。

3.3 Code Data Proportion in Pre-training

在这里插入图片描述
  在这些实验中,我们消除了预训练混合中的代码数据比例,以了解在非代码任务上实现性能最大化的最佳代码量。在这里,我们专注于随机初始化的预训练的第一阶段。我们训练了六个模型,使用 200B token,代码比例依次增加:0%、25%、50%、75%、90% 和 100%。剩余部分填充了文本数据。对于每个变体,我们独立训练一个新模型,以仔细消除不同代码比例的影响。
在这里插入图片描述
  Natural Language Reasoning and World Knowledge。对于自然语言推理,随着代码量的增加,在图 4 中,我们看到与纯文本(0% 代码)模型相比,性能有所提高。性能最好的模型是具有 25% 代码和 75% 文本的模型,与具有 0% 代码的模型相比,相对提高了 3.4%。虽然性能在高达 75% 的代码下仍能保持,但在更高的比例下,它开始迅速下降,与没有代码的模型相比,当模型在 100% 代码上进行训练时,相对下降幅度急剧上升 18.3%。
  对于世界知识任务,我们发现代码量与性能呈反比关系。如图 4 中间插图所示,与无代码模型相比,在 25% 代码时,性能略有下降,为 3.4%,而在 75% 代码时,性能下降幅度进一步扩大至 31%。全代码模型(100% 代码)无法在世界知识任务中发挥作用(相对于纯文本下降 86%),因为在预训练组合中没有数据源来获取所需的知识。
  Performance on Code。对于代码评估,随着代码量的增加,性能呈线性增长,最佳模型是纯代码模型。如图 4 右插图所示,与 25% 代码模型相比,100% 代码使代码基准测试增加了 2.6 倍。正如预期的那样,对于 0% 代码的模型,平均 pass@1 分数下降到 0。

3.4 Influence of Code Quality and Properties on General Performance

在这里插入图片描述
  在本节中,我们通过改变代码数据的质量和组成来研究其属性。我们首先 (a) 以从头开始​​训练的角度研究这一点,因为我们想要分离代码数据不同属性的确切影响。其次 (b),我们在继续预训练实验中加入了代码数据的最佳变体(高质量合成代码),以查看代码质量的影响是否转移。我们报告了 NL 推理和代码任务的表现。这些是我们研究的属性:

  • Markup-style Data:如第 2.1 节所述,我们将markup编程语言与其余基于 Web 的代码分开(附录 A.3)。我们用markup token替换了 20% 的纯代码token。
  • Code Adjacent Data:我们没有使用纯粹基于网络的代码数据,而是用代码相关数据集替换了 15% 的代码token - 包括 GitHub issues(5%)、StackExchange(5%)和 Jupyter Notebooks(5%),从而形成了code-adjacent模型。
  • Code Quality:为了控制代码质量,我们用合成生成的高质量代码数据集替换了 10% 的现有代码token。其余基于 Web 的代码数据比例保持不变,从而形成code-synth模型。

在这里插入图片描述
  Code-only pre-training。我们将上述变体与仅使用stack数据集中的基于 Web 的代码数据进行训练的模型进行比较,该模型构成了我们的基线模型。请注意,所有这些变体都使用相同数量的token进行预训练(200B 个token),以便进行公平比较。
  在图 5a 中,我们评估了代码质量和代码组成的影响。我们观察到,在所有变体中,包括不同的代码源和合成代码,相对于纯代码模型,自然语言性能都有所提高,但是,只有合成生成的代码才能提高代码基准。我们将其与我们的代码评估联系起来,我们在 Python 中测量性能,因此不同的编程语言或代码相关数据会略微降低结果。在这里,与纯代码模型相比,code+markupcode+adjacent导致 NL 推理相对提高 2.8% 和 6.3%,但导致代码评估下降 15.7% 和 9.4%。
  我们的合成代码数据(code+synth)是具有最好的消融结果。考虑到它在整个数据集中所占的份额相对较小,这一点尤其令人印象深刻。尽管权重只有 10%,但与纯代码的基线相比,加入合成数据可以使自然语言推理相对提高 9%,代码基准相对提高 44.9%。我们注意到,考虑到可用的合成数据量与code-adjacent 数据(3.2 B token vs 21.4 B token)或 code+markup 数据(3.2 B token vs 40 B token)相比有限,以及训练前分配期间的权重(synthetic-data、code-adjacent和 code-markup 分别为 10% vs 15% vs 20%),合成数据的提升更加令人印象深刻。这表明,未来改进的一个关键杠杆是增加此类高质量代码数据源的比例。
  Continual pre-training。在这里,基于纯代码预训练的结果,我们将code+synth 纳入我们的最佳继续预训练变体(balanced+synth→text)。我们将其与没有合成代码数据的相同变体(balanced→text)进行比较,以评估将合成数据应用到此设置的好处。同样,我们在这些实验中使用相同数量的代码和文本token。
  如图 5b 所示,balanced+synth→text 在 NL 推理和代码方面分别比 balanced→text 实现了 2% 和 35% 的相对提升。这进一步证实,即使是一小部分高质量的代码数据,不仅可以提高代码预训练的性能,而且在使用文本数据进行持续预训练后,还可以提高代码和非代码的性能。

3.5 Code in Pre-training Cooldown

在这里插入图片描述
在这里插入图片描述

3.6 Comparing Pre-Training Recipes

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值