
整理 Andrej Karpathy 在 Microsoft Build 2023 的演讲,深入理解 GPT 的训练过程、发展现状、当前 LLM 生态以及未来展望。
GPT 的现状
本文是对 Andrej Karpathy 的在 2023 年 3 月份的 Microsoft Build 演讲的整理。 演讲 Beamer 可见于:https://karpathy.ai/stateofgpt.pdf
演讲介绍了 GPT 的训练过程,发展地步,当前的 LLM 生态以及未来展望,在一年后的今天也没有过时,完全可以与当下的实际发展对比阅读、分析。
Overview

pretraining 部分占据了绝大部分训练时间,后面的三个阶段都是 fine-tuning 阶段。
Data collection

Training data mixture used in Meta’s LLaMA model
Composition of the mixture:
- CommonCrawl: 普通的网络爬虫
- C4:Common Crawl 的一个巨大而干净的版本。
- 其它高质量数据集如图所示
这些知识混合在一起,然后根据给定的比例进行采样,构成了 GPT 神经网络的训练集。
Pre-training
实际训练前,需要进行预处理步骤如下。
tokenization
基本上是把互联网上爬取的原始文本转译为整数序列(sequence of integers)的无损转换过程。

可以使用像byte-pair encoding(BPE)的方法,迭代合并小文本块并将它们分组为token

Transformer 神经网络的超参数表格
Vocabulary Size(词汇表大小):
- 词汇表大小指的是模型能够识别和生成的唯一词汇(包括单词、字符或子词单元)的总数。这个数字定义了模型输入和输出的可能性范围。
- 类比Bigram中,我们指定的是输出预测的字母,因此是”字符表”,大小为 27
Context Length(上下文长度):
- 上下文长度指的是模型在处理文本时能够考虑的最大单元数(通常是词或者 token)的数量。这个长度定义了模型在生成文本或理解文本时能够回顾的信息量。
- NPLM模型中,上下文长度就被设为 3,也就是通过前 3 个 token 预测下一个。
- 如今 GPT4 等模型可以接受十万多的输入。
参数量(Parameters)
- 参数量指的是构成模型的参数的总数,这些参数在训练过程中学习并调整,以最小化预测误差。参数可以是权重(weights)和偏置(biases),它们在神经网络中用于处理输入数据,进行变换,并最终生成输出。模型的参数量是衡量模型大小和复杂度的一个直接指标。
- NPLM中的这段代码中就统计了模型的参数量,并尝试了通过增加隐藏层神经元数等方式来加大参数量改善拟合。
g = torch.Generator().manual_seed(2147483647)
C = torch.randn((27,2), generator=g)
W1 = torch.randn((6,100), generator=g)
b1 = torch.randn(100, generator=g)
W2 = torch.randn((100,27), generator=g)
b2 = torch.randn(27, generator=g)
parameters = [C, W1, b1, W2, b2]
sum(p.nelement() for p in parameters)- Training Tokens Total(训练的 token 总量):
- 训练的 token 总量指的是在训练过程中模型处理的 token(可以是单词、字符或子词单元)的总数。这个数字反映了模型训练过程中”看到”和学习的数据量。
- 类比姓名数据集中,一共有 30k 数据,那可以理解为 (1B 是,即十亿)。
可以看到,LLaMA 的训练量十分之大,用更长的训练时间取得了比 GPT-3 更好的效果,因此不能只根据模型的参数量来判断性能。

最开始的时候,模型的权重是随机的,因此采样结果是完全随机的。随着训练时间增常,从模型中获取的样本就会越来越连贯而一致。从图中最后可以看出,这个 GPT 模型已经学到了单词、空格和标点符号等方面的知识。
Training curve

随着训练进度推移,关注的重点是损失函数的变化,低损失意味着这个 Transformer 模型对序列中正确的下一个整数给予了更高的概率。
GPT 学习到了强大的general representations,也可以非常高效的地去微调,适用于任意下游任务。
以情感分类任务为例子,我之前正好参与过相关研究,当时是调用了百度的某个情感分析 API 来对我们收集到的数据进行积极、消极判断等处理,得到监督学习中可以使用的数据,然后再用其它 NLP 模型进行训练。但 GPT 出现后,完全可以先忽略情感分类去做 LLM 的预训练,用少量的数据高效微调针对这一任务的 Transformer 模型。
这是因为 Transformer 模型在语言建模任务中被强制执行了大量的multitask,它被迫要了解文本的结构和其中所有不同的概念来预测下一个 token。这是 GPT-1 阶段。
在 GPT-2 阶段,人们注意到使用prompt(提示词)实际上比微调更好、更有效。
Base model ≠ Assistant
基础模型并非我们平时使用的 ChatGPT,我们使用的是 GPT 模型的 api 如 Davinci、3.5 Turbo,它们是助手。而真正的基础模型并不是assistant,只是想补全文件:

你你可以通过创建特定的few-shot prompt来讲基础模型变为助手,让它看看起来像是有一个中间的交互文档,然后将你的查询放在末尾,基础模型就会自我调整为一个能帮忙的助手回答问题。但这不太可靠并且效果欠佳,所以创建实际的 GPT 助手走了一条不同的的路。
Supervised Finetuning

这个阶段收集小而高质量的数据集,用众包的形式,人工收集 prompt 和理想回应的数据。继续对这些数据进行语言建模,算法不变,只是更换了数据集。训练得到一个 SFT(Supervised Fine-Tuning) 模型,这是可部署的真正助手,有一定效果。

示意图,众包工人撰写的回应被要求友好、真实和无害,并遵循着指示文件。
RLHF pipeline
acronym of reinforcement learning from human feedback
Reward Modeling

这个阶段,我们将收集到的数据转为Comparisons的形式,用相同的 prompt,来要求助手完成任务,让训练好的 SFT 模型创建多个版本的回答,再让人们去评估哪个版本更好(这个很费时费力)

然后对这些版本进行分类,做法是在最后添加一个特殊的reward token,然后基本上只监督这个 (绿色)token 上用 Transformer。Transformer 会预测完成某个 prompt 的回答对应的奖励,根据人工标注的真实奖励标签转化为损失函数,然后训练我们的模型,让它产生和人工众包的评估事实一致的对奖励的预测。

建立好奖励模型后,它本身作为助手还不是很有用,但是对接下来的强化学习阶段十分有用。
Reinforcement Learning

根据奖励模型,我们可以为任何给定 prompt 的 completion 完成质量打分。这个阶段将针对奖励模型来进行强化学习。
现在的训练目标是 (黄色的)completion。使用 SFT 模型对不同 prompt 创建一些 completion,然后再次添加奖励 token,根据已经固定的奖励模型指示的奖励来权衡语言建模目标。

图中可以看出,高绝对值的 reward 会增加未来 token 采样的权重。
在大量 prompt 和 batches 上迭代,获得了能创建在奖励模型中取得高分的 completion 的策略。
得到了一个可部署的 RLHF 模型。
Why RLHF?

表现更好,人类更喜欢它们生成的回答。
一种解释可能:判断比较和生成的难度是不对等的,比如相比于创作一个优秀的俳句 (一种日本的古典短诗),判断几个俳句中哪个写的更好显然更简单。这可以潜在地利用人类的判断力,创建更好的模型。
但也因此,相较于 Basemodel,RLHF 后的模型失去了一些熵。也就是说模型输出的变换很小,而 basemodel 具有很高的熵,并产生多种可能的输出。因此在类似”生成更多 Pokemon 名字”的任务中,basemodel 也许更擅长。
Apply LLM Assistant
Chain of thought
aka COT
当人类写作的时候,我们内心有一个独立的过程——总是在审视我们所写的内容,并判断写的是否 good enough,我们可能删掉一部分或者重新写,然后对结果满意。
而在 GPT 的视角,这只是一系列 token,它会查看每个 token 并在每个 token 上花费等量的计算,完全不会有上述的内心独白。也就是说,Transformers 模型就相当于 token 模拟器,它们不知道自己善于或不擅长什么,只是拟合下一个 token。模型不会对任何内容做反馈、合理性检查或是纠错。
GPT 通过存储大量领域的基于事实的知识,用几十亿个参数存储,拥有很强的工作记忆力。因此,在上下文长度范围内的任何内容都可以通过 Transformer 内部的自注意力机制立即获得,无损地记住这些内容。相当于是有限的完美记忆。
Prompting 只是弥补人脑和”LLM 脑”之间的认知差异的一种方式。因此实践中,如果你在做需要推理能力的任务,你不能指望 Transformer 能对每个 token 都做太多推理,所以你必须将推理分散到更多 token 中。

