翻译:Writing_an_LLM_from_scratch_part_1
版权声明:
除非注明,本博文章均为原创,转载请以链接形式标明本文地址。
从零开始构建大型语言模型(LLM),第一部分
发布于 2024 年 12 月 22 日,主题:AI、从零开始构建 LLM、TIL 深度探索
在圣诞节假期(可能更久)期间,我计划学习Sebastian Raschka的书《从零开始构建大型语言模型》。我预计每天会学习一章或更少,以便有足够的时间消化内容。每天或每章结束后,我会在这里分享我觉得特别有趣的内容。
今天的内容可能是最简单的部分:第一章《理解大型语言模型》。
正如你所料,这一章主要是重申那些与 LLM 稍有接触的人已经知道的内容,因为 Raschka 需要为后续章节做铺垫。不过,这一章也提到了一些底层技术概念——虽然目前还比较粗略,但这些术语在后续章节中会得到详细解释。
Transformer
核心信息是,Transformer 架构是 LLM 如此强大的原因。他指出,LLM 不一定非得基于 Transformer 构建,基于 Transformer 的 LLM 也不一定是 GPT,但为了简洁起见,他在书中会忽略这一点。这很合理——如果每次都要说“基于 Transformer 的 LLM”或“GPT LLM”而不是简单的“LLM”,书会变得难以阅读。更不用说“GPT”在大多数人心中与 OpenAI 紧密相关。
无论如何,正如你所料,这一章的核心是对 Transformer 的高层次概述。他采用了我喜欢的方法,即从历史开始。这很有用,因为很多术语只有在了解其起源背景时才能真正理解。
最初的 Transformer 是用于机器翻译的,工作原理如下:
- 输入文本(例如英语)进入编码器。编码器是一个大型神经网络,将文本转换为嵌入(embedding)——一个非常高维空间中的向量(或一组向量),以某种抽象方式表示输入文本的含义。
- 然后,这个嵌入被输入解码器,解码器会使用它逐个生成另一种语言(例如德语)的 token,这些 token 表达了嵌入中的概念,因此是对原始输入的翻译。解码器会先生成第一个 token,然后使用它和嵌入生成下一个 token,接着使用前两个 token 和嵌入生成第三个 token,以此类推——因此它始终能看到之前的输出来帮助指导输出构建。
- 编码器和解码器都可以访问自注意力机制(self-attention),这是一种让它们知道在处理特定 token 时应该关注哪些其他 token 的系统。例如,如果它正在处理“the fat cat sat on the mat”(假设一个单词等于一个 token),当处理“cat”时,它可能会更关注“fat”(因为这是形容词修饰的名词),或者当处理“sat”时,它可能会关注“cat”和“mat”(因为它们是动词的主语和间接宾语)。
这种自注意力机制被编码器(显然需要它,因为它正在构建类似句子含义的心理模型)和解码器(需要它来构建有效的句子)共同使用。
目前我不太清楚的是,编码器和解码器是否共享相同的注意力机制(允许编码器向解码器传递“提示”,以帮助构建输出,而不仅仅是嵌入中的信息)。我猜测“不共享”,因为如果共享的话,应该会提到。
自注意力听起来像魔法,说实话,这是我真正期待学习的 LLM 部分——目前我对它的工作原理几乎没有任何概念。当然,Raschka 在这里只是简要提及——第 3 章会详细讨论。
无论如何,这就是 Transformer 系统的历史背景。接下来人们发现,编码器和解码器实际上可以单独使用。我听说过“仅编码器”或“仅解码器”的模型——基于 GPT 的 LLM 就是后者之一——这解释了这些术语的来源。
仅编码器模型的一个例子是 BERT,我知道它广泛用于分类任务;事实上,Answer.AI 最近发布了 ModernBERT,这是一个针对分类任务的更新版本。这对我来说有些直观意义。如果你有一个设计用于接收文本输入并生成表示其含义(在某种意义上的)嵌入的模型,那么添加一个额外的层将该含义转换为“这段文本的语气是快乐/悲伤/愤怒等”似乎并不难。
对我来说不太明显的是,这样的编码器如何用于完成这些模型也擅长的任务:填补句子中的空白。Raschka 展示了一个例子:
This is an ___ of how concise I ___ be
并预测缺失的单词是“example”和“can”。我知道 BERT 及其同类模型可以做到这一点,但我从未确切知道原因,遗憾的是这一章没有填补这一空白。我现在真的很想研究它,但应该继续按计划进行 :-)
正如我上面所说,GPT 是仅解码器架构的一个例子。这在我的脑海中比编码器的分类用例更模糊。很明显,能够接收嵌入并生成一系列单词的东西对文本生成很有用。但 GPT 基本上是通过下一个 token 预测来工作的,例如,如果提供输入:
This is an example of how concise I
它可能会返回“can”,然后再次运行时提供输入:
This is an example of how concise I can
它可能会返回“be”。
那么问题是,像 GPT 这样的仅解码器模型如何在没有编码器生成的嵌入的情况下工作?
Raschka 提到的另一件事让我有点困惑,即最初的 Transformer 架构有六个编码器和六个解码器块,而 GPT-3 有 96 个 Transformer 层。这与我对这一切如何运作的模型不太吻合。编码器和解码器看起来像是独立的东西,接收输入(token/嵌入)并生成输出(嵌入/token)。那么,多层编码器或解码器有什么用呢?
所以——如何设计一个解码器来接收嵌入并输入文本,如何将解码器块分层,以及注意力机制——这些似乎是这本书将为我揭示的内容。但在现阶段,我们真的只是在了解需要解决的问题,而不是解决方案。
[更新,发布后两小时。我突然想到:如果解码器设计用于接收嵌入和(最初为空的)文本,那么通过给它一个“空”嵌入和一些预先编写的文本,如果训练得当,它可能能够预测下一个单词。这或许就是 GPT 的工作原理?]
数据
从一开始就很明显,训练 LLM 是昂贵的——你听到 OpenAI 最近的模型训练成本高达数亿美元。从我自己的微调 LLM 实验中,我知道在本地训练一个 0.5B 的模型,使用 10,000 个示例,每个示例大约 1,000 个 token(总共 10M token),大约需要半小时,而在一个 8x A100 80GiB 的云服务器上训练一个 8B 模型,使用相同数量的 token,成本约为 10 美元/小时,需要 20 分钟。
GPT-3 显然是在 3000 亿个 token 上训练的,所以工作量是 300,000,000,000 / 10,000,000 = 30,000 倍。让我们天真地将我的成本/时间数字放大——显然这将是一个非常粗略的近似值,但应该在一个数量级左右:
- 本地训练需要 15,000 小时,大约 21 个月。
- 更大的模型需要 10,000 小时,大约 13 个月,成本为 10 万美元。
说实话,这两个数字都比我预期的低——也许我在数学上哪里出错了?——但无论如何,这比任何阅读这本书的人可能愿意花费的时间和金钱都要多得多。
在资源受限的情况下,Raschka 在他的书中给出了最合理的解决方案,即完成启动 LLM 训练所需的所有工作,稍微训练一下以证明它有效,然后指向一组预训练权重,人们可以下载并插入以进行进一步的微调。
虽然拥有一个 LLM 并能够说“这都是我的,我从头开始训练了它”会很好,但这似乎是最合理的实际解决方法,因为真正从头开始训练的成本高得离谱。
非完全勘误
这一章中有几件事——至少在我看来——并不完全正确。我认为它们可能是 Raschka 为了可读性而做出的简化,因为我 100% 确定他自己对这些事情没有任何混淆!
- 当他第一次提到 LLM 时(在他明确表示 LLM 指的是 GPT 之前),他说 LLM 专注于下一个单词预测,当然,当你考虑到 BERT 及其类似模型时,这并不完全正确。我认为这只是我这边“一知半解”的情况——我已经知道 BERT 可以处理预测掩码 token 而不仅仅是下一个单词,所以我发现这比不了解这一点的人更令人困惑。[更新:为了清晰起见,这个挑剔点特别针对第 2 页的提及——后面会解释清楚。]
- 他说“与深度学习相比,传统机器学习需要手动特征提取”,这在我看来有点不准确——毕竟,还有其他机器学习系统(例如核方法,甚至用于垃圾邮件过滤的朴素贝叶斯)可以自行提取特征。不过这是一个小挑剔,保持简单是有道理的。
总结
以上就是我从这本书第一章中得到的收获。当然,还涵盖了很多其他内容,但它们要么是为未来章节做铺垫,要么是我已经足够熟悉的背景信息,所以没有让我感到惊讶。
我真的很期待明天的第二章!