解密 LLM 扩展定律

技术

点击下方 卡片 ,关注“ 慢慢学AIGC ”

picture.image

LLM 扩展定律

现在,主要的云服务提供商和众多公司大量投资,收购数十万个 GPU 集群并利用海量训练数据来开发大型语言模型(LLMs)已不再令人惊讶。为什么更大的模型被认为更好?OpenAI 论文《自然语言模型的扩展定律》【1】认为,对于 LLMs 来说,下一个标记(1 个标记约为0.75 个词)预测的损失是可预测的和平滑的。事实证明,你只需要知道两个关键变量就可以估计它们的准确性: 模型中参数的总数(N)和用于训练模型的文本标记的大小(D) 。参数数量反映了模型学习和表示数据中复杂关系的能力,而训练数据量则允许模型从更广泛的例子和上下文中学习。

仅用这两个变量(即 N 和 D),我们就可以预测 LLM 在下一个标记预测任务上的损失。随着我们训练更大的模型并使用更多数据,我们继续看到准确性的提高。然而,transformers 的神经网络架构在过去 7 年中只进行了适度的修改。考虑到 LLMs 以能源和数据消耗大而闻名,我们希望未来的研究能够提出更优化的架构(其实已经有不少了)。

LLMs 的扩展定律揭示了模型的质量如何随着其规模、训练数据量和计算资源的增加而演变 。这些见解对于驾驭训练更大模型的复杂性和做出关于资源分配的明智决策至关重要。

因此,理解这些扩展定律对于优化 LLMs 的开发和部署是必要的, 确保资源被有效利用以达到所需的性能水平

此外,过拟合的风险与模型大小和数据集大小的比率密切相关,建议 D ≥ 5 x 10³ N^(0.74) 以避免模型过拟合(参见 OpenAI 论文中的公式 4.4)。训练曲线倾向于遵循可预测的 幂律模式 ,允许根据当前训练进展对未来性能进行粗略预测。

OpenAI 和 DeepMind 的实证实验

从根本上说,研究人员试图回答 LLMs 扩展定律的问题:给定以 FLOP(浮点运算)衡量的受限计算预算,什么样的模型大小和训练数据大小(以标记数量衡量)的组合能产生最低的损失?

计算预算有各种形式:PF-days(10¹⁵ FLOP/秒 x 24 小时 x 3600 秒/小时,得到 8.64x10¹⁹ FLOP)是最常见的单位之一。关于 FLOP 的更多细节请参见附录 1。

picture.image

图 1:随着模型大小、数据集大小和计算量的同步扩大,LLM 模型得到改善(即 test loss 降低)

已经进行了各种实验来研究语言模型的扩展定律,涉及不同的模型大小、数据集大小和其他因素,如:

  • 模型大小(N) :范围从768到15亿非嵌入参数。
  • 数据集大小(D) :从2200万到230亿标记不等。
  • 模型形状 :包括深度、宽度、注意力头数和前馈维度的变化。
  • 上下文长度 :主要是 1024,有些实验使用较短的长度。注意,在各种论文或代码实现中可能会看到上下文长度、上下文窗口大小或块大小。它们都指的是同一件事,即 transformer 在训练过程中看到的连续标记的最长序列,也是它一次可以推理的长度。本博文中的代码使用块大小。

训练变量:

  • 测试交叉熵损失(L) :代表模型的性能。

  • 计算(C) :用于训练模型的计算资源。

尽管这些实验已经有近 4 年的历史,但它们提供了对 LLMs 训练要求的深刻理解。当 OpenAI 研究人员研究 LLMs 时,有两个显著的发现:

picture.image

图 2:当非嵌入参数 N 的总数固定时,模型损失对模型形状的依赖性较小

首先, 规模对模型损失的影响比模型的架构结构的影响更为显著 。规模指的是参数数量(N)、数据集大小(D)和用于训练的计算资源(C,以FLOP衡量,如附录 1 所述)。这些因素共同对模型损失的减少有更实质性的影响,而不是架构细节(即改变 前馈比率、纵横比、注意力头维度 等),如图 2 所示。这意味着 增加模型的大小、使用更大的数据集和分配更多的计算能力可能会产生比仅仅调整模型结构更好的结果

其次,如图 1 所示,当这些因素互不约束时,模型的性能与每个规模因素(N、D、C)之间存在幂律关系,如公式 1 表中的三种情况所示:

  • 情况1:参数 = Nopt(计算效率最优的模型大小),数据 = Dopt(计算效率最优的数据标记大小),计算 = Cmin(计算效率最优的计算预算)
  • 情况2:参数 = 无限,数据 = D,计算 = 早停
  • 情况3:参数 = N,数据 = 无限,计算 = 无限

这种关系在广泛的值范围内成立,表明存在一种一致的模式,即性能随着任何这些因素的增加而可预测地改善。换句话说,随着我们扩大模型大小、数据集大小或计算资源,我们可以预期模型性能会相应地、可预测地改善,遵循幂律趋势。

