ai-workshop-newsletter
  • Posts
  • Tutorials
Tutorials

003_LLM_Basic

003 LLM - Basic¶

Reference:

  • Github repo: https://github.com/hkproj/transformer-from-scratch-notes
  • Video: https://www.youtube.com/watch?v=bCz4OMemCcA

什么是LLM?¶

大语言模型LLM(Large language model)是能够实现通用语言生成的模型,从大量的文本透过自监督和半监督式训练所得到的神经网路模型。目前最火热的大语言模型是基于Transformer架构来构建的GPT模型,如openai的GPT3.5和GPT4, Google的PaLM和Gemini,Meta的LLaMA(开源模型),以及Anthropic的Claude。 LLM可用于文本生成,属于一种生成式AI,通过输入的文本预测下一个标记或是单词。简言之,LLM在做的工作是“文字接龙”,透过前面的叙述,选择最适当的下一个单词。Transformer架构最早在2017年一篇名为“Attention Is All You Need”的论文被提及,演变到现在,除了文本生成的功能,也扩展到图像生成,语音生成等多模态(Multi modal)领域。 Transformer架构对比传统用于seq2seq的时间序列或文字序列的模型架构(如RNN,LSTM,CNN)有其优势,Transformer可以同时处理整个序列,利用现代计算机并行计算的能力,加快模型训练,同时自注意力机制,能捕获输入序列中长距离的依赖关系。

Transformer架构¶

Transformer架构如下图: Transformer_Architecture.png

一般神经网路常由Encoder和Decoder组成,Transformer架构的左侧部分为Encoder,右侧部分为Decoder。

Encoder¶

Transformer的Encoder部分,如下图所示:

Transformer_Encoder_Part.png

Embedding¶

Embedding是将原始的输入字串先做Tokenize(分成一个个单词或小于一个单词的组合),Token数量也常被生成式模型作为计费的标准。再将每个Token所对应的ID标记(每个Token有固定的ID),再将每个Token编码成一个512长的向量(不同模型的embedding长度不同),注意Token的ID是固定的,类似字典的位置,但是Embedding之后的向量内容,在同一个Token的不同字串场景不相同。如下图所示:

Transformer_Encoder_Part_Embedding.png

Positional Encoding¶

Positional Encoding的目的是将每个Token在句子中的位置信息增加到编码当中,使得Token在句子中的位置,不同Token的相邻关系能够被模型在训练的过程学习。首先使用下图中两个方程式来计算每个Token长度为512的向量数值。

Transformer_Encoder_Part_Positional_Encoding_1.png

再将位置信息和前述Token编码向量相加,做为输入神经网路前处理的编码,如下图:

Transformer_Encoder_Part_Positional_Encoding_2.png

Self Attention (Single-Head Self Attention)¶

Self Attention自注意力机制是个巧妙地安排。

$Attention(Q, K, V) = softmax\left(\frac{QK^T}{\sqrt{d_k}}\right)V$

Transformer_Encoder_Part_Self_Attention_1.png

上图中说明自注意力机制的原理,$Q$,$K$,$V$都是相同的输入,图中示例是一个$[6, 512]$的矩阵,代表着6个Token的单词和前述每个Token Embedding后512长的向量。将$Q$和$K^T$矩阵相乘之后再除以$\sqrt{512}$得到$[6, 6]$的矩阵其中包含了每个Token与其他Token的关联性。这里用到的Softmax是机器学习常用在output layer的一个方程式,其目的是使得每个输出的综合介于0~1之间,相当于人为的将输出限制在0~1之间,以便找出数值最大的输出当作预测的结果。

$Softmax(x_i) = \frac{e^{x_i}}{\sum_{j=1}^{K} e^{x_j}}$

Transformer_Encoder_Part_Self_Attention_2.png

接下来再将上图中$[6,6]$的矩阵乘上$V$是原始输入的$[6, 512]$矩阵,所得到的$[6, 512]$自注意力矩阵,这个矩阵的运算包含了每个Token在字典的ID,在句子的位置,以及每个Token和其他Token相对关系。

Multi-Head Attention¶

多头注意力机制是Transformer架构最重要的一项设计,其定义如下:

Transformer_Encoder_Part_Multi_Head_Attention_1.png

$Multi-Head(Q,K,V)$的定义是将$head_1~head_h$组合起来,再乘上$W^o$, 而$head_i$则是将$(Q,K,V)$分别乘上一组参数$(W_i^Q, W_i^K, W_i^B)$,用前一节的但注意力的算法计算出来。

详细的Multi-Head-Attention计算说明如下图:

Transformer_Encoder_Part_Multi_Head_Attention_2.png

  • $seq$代表输入字串长度(tokens数量),例如前面案例为6个tokens。
  • $d_{model}$代表模型的维度,例如前面案例,使用512的长度做编码。 = $h$代表有几个头,positional encoding后,分了四个分支输入给Multi-Head-Attention和Add & Norm,因此$h$数值为4。
  • $d_k = d_v = \frac{d_{model}}{h}$,因此数值为$512/4=128$。

