最小GPT
GPT 的 PyTorch 重新实现,包括训练和推理。 minGPT 试图做到小、干净、可解释和具有教育意义,因为大多数当前可用的 GPT 模型实现可能有点庞大。 GPT 不是一个复杂的模型,这个实现大约有 300 行代码(参见 mingpt/model.py)。所发生的事情就是将一系列索引输入到 Transformer 中,然后得出序列中下一个索引的概率分布。大多数复杂性只是为了提高效率而巧妙地进行批处理(跨示例和序列长度)。
注意(2023 年 1 月) :虽然我可能会继续接受并更改一些细节,但 minGPT 处于半存档状态。有关最新进展,请参阅我重写的 nanoGPT。基本上,minGPT 在各种各样的地方(笔记本、博客、课程、书籍等)被引用,这让我不太愿意做出更大的改变来推动代码前进。我还想稍微改变一下方向,从只关注教育到仍然简单且可破解但具有牙齿的东西(重现中型行业基准,接受一些权衡以获得运行时效率等)。
minGPT 库由三个文件组成:mingpt/model.py 包含实际的 Transformer 模型定义,mingpt/bpe.py 包含一个稍微重构的字节对编码器,它在文本和整数序列之间进行转换,就像 OpenAI 在 GPT、mingpt/trainer 中所做的那样。 py 是(独立于 GPT 的)PyTorch 样板代码,用于训练模型。然后在projects
文件夹中有许多使用该库的演示和项目:
-
projects/adder
从头开始训练 GPT 来添加数字(受到 GPT-3 论文中的加法部分的启发) -
projects/chargpt
将 GPT 训练为某些输入文本文件上的字符级语言模型 demo.ipynb
在一个简单的排序示例中以笔记本格式展示了GPT
和Trainer
的最小用法generate.ipynb
展示了如何加载预训练的 GPT2 并根据提示生成文本
库安装
如果你想import mingpt
到你的项目中:
git clone https://github.com/karpathy/minGPT.git
cd minGPT
pip install -e .
用法
以下是实例化 GPT-2(124M 参数版本)的方法:
from mingpt . model import GPT
model_config = GPT . get_default_config ()
model_config . model_type = 'gpt2'
model_config . vocab_size = 50257 # openai's model vocabulary
model_config . block_size = 1024 # openai's model block_size (i.e. input context length)
model = GPT ( model_config )
以下是训练它的方法:
# your subclass of torch.utils.data.Dataset that emits example
# torch LongTensor of lengths up to 1024, with integers from [0,50257)
train_dataset = YourDataset ()
from mingpt . trainer import Trainer
train_config = Trainer . get_default_config ()
train_config . learning_rate = 5e-4 # many possible options, see the file
train_config . max_iters = 1000
train_config . batch_size = 32
trainer = Trainer ( train_config , model , train_dataset )
trainer . run ()
有关更具体的示例,请参阅demo.ipynb
。
单元测试
覆盖范围还不是非常惊人,但是:
python -m unittest discover tests
待办事项
- 在任意给定文本文件上添加 gpt-2 微调演示
- 添加对话代理演示
- 现有项目的更好的成果文档(adder、chargpt)
- 添加混合精度和相关的训练缩放功能
- 分布式培训支持
- 重现项目/中的一些基准,例如text8或其他语言建模
- 正确的日志记录而不是打印语句业余时间哈哈
- 我可能应该有一个requirements.txt 文件...
- 应该可以加载除 gpt2-* 之外的许多其他模型权重
参考
代码:
- openai/gpt-2 有 TensorFlow 中的模型定义,但没有训练代码
- openai/image-gpt 在其代码中有一些更现代的 gpt-3 类似修改,也是很好的参考
- Huggingface/transformers 有一个语言建模示例。它功能齐全,但因此追踪起来也有些困难。例如,一些大型函数在各种分支语句后面有多达 90% 未使用的代码,这些代码在简单语言建模的默认设置中未使用
论文+一些实施说明:
通过生成预训练提高语言理解 (GPT-1)
- 我们的模型很大程度上遵循了原始变压器的工作原理
- 我们训练了一个仅包含 12 层解码器的 Transformer,它带有屏蔽的自注意力头(768 个维度状态和 12 个注意力头)。对于位置前馈网络,我们使用 3072 维内部状态。
- Adam 最大学习率为 2.5e-4。 (后来该模型尺寸的 GPT-3 使用 6e-4)
- LR 衰减:在前 2000 次更新中从零线性增加,并使用余弦时间表退火到 0
- 我们在 64 个随机采样的、包含 512 个 token 的连续序列的小批量上训练 100 个 epoch。
- 由于层规范在整个模型中广泛使用,因此简单的权重初始化 N(0, 0.02) 就足够了
- 具有 40,000 个合并的字节对编码 (BPE) 词汇
- 残差、嵌入和注意力丢失,正则化率为 0.1。
- (37) 中提出的 L2 正则化的修改版本,所有非偏差或增益权重的 w = 0.01
- 对于激活函数,我们使用高斯误差线性单元(GELU)。
- 我们使用学习的位置嵌入代替原始工作中提出的正弦版本
- 对于微调:我们以 0.1 的比率向分类器添加 dropout。学习率为 6.25e-5,批量大小为 32. 3 epoch。我们使用线性学习率衰减计划,其中预热时间超过训练的 0.2%。 λ设置为0.5。
- GPT-1 模型有 12 层,d_model 768,约 117M 参数
语言模型是无监督多任务学习者 (GPT-2)
- LayerNorm 被移至每个子块的输入,类似于预激活残差网络
- 在最终的自注意力块之后添加了额外的层归一化。
- 使用修改后的初始化,该初始化考虑了剩余路径上随模型深度的累积。我们在初始化时将残差层的权重缩放为 1/√N,其中 N 是残差层的数量。 (很奇怪,因为在他们发布的代码中我只能找到旧的 0.02 的简单用法...在他们发布的 image-gpt 中我发现它用于 c_proj,即使如此也仅用于 attn,而不用于 mlp。呵呵。https: //github.com/openai/image-gpt/blob/master/src/model.py)
- 词汇量扩大至50,257
- 将上下文大小从 512 个标记增加到 1024 个标记
- 使用更大的批量大小 512
- GPT-2 使用 48 层和 d_model 1600(相对于原始 12 层和 d_model 768)。 ~1.542B 参数
语言模型是少样本学习者 (GPT-3)
- GPT-3:96层,96个头,d_model为12,288(175B参数)。
- GPT-1-like:12层,12头,d_model 768(125M)
- 我们使用与 GPT-2 相同的模型和架构,包括其中描述的修改后的初始化、预标准化和可逆标记化
- 我们在变压器的层中使用交替的密集和局部带状稀疏注意力模式,类似于稀疏变压器
- 我们的前馈层始终是瓶颈层大小的四倍,dff = 4 * dmodel
- 所有模型都使用 nctx = 2048 个令牌的上下文窗口。
- Adam,β1 = 0.9,β2 = 0.95,eps = 10−8
- 所有模型都使用 0.1 的权重衰减来提供少量的正则化。 (注:我相信 GPT-1 使用了 0.01,见上文)
- 将梯度的全局范数限制为 1.0
- 前 3.75 亿个代币的线性 LR 预热。然后使用余弦衰减将学习率降低至其值的 10%,超过 2600 亿个代币。
- 根据模型大小,在训练的前 4-120 亿个令牌中逐渐将批量大小从较小值(32k 个令牌)线性增加到完整值。
- 始终使用完整的 2048 大小的时间上下文窗口,并带有特殊的 END OF DOCUMENT 标记分隔符
从像素生成预训练(图像 GPT)
- 处理图像时,我们选择恒等排列 πi = i(1 ≤ i ≤ n),也称为光栅顺序。
- 我们通过使用 k = 512 的 k 均值聚类(R、G、B)像素值来创建我们自己的 9 位调色板。
- 我们最大的模型 iGPT-XL 包含 L = 60 层,并使用 d = 3072 的嵌入大小,总共 6.8B 个参数。
- 我们的下一个最大模型 iGPT-L 本质上与 GPT-2 相同,L = 48 层,但包含稍小的嵌入大小 d = 1536(vs 1600),总共 1.4B 个参数。
- 我们使用与 GPT-2 相同的模型代码,不同之处在于我们以与稀疏变换器 (Child et al., 2019) 中的层相关的方式初始化权重,并对产生 logits 的所有投影进行零初始化。
- 我们还训练 iGPT-M,一个 455M 参数模型,L = 36 和 d = 1024
- iGPT-S,一个 76M 参数模型,L = 24 和 d = 512(好吧,有多少个头?看起来像 Github 代码声明 8)
- 在预训练 iGPT-XL 时,我们使用批量大小 64 并训练 2M 迭代,对于所有其他模型,我们使用批量大小 128 并训练 1M 迭代。
- Adam 的 β1 = 0.9 且 β2 = 0.95
- 学习率预热一个 epoch,然后衰减到 0
- 我们没有使用权重衰减,因为应用 0.01 的小权重衰减不会改变表示质量。
- iGPT-S LR 0.003
- 不使用 dropout。
执照
麻省理工学院