专题研修

31|推导附章:注意力反向传播与可训练检索

专题研修约 3.9 千字1 组分步图解

目标:能沿计算图手工求导,再用数值实验验证;把模型“怎样学习”与前面“怎样推理”闭合。实验:attention_gradients.py,提供解析反向和有限差分。

本章目录

沿着对象与状态理解本章

反向推导中每个梯度对象都要对齐前向算子与shape;先看局部变化怎么传回去。

下方图解的固定输入在“输入与适用条件”中声明。它用于解释本章机制,不与本章其他独立例子的数值暗中接续。

动态图解 · F18

训练:给每个位置一道“下一项”题

为什么训练看完整句,生成却只能往前走?

训练时答案放在试卷的评分区,所以各位置的题目可以同时准备;mask负责不让模型读到自己的答案。生成时后续Token还未决定,下一题的前缀依赖本题选择。两者共享因果预测目标,但已知信息不同。

标签用于评分的真实下一Token。
交叉熵本例为真实目标概率的负对数。
有效目标数实际参与评分的位置数,不必等于补齐长度。

输入与适用条件:标签对齐使用5项序列;单位置交叉熵与PAD平均分别是明确独立的小例,不假称那些概率来自对齐图的模型。

1 / 5 · 把输入和目标错开一格

第1步,共5步

窄屏可左右滑动图形,或点击“放大图形”。文字解释紧随图后。

训练:给每个位置一道“下一项”题:把输入和目标错开一格我输入0爱输入1学习输入2!输入3爱目标0学习目标1!目标2EOS目标3

完整教学序列为“我/爱/学习/!/EOS”。输入用前四项,目标用后四项。每个输入位置预测的是其后一个真实Token。

输入=[1,2,3,5];目标=[2,3,5,6]

默认静止。用“下一步”看完解释再继续;播放到最后一步自动停止。键盘聚焦播放器后,可用左右键逐步查看、空格播放/暂停。图中颜色辅助区分,含义同时用文字注明。

为什么需要

用清晰的预测任务,把参数更新与语言序列关系连接。

怎样实现

正确移动标签、限制可见性、屏蔽无效目标、按有效数归一化。

可能的代价与误解

偷看未来会产生漂亮但虚假的训练成绩;训练样本重复或泄漏也会高估泛化。

如何判断是否做对

用极小固定序列验证每个输入位置和目标位置,再验证PAD不影响有效损失。

1. 从单头注意力开始

设Q为m×d,K为n×d,V为n×dv,定义S=QKᵀ/√d,按行softmax得到P,输出O=PV。允许m不等于n,以覆盖缓存中新块查询面对完整历史的形状。设上游损失对输出梯度G为m×dv。

前向可以理解为两个步骤:用Q/K决定每行权重,再按权重混合V。反向同样分为权重路径和内容路径。这个推导来自矩阵微分与softmax导数,不需要把注意力拟人化。[N07]

2. 先对V和P求导

由dO=dP·V+P·dV及标量损失的迹形式,可得:

∂L/∂V = Pᵀ G                    [n,dv]
∂L/∂P = G Vᵀ                    [m,n]

第一式表示每个Value从读取它的查询位置累计梯度。第二式表示若改变某个注意力权重,输出沿对应V方向变化会如何影响损失。形状核对是推导的一部分,不应只凭公式记忆。

3. softmax的Jacobian不必显式建立

对一行p,Jacobian是diag(p)−ppᵀ。直接建立n×n矩阵会浪费;设该行上游梯度为g,可写:

ds = p ⊙ (g − Σj pj gj)

把所有行组合:D_S=P⊙(D_P−rowsum(P⊙D_P))。这一步使每行分数梯度和为零,与给整行分数加同一常数不改变softmax的性质一致。

若某位置被固定mask屏蔽,P为零,其对应分数梯度也应为零。全mask行则没有有效概率分布,本书显式拒绝。生产核若采用其他语义,需要在前向与反向保持一致。

4. 再传回Q与K

∂L/∂Q = D_S K / √d              [m,d]
∂L/∂K = D_Sᵀ Q / √d            [n,d]

注意K与V虽然都来自历史位置,梯度路径不同。Q/K影响选择权重,V影响被聚合内容。若只对V反向而不对Q/K反向,模型可能学到输出内容,却无法正确学习注意力匹配。

Q、K、V若都由同一个X通过不同投影产生,X梯度是三条路径贡献之和;每个投影权重梯度分别由输入转置乘对应输出梯度得到。残差支路还要把上游梯度直接加回。多头实现只是额外的形状重排和各头计算,最后合并处同样需要正确逆变换。

5. RoPE、RMSNorm与门控的反向直觉

RoPE对固定位置是正交线性变换,反向使用旋转矩阵转置,也就是相反角度旋转上游梯度。位置频率若固定,不需要对它优化;若某种架构学习相关参数,则计算图不同,不应一概而论。

