赞
踩
本文总结大模型相关基础知识,用于大模型学习入门
Transformer 模型的自注意力(Self Attention)机制涉及三种线性变换:查询(Q)、键(K)、值(V),以及通过计算注意力权重和加权求和来生成最终的输出。以下是自注意力机制的公式:
假设输入序列为 X ∈ R L × d X \in \mathbb{R}^{L \times d} X∈RL×d,其中 L L L 是序列长度, d d d 是特征维度。自注意力层中的线性变换矩阵为 W q ∈ R d × d k W_q \in \mathbb{R}^{d \times d_k} Wq∈Rd×dk、 W k ∈ R d × d k W_k \in \mathbb{R}^{d \times d_k} Wk∈Rd×dk 和 W v ∈ R d × d v W_v \in \mathbb{R}^{d \times d_v} Wv∈Rd×dv,其中 d k d_k dk 和 d v d_v dv 是分割查询、键和值时的维度。
查询(Q)、键(K)和值(V)的线性变换:
多头拆分:
注意力得分计算:
注意力加权求和:
上述公式涵盖了Transformer模型中自注意力层的基本计算步骤。在实际应用中,通常还会考虑添加缩放(scaling)、掩码(masking)等操作来优化注意力机制的计算过程。多头自注意力则在每个头上分别进行这些计算,然后将多个头的输出拼接或串联起来,进一步提取序列中的信息
一个多头 Self Attention 代码实现如下:
import torch
import torch.nn.functional as F
class SelfAttentionLayer(torch.nn.Module):
def __init__(self, d_model, num_heads):
super(SelfAttentionLayer, self).__init__()
self.d_model = d_model
self.num_heads = num_heads
self.d_k = d_model // num_heads
# 线性变换矩阵
self.W_q = torch.nn.Linear(d_model, d_model, bias=False)
self.W_k = torch.nn.Linear(d_model, d_model, bias=False)
self.W_v = torch.nn.Linear(d_model, d_model, bias=False)
def split_heads(self, x, batch_size):
x = x.view(batch_size, -1, self.num_heads, self.d_k)
return x.permute(0, 2, 1, 3)
def forward(self, x):
batch_size, seq_len, d_model = x.size()
q = self.W_q(x)
k = self.W_k(x)
v = self.W_v(x)
q = self.split_heads(q, batch_size)
k = self.split_heads(k, batch_size)
v = self.split_heads(v, batch_size)
# Scaled Dot-Product Attention
attn_scores = torch.matmul(q, k.transpose(-2, -1)) / (self.d_k ** 0.5)
attn_weights = F.softmax(attn_scores, dim=-1)
# Attention加权求和
output = torch.matmul(attn_weights, v)
output = output.permute(0, 2, 1, 3).contiguous().view(batch_size, seq_len, -1)
return output
# 测试自注意力层
d_model = 512
num_heads = 8
seq_len = 10
batch_size = 16
input_data = torch.randn(batch_size, seq_len, d_model)
self_attention = SelfAttentionLayer(d_model, num_heads)
output = self_attention(input_data)
print(output.size()) # 输出: torch.Size([16, 10, 512])
上面 Transformer 代码中有使用 d k \sqrt{d_{k}} dk 来对 softmax 之后的结果进行 scale,解释如下:
We suspect that for large values of d k d_{k} dk, the dot products grow large in magnitude, pushing the softmax function into regions where it has extremely small gradients. To counteract this effect, we scale the dot products by 1 d k \frac{1}{d_{k}} dk1. To illustrate why the dot products get large, assume that the components of q and k are independent random variables with mean 0 and variance 1. Then their dot product q ⋅ k = ∑ i = 1 d k ( q i k i ) q ⋅ k=\sum_{i=1}^{d_{k}}(q_{i}k_{i}) q⋅k=∑i=1dk(qiki), has mean 0 and variance d k d_{k} dk.
对于任何一门语言,单词在句子中的位置以及排列顺序是非常重要的,它们不仅是一个句子的语法结构的组成部分,更是表达语义的重要概念。一个单词在句子的位置或排列顺序不同,可能整个句子的意思就发生了偏差。
I do not like the story of the movie, but I do like the cast.
I do like the story of the movie, but I do not like the cast.
上面两句话所使用的的单词完全一样,但是所表达的句意却截然相反。那么,引入词序信息有助于区别这两句话的意思。
Transformer 模型抛弃了 RNN、CNN 作为序列学习的基本模型。我们知道,循环神经网络本身就是一种顺序结构,天生就包含了词在序列中的位置信息。当抛弃循环神经网络结构,完全采用 Attention 取而代之,这些词序信息就会丢失,模型就没有办法知道每个词在句子中的相对和绝对的位置信息。因此,有必要把词序信号加到词向量上帮助模型学习这些信息,位置编码(Positional Encoding)就是用来解决这种问题的方法。

语言模型是对文本进行推理。由于文本是字符串,但对模型来说,输入只能是数字,所以就需要将文本转成用数字来表达。最直接的想法,就是类似查字典,构造一个字典,包含文本中所有出现的词汇,比如中文,可以每个字作为词典的一个元素,构成一个列表;一个句子就可以转换成由每个词的编号(词在词典中的序号)组成的数字表达。分词就是将连续的字序列按照一定的规范重新组合成语义独立词序列的过程,一个分词示例流程如下:
古典分词方法
拆分为单个字符(Character embedding)
基于子词的分词方法(Subword Tokenization)
字节对编码(BPE, Byte Pair Encoder),又称 digram coding 双字母组合编码,是一种数据压缩 算法,用来在固定大小的词表中实现可变⻓度的子词。该算法简单有效,因而目前它是最流行的方法。
WordPiece:WordPiece算法和BPE类似,区别在于WordPiece是基于概率生成新的subword而不是下一最高频字节对。- Unigram:它和 BPE 等一个不同就是,bpe是初始化一个小词表,然后一个个增加到限定的词汇量,而 Unigram 是先初始一个大词表,接着通过语言模型评估不断减少词表,直到限定词汇量。
在 Openai Tokenizer demo 中,中文分词后的 token 数量远大于原始中文字符数目
原因剖析:OpenAI 为了支持多种语言的 Tokenizer,采用了文本的一种通用表示:UTF-8 的编码方式,这是一种针对 Unicode 的可变长度字符编码方式,它将一个 Unicode 字符编码为1到4个字节的序列。
对于任何一门语言,单词在句子中的位置以及排列顺序是非常重要的,它们不仅是一个句子的语法结构的组成部分,更是表达语义的重要概念。一个单词在句子的位置或排列顺序不同,可能整个句子的意思就发生了偏差。
I do not like the story of the movie, but I do like the cast.
I do like the story of the movie, but I do not like the cast.
上面两句话所使用的的单词完全一样,但是所表达的句意却截然相反。那么,引入词序信息有助于区别这两句话的意思。
Transformer模型抛弃了RNN、CNN作为序列学习的基本模型。我们知道,循环神经网络本身就是一种顺序结构,天生就包含了词在序列中的位置信息。当抛弃循环神经网络结构,完全采用Attention取而代之,这些词序信息就会丢失,模型就没有办法知道每个词在句子中的相对和绝对的位置信息。因此,有必要把词序信号加到词向量上帮助模型学习这些信息,位置编码(Positional Encoding)就是用来解决这种问题的方法。


参考:What is Temperature in NLP / LLMs?
参考:Huggingface 的 generate 方法介绍:top_p sampling、top_k sampling、greedy_search、beam_search
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。