picture.image

等式 1:OpenAI 研究人员提出的扩展定律

实证上,来自OpenAI的研究人员拟合了等式 1(即 N、D 有限,早停,固定批量大小的情况),并估计 Nc = 8.8x10¹³,AlphaN = 0.076,AlphaD = 0.095,以及 Dc = 5.4x1⁰¹³。以 Llama 3 为例,它有 700 亿参数和 15 万亿标记。因此,损失 L(70x10⁹, 15x10¹²) = 1.72。

样本高效的 LLMs

picture.image

图 3:LLM 的 test loss 与数据集大小或计算量的关系(按模型大小)

大型模型比小型模型更具样本效率 ,能用更少的优化步骤和更少的数据点达到相同的性能水平。显然,对于给定的处理标记数,较大的模型能达到较低的测试损失,如图 3 所示。

picture.image

图 4:DeepMind 提出了一个修改后的扩展定律,表明包括 Gopher、GPT-3 和 Megatron-Turing NLG 在内的模型可以用少得多的模型参数进行训练。(左)给定 FLOP 预算的最优标记数和参数数(右)修改后的扩展定律和 OpenAI 扩展定律预测的叠加

DeepMind 发表了另一篇论文《训练计算最优的大语言模型》【2】,详细介绍了训练计算最优 LLMs 的扩展定律的各种方法,这些方法与 OpenAI 不同。他们进行了超过 400 次 LLMs 训练,发现对于计算最优训练,模型大小和数据集大小(标记数)应该等比例扩大。

他们应用了三种扩展定律方法,并将其发现与 OpenAI 的结果叠加,如图 4 右侧所示。他们发现,为了达到相同的模型性能,所有三种方法都建议使用更小的模型大小。也就是说,在给定计算预算和训练数据的情况下,可以用更小的模型大小达到相同的模型性能,如图 4 左侧所示。

picture.image

图 5:参数拟合损失函数

这是我最喜欢的部分:当 DeepMind 的研究人员将损失建模为模型大小和标记数的函数,并使用 OpenAI 研究人员建议的约束 FLOPs(N, D) ~ 6ND 时,出现了一种有趣的 LLMs 扩展定律解释方式:绘制等损失等高线或等 FLOP 切片,如图 5 所示。要理解左边的等损失等高线图,让我们用第一性原理来理解这种情况。对于给定的等损失(黑线),我们的目标是使用最少的计算能力,即最少的 FLOP。当你 追踪代表所有等损失的最少 FLOP 的所有点时,这些点可以连接成一条蓝线 。这条线被称为有效前沿,这个概念对那些在金融或商学院学习过运筹学的人来说很熟悉。

人们可以使用蓝线来推断给定更大计算预算(换句话说,更多训练 FLOP)的最优模型大小和预测损失。例如,在Gopher 模型的情况下,给定预算的最优模型大小为 400 亿参数。

picture.image

图 6:各种模型大小的估计最优训练 FLOP 和训练标记

对于最优的计算效率训练,DeepMind 建议每 1 个模型参数至少有 20 个训练标记,如图 6 所示。为了更好地理解,Meta 发布的 Llama 3 的标记与参数的比率为 215:1。

picture.image

公式 2:DeepMind 科学家拟合的参数损失函数

与 OpenAI 的扩展定律方程不同,DeepMind 的科学家使用不同的规模方程,并实证拟合了公式 2。他们得出 E = 1.69,A = 406.4,B = 410.7。以 Llama 3 为例,它是一个有 700 亿参数和 15 万亿标记的模型。损失 L(70x10⁹, 15x10¹²) = 1.86,比使用公式 1 估计的结果(即1.72)略高。

附录 1:以 FLOP(浮点运算)衡量的计算预算

模型的计算资源或计算复杂性以 FLOP 或浮点运算来衡量。它们用于估计训练和运行模型所需的计算资源量,如图 7 的 y 轴所示。

为了更好地理解,据估计 OpenAI 使用了 133 亿 petaFLOP 来训练 GPT4。在计算大型语言模型的 FLOP 时,重要的是要考虑训练过程中涉及的所有操作,包括与嵌入矩阵相关的操作。以下是 transformer 模型前向传递的 FLOP 计算明细:


          
# reference: https://github.com/Lightning-AI/litgpt/blob/410a7126f82ea550d4a43dab89367547b073b5a3/litgpt/utils.py#L321
          

          
def flops_per_param(max_seq_length: int, n_layer: int, n_embd: int, n_params: int) -> int:
          
    flops_per_token = 2 * n_params  # each parameter is used for a MAC (2 FLOPS) per network operation
          
    # this assumes that all samples have a fixed length equal to the block size
          
    # which is most likely false during finetuning
          
    flops_per_seq = flops_per_token * max_seq_length
          
    attn_flops_per_seq = n_layer * 2 * 2 * (n_embd * (max_seq_length**2))
          
    return flops_per_seq + attn_flops_per_seq
          

          
