训练一个大型语言模型需要多少钱
机器学习正在影响每个行业,似乎没有人清楚地知道训练一个专门的LLM需要多少钱。在本周的 2023 年 OpenAI 开发者日上,该公司宣布了他们的模型构建服务,最低价格为200万-300万美元。这是为专业模型付出的沉重代价,许多人想知道,有必要吗?
训练 LLM 需要多少成本的问题是一个非常困难的问题,虽然没有一个简单的即插即用成本计算,但答案主要取决于两个因素:计算要求和训练所需的时间。为了帮助明确如何估算训练 LLM 的成本,我编制了一份结构化的概述,概述了影响模型训练时间和计算要求的不同杠杆。
请注意,本文不包括以下费用:
- 开发和运营(工程工资、调试、IDE、版本控制系统、监控模型性能的工具、基础设施设置(尝试 Brev 哈哈)
- 使用更优化的 ML 库/API(降低成本)
- 代码许可/法律注意事项
- 数据隐私/安全和监管合规
- 模型偏见和公平性评估/伦理审查
- 对抗性训练(防止对抗性攻击)和其他安全措施
- 在生产环境中部署
确定计算要求和训练时间时要考虑的三个主要变量是模型架构、训练动态和优化训练性能的方法。然而,首先,我们应该了解这些模型所适合的硬件,以便我们了解这些变量适合的上下文。
硬件成本
这是指对 GPU 的访问及其相关成本,而 GPU 内存往往是瓶颈。这是 GPU 一次能够在内存中保存多少“东西”(模型、参数等)。我们注意到的是,大多数人认为他们需要一台昂贵、难以捉摸的 A100 或 H100,配备 40GB 或 80GB GPU 内存。但是,更小、更便宜、更可用的东西可能就足够了。
我已经发布了一些关于微调的指南(HF 数据集上的 Mistral、自己的数据集上的 Mistral、自己的数据集上的 Llama)。在这些指南中,我在所有线性层上使用了具有 4 位量化和 LoRA 的 QLoRA,将可训练参数减少了 98%。因此,我能够在单个 A10G(24GB GPU 内存,而 Brev 上仅花费 1 美元/小时)上训练这些模型,它提供云 GPU,而不会受到云提供商(如 AWS、GCP 和 Lambda Labs)的供应商锁定)。在我自己的数据集上训练大约需要 10 分钟,对 200 个样本进行 500 次迭代,在 HF 数据集上训练 6,000 个样本和 1000 次迭代大约需要一个小时。这些模型可能不是生产级的;我只是提供这些值作为基本参考。
云提供商成本以及 Spot 实例和预留实例之间的选择是直接的成本因素。如果使用云 GPU,不同的提供商和地区可能会有很大差异的定价。Spot 实例更便宜,但可靠性较低,因为您可能会在训练时丢失它们,而预留实例成本更高,但可确保可用性。
模型架构
尺寸和结构
深度(层数)、宽度(每层神经元数)和参数总数都会影响 GPU 内存要求和训练时间。具有更多和/或更宽层的模型能够学习更复杂的特征,但代价是计算需求增加。增加要训练的参数总数会增加估计的训练时间和 GPU 内存要求。低秩矩阵分解等技术(例如,LoRA 和稀疏性,其中张量被修剪为具有大量 0 值)可以减少可训练参数的数量并降低这些成本,但它们需要仔细调整。稀疏性通常在 transformer 注意力机制(见下文)或权重(如块稀疏模型)中完成。
注意力机制
Transformer 利用自注意力机制,多个磁头处理不同的序列部分,以增加计算量为代价来增强学习。传统的 Transformer 注意力风格将上下文窗口中的每个标记与所有其他标记进行比较,从而导致上下文窗口大小 $O(n^2)$ 的内存要求是二次的。稀疏注意力模型通过关注位置的子集(例如局部(附近)注意力)来提供折衷方案,从而减少计算负载,通常低至 $O(n \\sqrt{n})$ ( source)。
效率优化
激活函数和门控机制的选择会影响计算强度和训练时间。不同的激活函数具有不同程度的数学复杂度;例如,ReLU 没有 sigmoid 或 tanh 复杂。此外,参数共享(例如跨层权重共享)可以减少唯一参数的数量,从而减少内存需求。
训练动态
学习率和批量大小
学习率和批量大小会显著影响模型的训练速度和稳定性。模型的学习率会影响它在梯度相反方向上所采取的步长(即最小化成本或损失函数的方向)。这称为梯度下降。批量大小是在更新模型参数之前处理的样本数。确实,批处理越大,需要的内存就越多;它与批次的大小呈线性关系。但是,较大的批量大小可以加快收敛速度,因为在每一步中,您都可以更好地估计真实梯度。
需要考虑的一个微妙之处是:即使您有 TB 的 GPU 内存,您仍然可能不想使用尽可能大的批处理大小。缩减采样(即使用小于训练样本总数的批量大小)会将噪声引入梯度,这可以帮助您避免局部最小值。这就是为什么它被称为随机梯度下降:随机性是指您在每批次中从训练集中下采样的程度。
学习率的大小(幅度)和时间表(训练的变化率)会影响收敛的速度和稳定性。更高的学习率意味着模型在梯度下降过程中会采取更大的步骤。虽然这可以加速收敛,但也可能导致超调最小值和潜在的不稳定训练。相反,太小的学习率会减慢收敛速度(因为达到最小值需要更长的时间),并且模型可能会卡在局部最小值中。有关局部最小值与全局最小值的示例,请参见下图。简单来说,不等于全局最小值的局部最小值是图上似乎已经找到最佳损失的位置,但我们只是走得更远一点 - 上山并处理一些更差的性能以到达那里 - 我们本可以在图中找到更好的位置。
精度和量化
计算的精度,如 FP16 与 FP32(使用 16 位表示每个浮点,而不是 32 位)以及量化等技术在内存使用与性能权衡之间取得平衡。使用半精度 (FP16) 而不是单精度 (FP32) 浮点可将张量大小减半,从而通过实现更快的运算和更多的并行化来节省内存并加快训练速度。但是,这需要在精度上进行权衡,这可能会导致潜在的数值错误,例如上溢/下溢错误,因为较少的位不能表示那么大或那么小的数字。它也可以降低准确性,但如果不是太极端,它可以作为一种正则化形式,减少过拟合,并允许模型在保留数据集上实际表现更好。另一种技术是使用混合精度训练,其中一些浮点是 FP16,一些是 FP32。但是,确定哪些矩阵应表示为 FP16 与 FP32 可能需要一些实验,这也是一个成本考虑因素。
量化是另一种将高精度浮点映射到较低精度值(通常是 8 位甚至 4 位定点表示整数)的技术。这会将张量大小减少 75% 甚至 87.5%,但通常会导致模型精度显着降低;不过,如前所述,它实际上可能有助于模型更好地泛化,因此实验可能是值得的。
超参数扫描
超参数是机器学习模型的外部配置变量,即它们不像权重那样由模型本身学习。超参数基本上是我们在这里讨论的所有变量:学习率、模型架构(如神经元或层的数量)、注意力机制等。超参数扫描是指运行实验,使用各种超参数设置的组合来训练不同的模型,它们使模型能够为其特定数据集和任务找到超参数值的最佳组合。但是,它的计算成本很高,因为您必须训练许多模型才能找到最佳配置。
检查点/提前停止
频繁的模型状态保存(检查点)可能会增加磁盘使用率,但会提供更多回滚点;如果模型在训练的早期状态下过度拟合或表现更好,则可以在检查点保存这些权重并加载该模型。提前停止是一种在模型训练停止改进保留验证集后停止模型训练的方法。这样可以节省训练时间。
优化训练性能
基本模型状态
从预训练模型开始,尤其是在与正在训练的新任务类似的任务中训练的模型,可以显著减少训练时间。如果初始权重更接近最优解的权重,则训练速度会更快。从头开始构建模型(即使用随机初始权重矩阵或类似模型)需要更多的计算,通常不建议这样做。
并行性和分布式训练
并行计算通常是由一台具有多个处理器的计算机完成的,这些处理器同时执行多个任务以提高效率。分布式计算涉及多台机器(可能在物理上相距遥远)处理分工任务,然后组合它们的结果。通常这两种技术一起使用。
并行性可以加快训练速度,但会增加复杂性和计算要求。有多种并行化方法,例如流水线模型并行化,其中模型被拆分为不同的阶段并分布在 GPU 上,以及数据并行化,其中数据集被划分到 GPU 中。分布式训练可以更高效,但需要更多的计算资源并增加复杂性。
数据注意事项
训练数据从存储馈送到模型的速度会影响训练时间。需要考虑的一些变量:
- GPU 位于何处?将自己的数据传输到更偏远地区的云计算机可能需要更长的时间
- 计算机 I/O 带宽会影响存储和 GPU 之间的传输时间
- 此时,GPU 上的数据缓存、预取和并行加载可以减少
此外,更复杂的数据可能需要更长的时间来学习模式,即损失收敛时间可能会增加。训练数据的相关性和质量也对训练效率产生深远影响。预处理和扩充可以改善结果,但可能会增加计算开销。
结论
我希望这有助于理解计算微调或训练 LLM 的成本背后的复杂性。没有放之四海而皆准的答案或即插即用的方程式;我希望你得到的主要收获是,有很多实验来找到最适合你和你的用例的方法,但这是ML乐趣的一部分。所以尝试一些事情,期望很多事情都不起作用,但通过这样做,你会看到什么能给你带来最好的结果。
归根结底,像 OpenAI 提供的 LLM 这样的训练成本似乎很高。对于许多人来说,微调较小的模型并保持对专有数据的控制可能是一个更可行的解决方案。