[{"data":1,"prerenderedAt":418},["ShallowReactive",2],{"article:column:/column/llm-to-agent-learning/08":3},{"id":4,"title":5,"body":6,"description":410,"extension":411,"meta":412,"navigation":413,"path":414,"seo":415,"stem":416,"__hash__":417},"column/column/llm-to-agent-learning/08.md","08｜Attention：当前位置怎样读取其他位置",{"type":7,"value":8,"toc":391},"minimark",[9,13,16,19,24,27,37,40,43,46,49,53,56,59,62,65,78,81,84,88,91,99,102,110,113,116,119,123,126,129,132,135,138,141,144,151,154,157,160,163,166,172,175,179,182,190,193,196,202,205,208,211,215,218,226,229,232,235,239,247,255,263,266,270,273,276,284,287,290,299,302,306,312,315,320,323,328,331,334,339,342,347,350,355,358,361,366,369,374,377,382,385,388],[10,11,12],"p",{},"“我吃了一个苹果”和“这台电脑来自苹果”，两处“苹果”需要结合不同上下文理解。第03章已经指出：如果相同token只查出相同向量，再各自经过同一个逐行变换，周围文字根本没有参与，它们便无法因此获得不同的上下文表示。",[10,14,15],{},"我们需要一种让位置之间交换信息的机制。Attention做的一件核心工作，就是让当前位置根据输入，决定从其他可见位置读取多少信息，再把读到的内容组合起来。这里的“注意”是数学运算的名字，不表示模型具有人的主观注意力。",[10,17,18],{},"先固定三件事：本章推理时不更新参数，只改变输入；用一个头算清楚；先允许全部位置可见，再单独加因果限制。这样，当结果变化时，我们能追到究竟是匹配份额、取回内容，还是可见范围变了。",[20,21,23],"h2",{"id":22},"_1把找什么和取什么分开","1．把“找什么”和“取什么”分开",[10,25,26],{},"想象你在一叠通知中找会议地点。查找条件、用来匹配的标签、取回的内容，承担不同角色。Attention也分出三组向量，通常简称Q、K、V。",[10,28,29,30],{},"Q叫查询，表示当前位置拿什么去匹配；K叫键，表示各位置提供什么供匹配；V叫值，是最后真正被加权组合的内容。它们都是数字向量，不必能翻译成一句清晰的人话。",[31,32,36],"a",{"href":33,"rel":34},"https://arxiv.org/html/1706.03762v7#S3.SS2",[35],"nofollow","Transformer原论文：Attention定义",[10,38,39],{},"在自注意力中，三者来自同一组位置表示，但通过不同参数矩阵得到。若输入矩阵叫X，使用第03章的横排约定，可以写成Q＝XW_Q、K＝XW_K、V＝XW_V。下标只是区分用途，不需要额外数学知识。",[10,41,42],{},"三张W是训练得到的参数；Q、K、V是本次输入经过它们算出的中间结果。输入改变，三组结果可以改变，而参数不必改变。“同一个token这次更关注前文”，并不等于它临时重新训练了。",[10,44,45],{},"这些投影也接得上上一章的训练过程：最终损失的信号沿加权组合、softmax和点积往回传，再到投影参数。通常不需要人给每一个位置标注“应该注意哪个词”，但学到的读取方式是否有用，仍取决于数据和训练目标。每个头的一组参数通常跨位置共用，并非遇到新位置就新建一张权重表。",[10,47,48],{},"查询和键为何不直接共用同一个向量？分开变换，可以让“想找的信息”和“提供的匹配线索”使用不同组合。一个位置读取另一个位置，也不要求反向读取同样强。这和两组向量之间对称的几何相似度，并不是完全一样的问题。",[20,50,52],{"id":51},"_2用三处输入造一个能算完的单头","2．用三处输入造一个能算完的单头",[10,54,55],{},"我们只放三个token位置，每个位置有两个数。这里不把它们强行绑定为真实汉字的向量：位置1为［1，0］，位置2为［0，1］，位置3为［1，1］。叠起来，X就是3行2列。",[10,57,58],{},"所有数字和矩阵都为教学手填，暂时省略位置编码、偏置和其他模块。设c＝√2×ln 2，约为0.9803。ln 2在第04章出现过，指数运算后正好得到2；选择这个数只是为了稍后算出整齐的份额。",[10,60,61],{},"安排三张2×2矩阵：W_Q两行分别是［1，0］和［0，1］；W_K两行是［c，0］和［0，c］；W_V两行是［2，0］和［0，1］。",[10,63,64],{},"逐行乘上去，得到：",[66,67,68,72,75],"ul",{},[69,70,71],"li",{},"Q的三行：［1，0］、［0，1］、［1，1］",[69,73,74],{},"K的三行：［c，0］、［0，c］、［c，c］",[69,76,77],{},"V的三行：［2，0］、［0，1］、［2，1］",[10,79,80],{},"例如位置3的输入［1，1］乘W_V，第一项为1×2＋1×0＝2，第二项为1×0＋1×1＝1，所以v₃＝［2，1］。W_Q碰巧保持原值，也只是本例选择；真实模型的查询投影不必是这样的单位矩阵。",[10,82,83],{},"现在有了三份不同用途的表示。接下来不是把Q、K、V相加，而是先用Q和K决定V各占多少。",[20,85,87],{"id":86},"_3先匹配再把分数变成份额","3．先匹配，再把分数变成份额",[10,89,90],{},"先只看位置3。它拿查询q₃＝［1，1］，分别与三个键做点积。逐项相乘再相加，分数依次是c、c、2c。",[10,92,93,94],{},"标准缩放点积注意力还会除以查询与键的维数的平方根。这里每个有2项，所以除以√2，分数变成［ln 2，ln 2，2 ln 2］。",[31,95,98],{"href":96,"rel":97},"https://docs.pytorch.org/docs/2.7/generated/torch.nn.functional.scaled_dot_product_attention.html",[35],"PyTorch：缩放点积注意力定义",[10,100,101],{},"维度较大时，点积的典型尺度可能随之变大，softmax容易变得过分集中。这个缩放用于控制尺度，不是在证明分数有多可信。它也不是第03章的余弦归一化，没有把每个向量都除以自己的长度。",[10,103,104,105],{},"为什么除以√d，而不是d？作一个有条件的尺度分析：假设Q、K的各个坐标彼此独立、均值为0、方差为1，那么d个乘积相加的方差是d，标准差是√d。d从1增到4、16，典型幅度便从1增到2、4；除以√d，把这种增长抵消。训练后的向量不保证始终满足这些假设，这解释的是缩放的设计动机。",[31,106,109],{"href":107,"rel":108},"https://arxiv.org/html/1706.03762v7#S3.SS2.SSS1",[35],"原论文第3.2.1节与脚注",[10,111,112],{},"再做softmax：指数后得到［2，2，4］，总和是8；分别除以8，得到［1/4，1/4，1/2］。这就是位置3这一次读取的权重。",[10,114,115],{},"这里的分母只汇总当前查询允许读取的那些位置。不是把整张注意力矩阵所有格子一起归一化，也不是按列归一化。每个查询都分别形成总和为1的一行份额。",[10,117,118],{},"这些数和第04章的输出概率有相似的计算形式，却有不同用途。那里分配的是词表候选的下一token概率；这里分配的是读取位置的权重。位置3占一半，不能解释成“它有一半概率是正确答案”。",[20,120,122],{"id":121},"_4按份额组合内容得到新的表示","4．按份额组合内容，得到新的表示",[10,124,125],{},"权重准备好后，拿的是V，不是K。位置3的输出为：",[10,127,128],{},"o₃＝1/4×［2，0］＋1/4×［0，1］＋1/2×［2，1］＝［1.5，0.75］。",[10,130,131],{},"第一项是0.5＋0＋1＝1.5；第二项是0＋0.25＋0.5＝0.75。结果仍是两个数，但已经混合了三个位置提供的信息。",[10,133,134],{},"完整地算另外两行，也能得到：位置1的缩放分数为［ln 2，0，ln 2］，权重为［2/5，1/5，2/5］，输出［1.6，0.6］；位置2的分数为［0，ln 2，ln 2］，权重为［1/5，2/5，2/5］，输出［1.2，0.8］。",[10,136,137],{},"这一步仍有信息压缩：三个值向量合成一个结果，并没有把三个位置的完整原样副本都装进去。在这个没有其他变换的单头里，份额非负、总和为1，每个输出坐标都处在各个值的对应坐标范围内。随后若加上输出投影、残差等运算，就不能把这个范围限制直接套到整个网络。",[10,139,140],{},"所以这一步输入3×2，输出仍是3×2。中间的匹配表却是3×3：每一行对应一个查询，每一列对应一个被读取位置。尺寸没变，不代表信息没变；原来的逐行变换，现在接上了跨位置的读取。",[10,142,143],{},"先看图1上半部分：Q和K在匹配处合流，V沿另一条路到加权求和。图下半部分把位置3的每个权重与对应V对齐，便于核对每一次乘法。",[10,145,146],{},[147,148],"img",{"alt":149,"src":150},"08｜Attention：当前位置怎样读取其他位置：图1","/collections-assets/llm-to-agent-learning/ce0da1eed439571acf20a310f9b0a70e22d197b35437fa390e005cce69b25992.png",[10,152,153],{},"图1｜X分三路得到Q、K、V；Q、K决定读取权重，V提供混合内容。形状分别为3×2、3×3、3×2。数值展开只追踪q₃这一行，暂不加mask，省略位置机制与输出投影。",[10,155,156],{},"做一次上下文改动：保持位置3和全部W不变，只把位置2改成［0，2］。位置2的键变成［0，2c］，值变成［0，2］。位置3的分数于是变成［ln 2，2 ln 2，2 ln 2］，权重成为［1/5，2/5，2/5］，新输出为［1.2，1.2］。",[10,158,159],{},"还有一个值得注意的变化：虽然三张投影矩阵都只做线性变换，整个Attention却不是固定线性混合。权重经过softmax，而且会随着输入改变；换一个上下文，混合规则本身也跟着变。这正是它与“给所有位置永远取相同比例”之间的重要区别。",[10,161,162],{},"当前位置的原始输入没有变化，读到的上下文变了，最终表示就变了。这次同时改变了另一个位置的键和值，不能把全部变化只归因于“权重增加”。这也是分析真实模型时要分开观察的两条路径。",[10,164,165],{},"还可以拆开做受控检查。在计算得到K、V之后，只替换k₂而保留原V，输出是［1.2，0.8］；只替换v₂而保留原权重，输出是［1.5，1.0］。两条路一起改，才是上面的［1.2，1.2］。这两次内部替换是用于分析依赖的人工干预，不是说原始输入变化时K、V会自然独立。",[10,167,168],{},[147,169],{"alt":170,"src":171},"08｜Attention：当前位置怎样读取其他位置：图2","/collections-assets/llm-to-agent-learning/d7e7905b0861d3c4ec2b0660018a9992e04cdc00f4ae426234a77606b03193d2.png",[10,173,174],{},"图2｜固定q₃与全部参数，对照原例、只换K、只换V、两路都换。四种结果共同说明：权重与内容是不同的因果路径，不能只看权重就解释输出改动。",[20,176,178],{"id":177},"_5因果掩码怎样防止偷看答案","5．因果掩码怎样防止偷看答案",[10,180,181],{},"目前我们允许三个位置互相读取。如果要逐个预测后续token，位置2就不能利用尚未出现的位置3。训练时即使整段正确文本已经放在机器里，也要限制这一条信息路径。",[10,183,184,185],{},"因果掩码，也叫causal mask，为每个查询规定可见范围。在本例中，位置1只看1；位置2看1、2；位置3看1、2、3。允许看到自己，是因为这里的表示对应已经给出的当前位置，它可以用来预测下一个位置。",[31,186,189],{"href":187,"rel":188},"https://arxiv.org/html/1706.03762v7#S3.SS2.SSS3",[35],"Transformer原论文：解码器可见范围",[10,191,192],{},"回到未修改输入的例子。位置2原本的分数为［0，ln 2，ln 2］。mask把第三项排除，常在数学上写成负无穷，使其指数值为0。指数后的三个数成为［1，2，0］，重新归一化，权重就是［1/3，2/3，0］。",[10,194,195],{},"它的输出随之变为1/3×［2，0］＋2/3×［0，1］＝［2/3，2/3］。不能先保留原来的［1/5，2/5，2/5］，只把第三项划掉就结束；那样剩下的份额没有重新分配。",[10,197,198],{},[147,199],{"alt":200,"src":201},"08｜Attention：当前位置怎样读取其他位置：图3","/collections-assets/llm-to-agent-learning/60e9f42de0dd6a021d3ec5f5dd0979736f4d7846c05da8d9e06ca3599d90f62f.png",[10,203,204],{},"图3｜行是查询位置，列是被读取位置。因果mask保留对角线与左下部分；位置2先把第三项排除，再对剩余指数值1、2归一化，得到1/3、2/3、0。",[10,206,207],{},"遮住未来，是限制信息从哪来，并不是让训练必须一个位置一个位置串行计算。只要每一层都遵守掩码，就能同时算许多已知训练位置，而不把未来内容泄漏进去。实际生成还没有未来token，依然要逐步得到它们。",[10,209,210],{},"另外，补齐长度用的空白位置也可能需要遮挡，但它与“未来不可见”是不同理由的mask。后面SFT中的损失mask又是另一件事：它决定哪些位置参与评分，不直接代替这里的信息访问限制。",[20,212,214],{"id":213},"_6多头让同一位置有多种读取方式","6．多头让同一位置有多种读取方式",[10,216,217],{},"一个头只给出一组匹配和汇总。假如某项任务同时需要追踪时间、对象和条件，把信息一次混合，未必是最方便的表示。因此可以并行使用多组查询、键、值投影，分别计算注意力，再合并结果，这就是多头注意力。",[10,219,220,221],{},"用一个仅说明尺寸的例子：两个头各为三个位置输出两个数，分别得到3×2的结果；按每个位置拼接，成为3×4；再乘一张4×2的输出矩阵W_O，回到3×2。",[31,222,225],{"href":223,"rel":224},"https://docs.pytorch.org/docs/2.7/generated/torch.nn.MultiheadAttention.html",[35],"PyTorch：多头注意力的拼接与输出投影",[10,227,228],{},"拼接不是投票，也不等于直接平均。输出投影可以继续学习怎样组合不同头的结果。各头可能学出不同的读取模式，但我们不能未经检验就给它们分配“语法头”“常识头”“逻辑头”等固定职责。",[10,230,231],{},"这个例子让两头各有二维，便于追踪。真实设计常在固定总宽度下把通道分配给多个头，因此头数增加不等于把完整模型复制更多份，也不保证能力随头数单调提高。",[10,233,234],{},"自注意力的“自”，说的是Q、K、V来自同一组序列表示。若查询来自正在生成的文本，键和值来自另一组输入表示，就是交叉注意力的一种用法。匹配、归一化、加权组合的核心过程仍然相通。",[20,236,238],{"id":237},"_7从原论文走到qwen3哪些结构保留下来","7．从原论文走到Qwen3，哪些结构保留下来",[10,240,241,242],{},"2017年的Transformer原论文使用8个注意力头，基础模型每头的键和值都是64维。它将多头结果拼接后再投影，已经具备本篇描述的基本计算路径。",[31,243,246],{"href":244,"rel":245},"https://arxiv.org/html/1706.03762v7#S3.SS2.SSS2",[35],"原论文第3.2.2节",[10,248,249,250],{},"Qwen3技术报告则明确说明使用分组查询注意力GQA。以其中Qwen3-0.6B为例，报告列出的查询头数为16，键值头数为8；同组多个查询头共享键和值，而不是每个查询头都配置完全独立的一组K、V。",[31,251,254],{"href":252,"rel":253},"https://arxiv.org/html/2505.09388v1#S2",[35],"Qwen3技术报告第2节",[10,256,257,258],{},"这种共享减少了需要存放和读取的键值表示，是推理效率的一种取舍；它不意味着所有查询头会产生相同权重，因为查询仍可不同。",[31,259,262],{"href":260,"rel":261},"https://arxiv.org/abs/2305.13245",[35],"GQA原论文",[10,264,265],{},"报告还提到QK归一化、旋转位置编码等细节。因此，我们的小算例展示通用机制，并不声称逐项复现Qwen3内部实现，更不能把手填数字当作真实模型的注意力图。",[20,267,269],{"id":268},"_8读得多不代表理由已经被解释清楚","8．读得多，不代表理由已经被解释清楚",[10,271,272],{},"注意力图展示某层某头怎样分配读取份额，但最终输出还受到V的内容、输出投影、其他头、其他层和后续计算影响。即便一个位置权重较大，也不能直接把它称为最终结论的主要原因。",[10,274,275],{},"最简单的反例可以在纸上验证：如果两个位置的V完全相同，那么在两者之间重新分配权重，只要它们的总份额不变，加权结果就不变。注意力图变了，传给后面的内容却可能完全一样。",[10,277,278,279],{},"2019年的《Attention is not Explanation》在所研究任务中发现，明显不同的注意力分配可以产生相同预测。这支持的谨慎结论是：不能只凭权重热图就声称得到了完整因果解释；并不意味着注意力图在任何分析里都没有价值。",[31,280,283],{"href":281,"rel":282},"https://aclanthology.org/N19-1357/",[35],"原始研究",[10,285,286],{},"本篇为手算省略了位置机制，也留下一个限制：没有位置信息和可见性差异时，交换两组键和值的排列，只要它们仍然一一对应，加权总和不会因此改变。这样的读取本身不能充分表达词序。下一章需要补上位置机制，才能区分“谁先发生”“谁修饰谁”等顺序相关关系。",[10,288,289],{},"读取范围大也有代价。若n个位置都与n个位置配对，普通稠密注意力要处理与n²相关的匹配计算；从100个位置扩到200个位置，完整配对格子从一万变成四万。这里比较的是这部分计算规模，不能断言整个模型耗时恰好四倍。",[10,291,292,293,298],{},"FlashAttention这类高效实现可以避免在显存中展开完整注意力矩阵；也有方法限制可见位置，但这些优化有各自条件。",[31,294,297],{"href":295,"rel":296},"https://arxiv.org/html/2205.14135v2#S3",[35],"FlashAttention原论文","长文本能装进去，更不保证关键条件会被正确利用。Attention提供信息通路，训练目标和数据决定模型怎样学会使用它。",[20,300,301],{"id":301},"本章练习",[303,304,305],"h3",{"id":305},"题目",[10,307,308],{},[309,310,311],"strong",{},"问题1｜追踪两条依赖",[10,313,314],{},"固定Q、K，只把v₂从［0，1］改为［0，2］，位置3的权重与输出各怎样变化？哪些量是参数？",[10,316,317],{},[309,318,319],{},"问题2｜先屏蔽，再归一化",[10,321,322],{},"回到原始输入，对位置2加因果mask。写出指数值、归一化权重和输出；说明为何不能只删掉原权重第三项。",[10,324,325],{},[309,326,327],{},"问题3｜权重变了，内容呢",[10,329,330],{},"构造一个权重变化、输出不变的例子。取v₁＝v₂＝［2，1］，将两项权重由［0.2，0.8］改为［0.7，0.3］，算两次输出，并说明注意力图能证明什么、还不能证明什么。",[303,332,333],{"id":333},"思考提示",[10,335,336],{},[309,337,338],{},"提示1｜对应问题1",[10,340,341],{},"先找权重的计算依赖，再找加权和的依赖。W与本次计算结果是两类对象。",[10,343,344],{},[309,345,346],{},"提示2｜对应问题2",[10,348,349],{},"先屏蔽分数，再求指数与分母；检查一行权重合计是否为1。",[10,351,352],{},[309,353,354],{},"提示3｜对应问题3",[10,356,357],{},"分别展开两个加权和，注意共同的值向量可以提出来。",[303,359,360],{"id":360},"参考答案与解析",[10,362,363],{},[309,364,365],{},"答案1｜对应问题1",[10,367,368],{},"权重仍为［1/4，1/4，1/2］，因为Q、K没有变；输出变成1/4×［2，0］＋1/4×［0，2］＋1/2×［2，1］＝［1.5，1.0］。W_Q、W_K、W_V是参数，Q、K、V和权重是本次计算的中间结果。",[10,370,371],{},[309,372,373],{},"答案2｜对应问题2",[10,375,376],{},"屏蔽后的指数值为［1，2，0］，权重为［1/3，2/3，0］，输出为［2/3，2/3］。原权重［1/5，2/5，2/5］删掉第三项后只剩总和3/5，没有把份额在可见位置间重新分配。",[10,378,379],{},[309,380,381],{},"答案3｜对应问题3",[10,383,384],{},"两次输出都是［2，1］，因为权重总和都是1且两项V相同。注意力图能显示这一层这一头的读取份额，却不能单独证明最终答案因哪个词产生；还要看值向量、后续计算以及受控干预。",[20,386,387],{"id":387},"下一章",[10,389,390],{},"读取已经让位置之间交换信息，但一次读取之后，原表示与新信息怎样组合？下一章把Attention接入Transformer，追踪残差、归一化与位置旋转如何共同支持深层计算。",{"title":392,"searchDepth":393,"depth":393,"links":394},"",3,[395,397,398,399,400,401,402,403,404,409],{"id":22,"depth":396,"text":23},2,{"id":51,"depth":396,"text":52},{"id":86,"depth":396,"text":87},{"id":121,"depth":396,"text":122},{"id":177,"depth":396,"text":178},{"id":213,"depth":396,"text":214},{"id":237,"depth":396,"text":238},{"id":268,"depth":396,"text":269},{"id":301,"depth":396,"text":301,"children":405},[406,407,408],{"id":305,"depth":393,"text":305},{"id":333,"depth":393,"text":333},{"id":360,"depth":393,"text":360},{"id":387,"depth":396,"text":387},"从信息表示和学习出发，用可核算的例子与白板图逐步理解大模型、后训练、推理和Agent系统。","md",{},true,"/column/llm-to-agent-learning/08",{"title":5,"description":410},"column/llm-to-agent-learning/08","YBK9WBRvbld31gdl3mWyGMKN6xpvHYp80kjBuNUKwrU",1791935828762]