RMSNorm设r=sqrt(mean(x²)+ε),y=γ⊙x/r。令g=上游⊙γ,则输入梯度为g/r−x·mean(g⊙x)/r³。这是直接项减去归一化尺度反馈项。把归一化当常数,会丢掉第二项,梯度错误但前向看起来正常。

SwiGLU由乘法门控组成,两个分支都应接收另一分支值乘以上游的梯度。SiLU还需要自身导数。实现时先验证单算子,再组合整层,通常比只看最终训练loss更容易定位。

6. 有限差分与自动求导如何配合

本书以L=sum(O⊙G)构造标量目标,对Q/K/V每个元素分别加减ε,比较数值梯度与解析梯度。小矩阵上代价可接受;大模型则只抽样部分维度或做方向导数检查。

ε过大,截断误差明显;过小,浮点舍入放大。使用float64、适中数值和明确容差更容易发现逻辑错误。配套测试比较非方形mask下的三类梯度,并验证仅首行输出参与损失时未来K/V梯度为零。

自动求导不是不需要验证。错误mask、错误标签或错误维度会让自动求导忠实计算“错误目标”的梯度。有限差分也只能证明相对于当前前向实现的导数,不能证明前向语义正确。因此需要数学不变性、负对照与任务测试共同形成证据。

7. Dense Retriever怎样学习“相关”

双塔检索可对一条查询q、正例d+和多个负例dj计算对比损失:

L = −log exp(s(q,d+)/τ) / Σj exp(s(q,dj)/τ)

它推动正例相对候选更相似,而不是保证绝对距离有统一业务意义。batch内负例提高效率,但可能包含实际上也相关的文档,形成假负例;困难负例能训练细区分,也可能引入标签错误。[N70]

如果训练数据只区分主题相关与不相关,模型可能无法区分同主题的新旧版本、肯定与否定。对代码检索,需要与实际任务相符的正负样本和评价。增加向量维度不会自动补上目标缺陷。

重排模型可以学习更细的查询—文档交互,但其训练标签若偏爱长文或某种格式,也会带来偏差。检索训练与第19章的评测设计必须共同考虑。

8. 这个附章如何使用

先运行现有实验,再故意删掉softmax导数中的行内减项,观察有限差分失败;接着删mask,观察因果梯度测试失败。最后比较PyTorch训练中的自动求导与手工推导,理解两者并不竞争:一个用于高效实现,一个用于验证与理解。

本章达标是能解释某个梯度为什么这样流动,能用实验抓住错导数,并知道实验的逻辑边界。它不等于已经掌握完整分布式训练或GPU反向kernel实现。

运行示例 · S31

用一个方向导数核对矩阵反传是否接对

输入与条件。函数f(Q)=上游G与Attention输出的点积;解析梯度已算得dQ=[0.5615202771,−0.1871734257],方向v=[1,−2]。

步骤与对象内部动作中间结果 / 新状态
1解析方向导数dQ·v约0.9358671285。
2有限差分取ε=10^-6,算(f(Q+εv)−f(Q−εv))/(2ε)应接近同一数。
3坐标检查再对Q/K/V每个元素分别扰动能定位转置或softmax雅可比错误。
4容差比较绝对/相对误差不是要求浮点小数逐字相同。
5模型边界通过梯度检查只证明这个算子实现不证明训练数据或整个Agent任务正确。

把过程连起来。从数学公式到代码,最有价值的示例之一是能用独立数值方法反证错误实现。

边界与反例。示例采用可微且不处于mask/选择变化边界的输入;有限差分在不连续点与低精度下要谨慎。

依据与适用范围:[DERIVE]。示例输入和场景由本书明确设定。

运行示例 · X08

让检索向量学习:查询向量真的往哪个方向移动

输入与条件。查询q=[1,0],正例a=[0.8,0.6],负例b=[0,1]。使用点积分数、两候选softmax和正例交叉熵;本步只更新q,不更新a、b。

步骤与对象内部动作中间结果 / 新状态
1先打分q·a=0.8,q·b=0正例概率≈0.689974,负例≈0.310026。
2对分数求导正例梯度p正−1,负例梯度p负约[-0.310026,0.310026]。
3传回查询dq=(p正−1)a+p负b得到[-0.248020,0.124010]。
4更新q学习率0.1,q新=q−0.1dq得到[1.024802,−0.012401];这一小步增加正负点积分数之差。
5独立核验分别轻微增减q的每个分量,用损失差除步长有限差分与上面的解析梯度一致。

把过程连起来。“训练更好的检索”对应的是明确目标、候选与梯度。不是人工给Embedding某一列命名后再调高该列。

边界与反例。这里是点积相似度,更新后不重新单位化q;若改用cosine或加归一化,必须把对应导数一起传回。

依据与适用范围:[DERIVE]。示例输入和场景由本书明确设定。

记录保存在本机浏览器。

输入关键词即可检索。

↑ ↓ 选择 Enter 打开Esc 关闭 · 仅本地搜索

阅读设置

阅读设置仅保存在本机浏览器,不上传任何数据。