接下来,我们用三篇文章阐述**如何实现一个简版ChatGPT。**

1.回顾

想实现一个简版ChatGPT,依赖于如下前置知识:

  • 机器学习基本原理,可参考笔者这几篇文章:
    • 《【chatGPT】学习笔记3-机器学习基本原理(上)》
    • 《【chatGPT】学习笔记4-机器学习基本原理(下)》
  • 经典NLP相关技术,可参考笔者这几篇文章:
    • N-Gram:《【chatGPT】学习笔记6-手撸一个上古GPT》
    • Embedding:《【chatGPT】学习笔记7-词的向量化,大语言模型的关键部件》
    • 神经概率语言模型:《【chatGPT】学习笔记8-神经概率语言模型,大语言模型的关键部件2》
    • Seq2Seq:《【chatGPT】学习笔记9-Transformer之Seq2Seq,大语言模型的关键部件3》
  • 现代NLP相关技术,可参考笔者这几篇文章:
    • 注意力机制:《【chatGPT】学习笔记13-Transformer之注意力机制,大语言模型的关键部件4》
    • Transformer:《【chatGPT】学习笔记16-Transformer架构,大语言模型的关键部件5》

2.实现简版GPT

这是参考Transformer架构绘制的简版ChatGPT整体架构,我们将对它进行拆解:

image-20231017113929233

(1)整体

将上图抽象化,我们可以看到:

  • 简版GPT遵循Transfomer架构,但是没有实现编码器
  • Decoder的输出交给一个线性层,将解码器的输出转换为目标词汇表大小的概率分布——这属于常规操作,与Transformer核心思想关系不大。

image-20231017134713086

代码实现如下:

  • 1:对应上图将Outputs输入给Decoder
  • 2:对应上图将Decoder的输出,传入给线性层。

image-20231017135734066

(2)局部1:正弦位置编码表

首先,我们来细化OutputsDecoder之间的流程:

  • STEP1.对Outputs实施词嵌入,得到词向量。
  • STEP2.在词向量Decoder之间增加了位置编码表(也是一个向量),这个位置编码表体现了词和词序的关系
    • 由于Transformer取消了RNN,也就不再逐个词串行处理,所以必须建立词和词序的关系
  • STEP3.将STEP2的位置表码表向量和词向量相加,输入给Decoder

image-20231017140335543

正弦位置编码表的计算原理参见《【chatGPT】学习笔记16-Transformer架构,大语言模型的关键部件5》的”(2)局部1:正弦位置编码表"章节,本文不再赘述。

代码实现如下:

image-20231017140636308

(3)局部2:解码器堆栈

我们再来细化解码器

  • 编码器本质上由N个解码器串联而成的解码器堆栈
  • 我们的实现,也按照论文的设定层数,N=6

image-20231017150909585

(4)局部3:解码器

我们再进一步细化解码器Decoder

  • 解码器Decoder多头注意力前向传播网络组成。

image-20231017150925061

解码器堆栈的代码实现如下:

  • :这就是创建的位置编码层,再将词向量和位置编码向量相加
  • :这就是将多个解码器叠加成解码器堆栈,每个解码器的输入上个解码器的输出上个解码器输出的注意力权重
  • :这就是表示解码器堆栈输出的解码器输出

image-20231017142049236

解码器的代码实现如下:

  • :就是多头注意力层第一个解码器多头注意力层的输入是词嵌入+位置编码向量之和以及自注意力掩码后续解码器多头注意力层的输入是上一个解码器的输出自注意力掩码
  • :就是前向传播网络,它的输入是多头注意力层的输出

image-20231017145220345

我们接下来看多头注意力层、前向传播网络、自注意力位置掩码如何实现?

(5)局部4:多头注意力

多头注意力的原理参见《【chatGPT】学习笔记16-Transformer架构,大语言模型的关键部件5》的”(5)局部4:多头注意力"章节,本文不再赘述。

image-20231017150943298

代码实现如下:

image-20231017145622219

(6)局部5:前向传播网络

多头注意力的原理参见《【chatGPT】学习笔记16-Transformer架构,大语言模型的关键部件5》的”(6)局部5:前向传播网络"章节,本文不再赘述。

image-20231017151000709

代码实现如下:

image-20231017150114991

(7)局部6:填充位置掩码

多头注意力的原理参见《【chatGPT】学习笔记16-Transformer架构,大语言模型的关键部件5》的”(7)局部6:填充位置掩码"章节,本文不再赘述。

image-20231017151014381

代码实现如下:

image-20231017150413819

(8)局部7:后续位置掩码

多头注意力的原理参见《【chatGPT】学习笔记16-Transformer架构,大语言模型的关键部件5》的”(10)局部9:后续位置掩码"章节,本文不再赘述。

image-20231017151026419

代码实现如下:

image-20231017150515799

(9)模型训练

至此,我们已经完整地实现了Transformer架构,我们开始对其进行训练:

  • 数据集如下:

image-20231017151515137

  • 模型训练:

image-20231017151651529

image-20231017151717714

  • 训练好后,会生成简版GPT的pth模型文件:

image-20231017151835127

(10)模型测试

  • 测试用例采用贪婪编码和集束编码,比较简单,具体代码如下:

image-20231017151956136

3.小结

  • 本文基于Transformer架构,复现了简版ChatGPT,其关键在于只有解码器。
  • 理论上,如果有足够算力、足够训练数据,可以将此简版ChatGPT训练到GPT3的水平。
  • 那么,GPT3到ChatGPT还有一定的距离,我们知道ChatGPT公开的信息中,还对GPT3进行了监督学习微调SFT基于人类反馈的强化学习RLHF等,得到了InstructGPT,进而得到了ChatGPT。

我们下一步继续针对简版ChatGPT开展SFT和RLHF,且听下回分解。