def estimate_flops(model: "GPT", training: bool) -> int:
          
    """Measures estimated FLOPs for MFU.
          

          
    Refs:
          
        * https://ar5iv.labs.arxiv.org/html/2205.05198#A1
          
        * https://ar5iv.labs.arxiv.org/html/2204.02311#A2
          
    """
          
    # using all parameters for this is a naive over estimation because not all model parameters actually contribute to
          
    # this FLOP computation (e.g. embedding, norm). For this reason, the result will be higher by a fixed percentage
          
    # (~10%) compared to the measured FLOPs, making those lower but more realistic.
          
    # For a proper estimate, this needs a more fine-grained calculation as in Appendix A of the paper.
          
    n_trainable_params = num_parameters(model, requires_grad=True)
          
    trainable_flops = flops_per_param(
          
        model.max_seq_length, model.config.n_layer, model.config.n_embd, n_trainable_params
          
    )
          
    # forward + backward + gradients (assumes no gradient accumulation)
          
    ops_per_step = 3 if training else 1
          
    n_frozen_params = num_parameters(model, requires_grad=False)
          
    frozen_flops = flops_per_param(model.max_seq_length, model.config.n_layer, model.config.n_embd, n_frozen_params)
          
    # forward + backward
          
    frozen_ops_per_step = 2 if training else 1
          
    return ops_per_step * trainable_flops + frozen_ops_per_step * frozen_flops
      

需要注意的是,这个计算只涵盖了前向传递。对于训练,还需要考虑反向传播计算量。

如果这变得太复杂,经验法则是计算要求(C)约为 6ND 或分布式训练时为 8ND,其中 N 是 transformers 的参数数量,D 是训练数据大小,以标记衡量。C(前向) 约为 2ND;C(后向)约为 4ND。

picture.image

图 7:PFLOP 正在增长以赶上 LLMs 的扩展定律

附录 2:以 FLOPS(每秒浮点运算)衡量的计算速度

FLOPS,或每秒浮点运算计算速度。下面是 Nvidia A100 和 H100 GPU 性能的表格,如图 8 所示。

可以根据表格和计算要求(即 6*ND 估计)估算训练 LLMs 所需的 GPU 数量。例如,GPT4 需要 1330 亿 petaFLOP,即 1.33 x 10²⁶ FLOP(或 1.7 万亿参数并使用 13 万亿标记,得到 6 x 1.7 x 10¹² x 13 x 10¹²,1.33 x 10²⁶ FLOP)。假设计算使用 FP16 Tensor Core with sparse,A100 将提供 624 TFLOPS(6.24 x 10¹⁴ 每秒浮点运算)。据报道,OpenAI 使用了 25,000 个 A100。因此,1.33x10²⁶/(6.24x10¹⁴ x 25,000) = 8525641 秒或 98.67 天,这与报告和帖子大致吻合。很好,数学计算是正确的!:)

(译注:这里显然没有考虑 A100 训练时基于稠密计算而非稀疏计算,模型训练时的 TFLOPS 效率 MFU 也无法达到 100%。读者应加以分辨。欢迎加微信 Mistake113 深入探讨)

picture.image

图 8:Nvidia GPU 的计算速度表,以 TFLOPS(10¹² FLOPS)衡量

总结

我们涵盖了 LLMs 的各种扩展定律,研究了模型的损失如何随着训练数据和参数数量的增加而变化。讨论包括对用于解释 LLM 扩展定律的等损失等高线和等 FLOP 切片的解释,提供了关于优化计算资源的见解。

最后,我们讨论了 FLOP 和 FLOPS 的概念,它们分别衡量计算量和速度。以 GPT-4 或 Llama3 为例,我们澄清了训练 LLMs 所涉及的复杂性。在我们的下一篇博文中,我们将探讨使用模型并行或数据并行等技术 大规模训练 LLMs 的策略,以及微调 LLMs 的规模法则,提供关于高效大规模训练技术的进一步见解。我们希望您会发现这些材料有用,并期待听到您的反馈。

致谢

感谢我们的同事,包括 Josh Frazier、Srijith Rajamohan 和 Jeremiah Edwards,感谢他们对这些论文的讨论和解释。

作者简介

picture.image

作者:Yu-Cheng Tsai, Sage AI 的撰稿人,一位对创新 AI 产品充满热情的数据科学家。普林斯顿大学机械与航空航天工程博士,现就职于 Sage AI。

作者 Linkedin:https://www.linkedin.com/in/yu-cheng-tsai/

参考文献

【1】自然语言模型的扩展定律,https://arxiv.org/pdf/2001.08361

【2】训练计算最优的大语言模型,https://arxiv.org/pdf/2203.15556

注:文章由 AI 生成。点击“ 阅读原文 ”可直达 Medium 原文链接同作者直接交流。原文发表时间为 2024 年 4 月 30 日。

0
0
0
0
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论