预训练中代码语料的作用

文摘   2024-08-30 10:55   新加坡  

本文涉及到的详细测试代码和测试步骤放置于:

https://github.com/davidsajare/david-share.git

的:Deep-Learning/Make-High-Quality-Dataset-From-WARC,本文中不再赘述代码实现。

欢迎给repo点亮Star,您的点赞是作者持续创作的动力。


本文正文参考论文:https://arxiv.org/abs/2408.10914

在大型语言模型(LLMs)的预训练数据中包含代码已经成为标准做法,即使在这些模型明确用于代码生成任务之前也是如此。如今,各种编程语言(如Python、Java和HTML)的代码构成了很多LLMs(如Llama 3、Gemma 2和Qwen2)预训练数据的重要部分,从而提高了它们执行代码生成任务的能力。

然而,在训练数据中包含代码对非代码任务(如自然语言生成、推理和世界知识)的影响尚未得到充分研究。

例如:在LLM训练数据中包含代码是提高还是降低了它们在非代码任务上的表现?Cohere在其最近的论文中探讨了这个问题:

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

LLMs的预训练数据是什么?

最近的LLMs在数十亿个标记上进行预训练,主要来自网络爬取的数据。CommonCrawl是LLMs预训练数据的主要来源。然而,这些数据非常嘈杂,需要仔细过滤以保留对训练最有用的信息。有效的过滤技术对于创建高质量的预训练数据集至关重要。


为了最大化LLMs的实用性,预训练数据通常包括英语文本、其他语言和源代码的混合。例如,Llama 2和Llama 3的预训练数据分别包含4.5%和17%的代码。对于Llama 3,这相当于其预训练数据集中包含了25.5亿个代码tokens。

创建预训练数据混合物

Cohere在其论文中探讨的主要问题是:在LLMs的预训练数据中应包含多少代码以及哪个比例?

为此,Cohere从头开始训练了几个LLMs,模型参数分别为4.7亿和28亿。

他们采用了两阶段的预训练策略:继续预训练和冷却。继续预训练涉及在固定的token预算内进一步训练现有模型,而冷却阶段则专注于高质量数据集,并在训练的最后阶段逐渐降低学习率。冷却策略已被证明可以提高模型性能,特别是在训练的最后阶段。