让 LLM 模拟这种推理

或者是多次采样,然后投票选出答案
或者是我们生活中常用的:告诉 LLM 它的回答有错误,它会认识到错误。但如果你没有提示他,他就根本不会自主反馈。
Tree of Thoughts
通过同时考虑多个潜在的可行计划,并利用价值反馈机制进行决策,扩展了现有的规划方法。此外,该方法还引入了自我反思机制,使语言模型能够评估自身生成的候选项的可行性。
这是通过 python 粘合代码 (Glue Code) 和单个 prompt 共同实现,其中还包括树搜索等。
AlphaGo 就是模拟人类的决策,用蒙特卡洛树搜索等评估所有可能性,然后保留那些好的选择。

可以类比为针对文字的 AlphaGo。
人们开始探索更通用的技术,而不是单一的 prompt,更像是通过将很多 prompt 粘合在一起。
Chains / Agents
- ReAct:将对 prompt 的回答结构化为一系列 thought, action, observation, … 的组合,用思考过程回答问题,这过程中模型也可以使用外部工具。
- AutoGPT:允许 LLM 保持任务列表并递归拆分完成任务的项目,表现一般但可以带来一些启发。

Condition on good performance
Prompt Engineering
LLM 其实有”不想成功完成任务”的”心理怪癖”,它只是想模拟训练集的数据,但你想完成任务,因此你要做出要求。
如:对于一个数学问题,训练数据中可能有一个学生给出了错误答案,而一个数学专家给出了完美的答案,Transformers 无法区分哪个答案质量高。所以你必须要求它才能得到更好的表现。

听上去可能很荒唐,这能让 Transformers 现在不必将概率密度寄托在低质量的解决方案上
但也不要让它有”400 的 IQ”,这可能会得到科幻作品般的回答。
Tools / Plugins
LLM 默认情况下不知道自己不擅长什么。 因此甚至可以在 prompt 中告诉它”你不擅长计算”,计算的部分用这个 token 组合(如通过调用计算器 api 得到的)

Retrieval-Augmented LLMs
搜索引擎是Retrieval only(只有检索能力) 的代表,也就是前 LLM 时代的主流。 而 LLM 则是Memory only,在两个极端的之间存在很大的Retrieval augment(检索增强) 空间。

以 LlamaIndex 为例,它可以连接不同类型的数据,对这些数据建立索引并对 LLM 开放。
原理是将所给的文档分成块 (chunks),然后嵌入它们得到表示数据的嵌入向量 (embedding vectors),把它存储在向量存储库中。提问时,会对向量存储发出某种查询,获取可能与所提出的任务相关的块,然后塞入 prompt 中再生成回答。实践中效果很好。
可以类比,就算是一个记忆力出色的学生,但期末考试前还是会希望能去教材中找到具体原文。
Constraint prompting
这基本上是一些强制 LLMs 输出特定模板的技术
下面例子中,我们强制要求 LLM 输出 JSON 格式,然后可以对放入模板中这些空白处的内容强制实施额外限制。

Microsoft 的”guidance”项目
Finetuning
模型微调意味着改变模型的权重,一些技术让这件事变得比以前更容易了。如 LoRA 可以确保你可以用低精度的推理(而不是梯度下降)只训练模型中小而稀疏的部分(只有部分允许更改),做到有效微调,效果很好的同时降低了成本。
Suggestions
建议分为针对两个目标如下,也算是回顾了。
目标 1 得到最佳表现:
- 使用 GPT-4。
- 设计详细任务上下文、相关信息和指令的提示(prompt)。
- 若无法通过电邮回复,询问任务承包人将会怎样做。
- 为提示(prompt)添加任何相关的上下文或信息。
- 尝试使用之前幻灯片中提到的提示工程技术(prompt engineering techniques)。
- 使用少数示例(few-shot examples)进行实验,确保这些示例 1)与测试案例相关,2)多样性(如果适当)。
- 使用工具/插件来卸载对于大型语言模型(LLMs)难以处理的任务(如计算、代码执行等)。
- 质量时间优化流程/“链(chains)“。
- 如果你对已经最大化了提示效用有信心,考虑收集 SFT 数据和 RLHF 微调(fine-tuning)。
目标 2 优化成本:
- 一旦实现了最高性能,尝试节省成本的措施(例如使用更短的提示,GPT-3.5 等)。