上图计算的过程说明:

  1. 将$Input[seq,d_{model}]$复制3份,分别是$Q[seq,d_{model}]$, $K[seq,d_{model}]$, $V[seq,d_{model}]$, $Q, K, V$的物理意义分别为Query, Key, Value.
  2. 将$Q, K, V$分别乘上不同一组参数$W^Q[d_{model},d_{model}], W^K[d_{model},d_{model}], W^V[d_{model},d_{model}]$, 得到$Q'[seq,d_{model}], K'[seq,d_{model}], V'[seq,d_{model}]$。
  3. 将$Q', K', V'$分别拆分为$Q1 \sim Q4[seq,d_k]$, $K1 \sim K4[seq,d_k]$,$V1 \sim V4[seq,d_k]$的矩阵, 这些$Q1 \sim Q4, K1 \sim K4, V1 \sim V4$使用前述单注意力的方程式$Attention(Q, K, V) = softmax\left(\frac{QK^T}{\sqrt{d_k}}\right)V$计算出$head1 \sim head4$。
  4. 最后将$head1 \sim head4$合并成$H[seq, h*d_v]$的矩阵,再根据定义乘上$W^o[h*d_v, d_{model}]$得到多头注意力机制的矩阵$MH-A[seq,d_{model}]$。
  5. 这一连串操作下来,将$Input[seq,d_{model}]$的矩阵,在保持矩阵维度不变的条件下,转换成输入的每个token跟其他token是否有关联性的多头矩阵$MH-A[seq,d_{model}]$,这个操作对于后续模型的训练,在同一个字(token),因上下文而有不同意思的状况有帮助。

Add & Norm(normalization)¶

Normalization是将$MH-A[seq,d_{model}]$做标准化,同时增加参数$\epsilon$做为后续模型训练过程中调整的参数。

Transformer_Encoder_Part_Add_Norm.png

上图中,每一个token先计算其平均$\mu$和标准差$\sigma$,添加上$\epsilon$后,做为标准化后的数值$\hat{x_j}=\frac{x_j-\mu_j}{\sqrt{\sigma_j^2+\epsilon}}$。

Decoder¶

Transformer的Decoder部分,如下图所示:

Transformer_Decoder_Part.png Transformer_Decoder_Part_2.png

Decoder的Embedding和Positioning和Encoder部分一样,区别在于Multi-Head Attention的输入,由Encoder提供$K,V$的矩阵,而$Q$由“Masked Multi-Head Attention”提供。

Masked Multi-Head Attention¶

使用在Decoder的Masked Multi-Head Attention,设计的用意在于模型只能从已知的一个个按顺序输入的token知道位置,而不应该提前知道整个字串后续有什么token。因此在Attention计算softmax之前,将未知的部分数值调整为"$-\infty$",在softmax之后,这些数值将等于$0$.

Transformer_Decoder_Part_Masked_Multi_Head_Attention.png

Transformer_Decoder_Part_Masked_Multi_Head_Attention2.png

Training¶

Transformer模型的训练过程如下图所示:

Transformer_Training.png

此范例说明如何将“I love you very much”这句英文,训练模型输出翻译为意大利语“Ti amo molto”的过程。

  1. 首先将模型的输入“I love you very much”标记成I love you very much,其中代表Start Of Sentence, 代表End Of Sentence。
  2. 将输入由前面提到的Encoder部分做编码,提交给Decoder部分。
  3. 将答案“Ti amo molto”标记成“Ti amo molto”,做为Decoder的输入。
  4. 在Decoder的计算中,有来自Encoder编码I love you very much所得到的$K,V$,以及Decode输入的$Q$Ti amo molto,这些矩阵的维度是$[seq,d_{model}]$,为了正确输出字典中的字,Decoder之后有线性转换,将$d_{model}$对应到字典的大小$vocab\_ size$,在经过softmax之后,才能找到对应的字。
  5. 将训练的目标设定为"Ti amo molto",目标是训练的过程期望模型正确的输出所要的结果,亦即期望模型能做到以下: 看到 --> 输出 Ti 看到 Ti --> 输出 amo 看到 amo --> 输出 molto 看到 molto --> 输出 (结束)
  6. 每一步的训练评估Cross Entropy Loss做为Loss function, 用Gradient descent调整参数,直到模型能输出正确的答案。

Inference¶

训练后模型推理的过程,同样以“I love you very much”翻译为意大利语为例子。 模型的Encoder输入同样为“I love you very much”,不同之处在于Decoder的输入只提供“”,如下图:

Transformer_Inference_1.png

根据Decoder所计算Softmax最大值做为下一个字,此例应为“Ti”。

再将“Ti”做为Decoder输入,同时使用既有的Encoder输出(“I love you very much”不变不需要再计算),继续进行第二轮的推理,如下图所示。

Transformer_Inference_2.png

此时应得到下一个字“amo”,再将“Ti amo”做为下一轮的输入。。。持续迭代,直到出现如下图:

Transformer_Inference_4.png

出现完成推理的过程。

建议¶

生成式AI从2022年OpenAI推出chatgpt才开始引爆AI热潮,此前大部分都是专用型的AI模型,近期大量论文和免费课程可以在网路上找到学习。可以参考以下网站提供免费学习,或是自行上网搜索相关信息,Generative的AI内容教学书籍较少,现阶段大部分在线上先发行。

  • https://www.deeplearning.ai/
  • https://developers.google.com/machine-learning
  • https://www.cloudskillsboost.google/paths/118
  • https://microsoft.github.io/AI-For-Beginners/
© ai-workshop-newsletter 2024