LabHub
学习 学习路径 课程

Transformer — 手算一遍注意力

注意力就是加权平均

在 LabHub 中继续学习

一句话总结

注意力是确定“现在在这个位置上看哪个位置多少”,然后计算出值的加权平均**的运算。仅此而已。

概念图: 确定 · ,然后计算出值的 · Q(query) · K(key)

三个名字

从同样的输入中创建三个向量。

图书馆的比喻很准确。拿着问题(Q)去匹配书等的标题(K),然后拿出与之匹配的程度的书籍的内容(V)。

score  = Q · Kᵀ / √d       ← 얼마나 맞는가
weight = softmax(score)     ← 합이 1이 되게
out    = weight · V         ← 가중 평균

只有三行。其余的全部是重复做这三行,从不同的方向做。

为什么用√d除法——用数字

这是最常被忽略的部分,就是“就这样做”,理由很明确。

成分是独立的,分散度为1d维度向量的内积是方差d可以去。d=64面分数大致分布在±8范围内。

如果在Soft Max中加入±8分的分数会怎么样?e⁸ / e⁻⁸ ≈ 9백만是。**最大的一个几乎把1都拿走了,其余的就变成了0。**不是加权平均,而是直接“选择一个”。

那样就无法学习了。因为当softmax饱和时,斜率会接近0。

√d如果除以,分散率又恢复为1。在这个练习的第2阶段,直接测量这个——没有除以时的最大概率能上升到多高。

软麦克斯除以最大值后进行计算。

def softmax(xs):
    m = max(xs)                       # 이 한 줄이 없으면
    e = [exp(x - m) for x in xs]      # exp(1000) 에서 터진다
    s = sum(e)
    return [v / s for v in e]

exp(x - max)虽然在数学上是相同的值,但**不会出现溢位。**在实际代码中遗漏这一行的话,大值输入的瞬间infnan这个出来了。

口罩——看不到未来

语言模型学习如何正确识别以下的代币。但是注意力基本上是看所有位置。也就是说,看到答案后再回答。

所以分数矩阵的上方的三角形-inf变成。

      k0    k1    k2
q0   0.3  -inf  -inf
q1   0.1   0.5  -inf
q2   0.2   0.1   0.4

-infexp通过后正好变成0。不是乘以0,而是软最大值之前加上-inf才是关键——软最大值之后乘以0的话,剩下的加权数的和就不等于1了。

这就是“causal”或“decoder”掩码。BERT等编码器模型没有。所以BERT擅长看整个句子理解,GPT擅长连续写作。

多头——为什么拆分?

d=64与其一次性使用,不如分成8个d=8重复8次扎里注意力后连在一起。计算量几乎一样。

为什么?**一个softmax只能表达一种关系。**加权和为1,所以不能同时强烈地看多个地方。分头的话,哪一个头就是前面一个单词,哪一个头就是句子前的主语,哪一个头就是看引号对。

打开学习模型的头,实际上是那样分开的。

位置编码——注意力不知道顺序

这是第一次学习时最令人惊讶的部分。

**注意力完全没有顺序概念。**如果混合输入令牌,输出也会一样混合出来,但值本身不会改变(permutation equivariant)。“我喜欢你”和“我喜欢你”是无法区分的。

所以除了输入位置信息外还增加了位置信息。

**在第5步中亲自确认这个。**如果没有位置编码,如果混合输入的话,输出会按照原样混合,如果加起来的话就不一样了。

LayerNorm与残差连接

x = x + Attention(LayerNorm(x))
x = x + FFN(LayerNorm(x))

LayerNorm把注意力放在前面还是放在后面(pre-LN vs post-LN)实际上决定了学习稳定性。虽然原论文是post-LN,但最近几乎都是pre-LN——因为即使没有热身也能学习。

费用从哪里来

分数矩阵是n × n是。通过序列长度的平方进行内存和计算。如果将上下文4k增加到8k,是4倍。

试图减少这个的尝试是最近研究的重大方向。

整理

注意力本身只有三行。其余的内容是关于如何稳定、便宜、知道顺序地写出那三行的方法。在下次练习中直接写出那三行,如果没有缩放和位置编码,用数字看看会崩溃什么。

在现场

几乎没有直接做这个计算的事情。因为框架已经全部完成了。但是,应该记住的原因是遇到问题时应该看哪里在这里就分开了。

如果学习损失突然变成nan,通常是因为softmax前面值超出,如果戴错了面罩,就不会出现错误,安静地看着未来代币学习,只会有奇怪的好评价分数。如果改变了配置大小,结果变了,就应该怀疑正则化轴,如果将上下文增加两倍,内存增加四倍,这不是错误,而是结构上理所当然的事情。

如果运营推理服务的话,KV缓存很快就会成为内存预算。首先计算一下同时请求次数和最大上下文长度乘积的值是否进入GPU内存,如果进入不了,选择使用GQA的模型或降低上下文上限才是实际选择。