继续预训练(Continued Pre-training)

  • 定义:继续预训练是指在初始预训练之后,继续在一个固定的token预算内进一步训练模型。这一阶段的目标是通过更多的训练数据和计算资源,进一步提升模型的性能。

  • 特点:在这一阶段,模型可能会接触到更多样化的数据,包括不同领域的文本和代码,以增强其在各种任务中的表现。

    冷却阶段(Cooldown Phase)

  • 定义:冷却阶段是训练过程的最后阶段,主要目的是通过逐渐降低学习率和使用高质量的数据集,帮助模型更好地收敛并达到最佳性能。

  • 特点

    • 逐渐降低学习率:在这一阶段,学习率会逐渐降低,使模型的参数更新幅度变小,从而更稳定地调整参数,找到更好的局部最优解。

    • 高质量数据:冷却阶段通常会使用经过精心筛选和过滤的高质量数据集进行训练,以提高模型的泛化能力和在下游任务中的表现。

      对于预训练数据的文本部分,他们使用了SlimPajama语料库,这是一个从CommonCrawl、C4和维基百科等各种来源去重和质量过滤的数据集。过滤掉与代码相关的内容后,该语料库包含5030亿个标记。

      为了探讨代码对预训练的影响,他们还包括了几个代码数据集:

  • 基于网络的代码数据:该数据集来自GitHub,经过质量过滤并限制在前25种编程语言,总计1390亿个标记。

  • Markdown数据:一个单独的标记语言数据集,如Markdown、CSS和HTML,总计1800亿个标记。

  • 合成代码数据:一个高质量的、合成生成的数据集,包括形式验证的Python代码,总计32亿个标记。

  • 代码相关数据:包括辅助数据,如GitHub提交和Jupyter笔记本,总计21.4亿个标记。

    在冷却阶段,他们优先考虑高质量数据集,包括文本、数学、代码和指令跟随数据。该阶段已被证明可以提高模型在下游任务中的表现。

    训练细节

    本研究中使用的预训练模型是仅解码的自回归Transformer模型。这些模型具有先进的特性,如并行注意力层、SwiGLU激活和一个具有256k条目(非常大)的BPE分词器。训练使用AdamW优化器,批量大小为512个序列,最大序列长度为8192个标记,并采用余弦学习率调度。训练和评估过程在Google Cloud提供的TPU v5e芯片上进行,耗费了数千个TPU小时。

    主要发现

    该研究探讨了不同的预训练语言模型初始化策略,以确定包含大量代码数据是否能提高性能。探讨了四种主要策略:

  1. 仅文本基线;

  2. 代码和文本等量的平衡模型;

  3. 随后在文本上微调的平衡模型;

  4. 用代码数据初始化然后在文本上微调的模型。

    这是本研究中最出人意料的发现:结果(见图2)显示,用代码数据初始化显著提高了自然语言推理性能,代码初始化和平衡初始化模型分别比仅文本基线高出8.8%和8.2%。换句话说,如果你的目标任务是自然语言推理任务,首先用代码训练你的LLMs。



    对于需要世界知识的任务,平衡初始化模型取得了最佳结果,超过了代码初始化模型和仅文本基线。这表明在初始化期间代码和文本的平衡混合,然后进行文本为主的预训练,对于这些任务最为有效。相比之下,对于代码生成任务,保持50%代码比例的平衡模型表现最佳,尽管它在自然语言任务中牺牲了一些性能。

    此外,研究发现用代码数据初始化的模型提高了生成质量。包含代码数据不仅提高了推理能力,还提高了整体生成性能,表明代码数据在各种任务中都是有益的。

    以下是一些值得考虑的用于预训练LLMs的额外发现:

    扩展模型规模

    当模型规模从4.7亿参数增加到28亿参数时,所有任务的性能显著提高,如预期(见图3)。较大的模型在平衡和代码初始化预训练中受益更多,在自然语言推理、世界知识和代码任务中表现出更好的提升。


代码比例
研究人员调查了预训练数据混合中代码的最佳比例,以最大化非代码任务的性能(见图4)。他们在2000亿个标记上训练了六个具有不同代码比例(0%、25%、50%、75%、90%和100%)的模型,其余数据由文本组成。

  • 对于自然语言推理任务,性能随着代码比例的增加而提高,在25%代码时达到峰值,比仅文本模型提高了3.4%。然而,当代码超过75%时,性能急剧下降,在100%代码时下降了18.3%。

  • 对于世界知识任务,增加代码比例导致性能下降,在25%代码时下降了3.4%,在100%代码时由于缺乏相关知识来源而严重下降了86%。

  • 对于编码任务,性能随着代码的增加线性提高,代码唯一模型取得了最佳结果,比25%代码模型提高了2.6倍。没有代码的模型在代码评估中表现不佳。

    代码数据质量

    高质量的合成代码,即使数量较少,也显著提升了代码和自然语言任务的性能(见图5)。这一发现强调了预训练中使用的代码数据不仅数量重要,质量也同样重要。用高质量合成代码数据训练的模型甚至超过了用标准网络来源代码训练的模型,这表明未来的努力应集中在策划或生成高质量代码数据集上,以进一步提高模型性能。


在冷却阶段

在冷却阶段包含代码数据——在此阶段,模型通过仔细调整的学习率和专注于高质量数据进行微调——被证明特别有益。该阶段提高了所有任务的性能,特别是在生成任务中。

建议和结论

该研究以最佳预训练配方的建议结束。对于需要在广泛任务中表现良好的通用模型,包括自然语言处理、世界知识和代码生成,平衡预训练方法加上包含高质量代码数据的冷却阶段是最有效的。这种方法利用了文本和代码数据的优势,确保模型健壮、通用,并能够在各种应用中表现出色。

根据作者的说法,研究结果表明,在整个预训练过程中仔细管理代码数据的比例和质量对于实现最佳性能至关重要。

大魏分享
https://github.com/davidsajare/david-share.git
 最新文章