← 进阶 vibe coding注意力让模型结合相关内容

免费文章 · 02 理解模型怎样生成回答

注意力让模型结合相关内容


  上一节,我们已经知道模型会根据前文,一步步预测下一枚 token。但前文可能包含很长的资料、多个角色和许多要求,模型究竟怎样从中找到当前需要的信息?为什么有时能准确联系前面的内容,有时却会遗漏或误用其中的条件?

  这就涉及注意力(attention)机制。它通过计算不同位置之间的匹配程度,分配相应的权重,再将这些信息结合起来,参与后续计算。

  比如“小林把文件发给小周,随后他关闭了电脑”,模型要理解“他”,就需要联系前面的人物和动作。不过,这句话本身存在指代歧义,即使有了注意力机制,也不意味着模型一定能判断出“他”是谁。

  这一节,我们就通过简单的例子,看看注意力怎样匹配和汇总信息,以及它能帮助模型做到什么,又有哪些局限。

同一个位置,为什么需要 Q、K、V?

  前面提到,模型理解“他”时,需要联系前面的人物和动作。但面对这么多位置,模型怎样判断哪些信息值得关注,又该怎样把这些信息结合起来?

  为了解决这个问题,常见的 Transformer 自注意力层会把每个位置的向量分别转换成三种表示:Query(Q)、Key(K)和 Value(V)。我们可以先简单理解为:Q 用来寻找相关信息,K 用来参与匹配,V 则提供真正需要汇总的内容。

向量

在计算中做什么

当前查询 q

与其他可读位置的 k 比较,计算匹配得分

各位置的 k

参与匹配,帮助确定对应位置的注意力权重

各位置的 v

按照计算出的权重参与汇总,提供实际传递的信息

  这里的“查询”并不是我们向 AI 提出的问题,而是模型内部的一种计算。每个位置都有自己的 q,可以分别与其他可读位置的 k 进行匹配,再根据权重汇总对应的 v。整个过程都在向量之间完成,并不是真的把它们变成文字来提问和回答。

  那么,Q、K、V 是从哪里来的?它们其实都来自各位置的输入向量,只是经过了不同的变换,这个过程称为投影。模型会在训练中学到三组投影参数,平时推理则直接使用这些参数进行计算。

  因此,当我们修改前文时,输入向量发生变化,计算出来的 Q、K、V 也可能随之改变。但这只是输入变化带来的结果,并不意味着模型的投影参数被重新训练。

用三个位置,走完一次匹配与汇总

  前面已经知道 Q、K、V 各自的作用,接下来我们用一个简单的例子,看看它们究竟怎样参与计算。

  假设当前查询是 q = (1, 0),它需要从 A、B、C 三个位置获取信息。我们为每个位置设置一组 k 和 v,每个向量只有两个数,方便观察计算过程。这些数字都是人为设定的,不代表真实模型的输出,也没有特定的语义。

位置

k

v

A

(2, 0)

(1, 0)

B

(0, 2)

(0, 1)

C

(−2, 0)

(1, 1)

  首先,用 q 分别与三个位置的 k 计算点积:把对应位置的数字相乘,再将结果相加。

  A 的得分是 1×2 + 0×0 = 2,B 是 0,C 是 −2。这样,我们就得到了三个匹配得分 (2, 0, −2)。

  不过,得分还不是注意力权重。它们只是反映当前查询与各位置的匹配程度,接下来还需要进一步计算,才能决定从每个位置汇总多少信息。

  首先是缩放。本例采用缩放点积注意力,需要把每个得分除以 √d_k。其中 d_k 表示 q 和 k 的维数,这里是 2,因此缩放后的得分约为 (1.414, 0, −1.414)。这样做是为了避免维数较高时,点积数值过大,导致后面的 softmax 结果过于集中。

  接下来是 softmax。和上一节一样,先对得分取指数,再除以所有指数的总和,得到约 (0.768, 0.187, 0.045)。这三个权重都不小于 0,加起来等于 1。也就是说,在这次计算中,A 获得了最大的注意力权重,C 则最小。

  这里需要区分两种 softmax 的用途:上一节是在候选 token 之间分配生成概率,而这里是在不同位置之间分配注意力权重。因此,A 的权重约为 76.79%,只表示它在这次信息汇总中的相对比重,并不意味着“A 有 76.79% 的概率正确”,也不代表下一枚 token 就是 A。

  有了注意力权重,接下来就可以真正汇总信息了。这一步使用的是各位置的 V:先把每个 V 乘以对应的权重,再将结果按维度相加。

  在刚才的例子中,计算过程是:

plaintext
输出 ≈ 0.768 × (1, 0)
     + 0.187 × (0, 1)
     + 0.045 × (1, 1)
     ≈ (0.813, 0.232)

  可以看到,虽然 A 的权重最大,但最终结果并不是直接复制 A 的向量,B 和 C 也贡献了信息。注意力权重决定每个位置贡献多少,V 则决定它们提供什么信息。

这里的数值经过四舍五入,实际实验仍使用未舍入的数值计算。

  不过,这一步得到的仍然是一个向量,而不是下一枚 token。它还需要经过模型后续的计算,最终才会在输出端产生各个候选 token 的得分。也就是说,注意力负责结合前文的信息,但最终生成什么,还取决于后续的计算。

把所有查询排成矩阵

  刚才一次只观察一个 q。把各位置的输入表示排成矩阵 X,每一行对应一个位置,三组投影可以写成:

plaintext
Q = XW_Q
K = XW_K
V = XW_V

  三组 W 是模型参数;Q、K、V 是本次输入经过投影后的结果。注意力权重也是本次计算得到的数值,不是这些投影参数的另一个名字。

  把各位置的查询一起计算,就是:

plaintext
Attention(Q, K, V) = softmax(QKᵀ / √d_k)V

  QKᵀ 的每一行是一个查询对各位置的得分;softmax 对每行分别归一化。不同查询各有一组权重,不能把整个矩阵的数值混在一起归一化。乘以 V 后,每行得到一个汇总向量。

  在生成式模型的因果自注意力中,一个位置只能读取当前位置及此前位置,后面的不可读位置会被遮住。本例的 A、B、C 都设为可读位置,没有演示遮罩;下一节把这个限制放进完整 Transformer 结构。

改查询与改内容,会影响不同环节

  接下来,我们通过两个小实验,看看改变不同的向量会带来什么影响。

  先保持 K、V 不变,把 q 从 (1, 0) 改成 (0, 1)。这时,它与 A、B、C 的点积分别变成 (0, 2, 0),B 的匹配得分最高。经过缩放和 softmax,权重变为约 (0.164, 0.673, 0.164),最终汇总向量约为 (0.327, 0.836)。可以看到,即使可读取的内容没变,查询不同,注意力的分配也会不同。

  再把 q 恢复成 (1, 0),只将 C 的 v 从 (1, 1) 改成 (3, 1)。这一次,注意力权重会变化吗?不会。因为权重由 q 和 K 计算,而它们都没有改变。

  不过,C 实际提供的内容变了。它在第一维的贡献从约 0.045 × 1 增加到 0.045 × 3,使最终汇总向量从 (0.813, 0.232) 变成约 (0.904, 0.232)。虽然 C 的权重很小,改变它的 V 仍然会影响结果。

  这也让我们进一步看清:Q、K 决定从哪些位置取得多少信息,V 则决定这些位置实际提供什么内容。

  为了看清其中的区别,我们在实验中一次只改变一个变量。但在真实模型中,修改前文可能同时影响多个位置的表示,后续计算也会随之变化。因此,实验中的“只改 V”只是人为设置的对照,并不意味着我们可以通过提示词精确控制模型内部的某个向量。

运行注意力实验

沿用已准备的课程实验仓库,打开注意力实验。

  1. 保持基准条件,再点击“切换为 Q = (0, 1)”,观察得分、权重与输出。
  2. 切回(1,0),勾选“只把 C 的 V 改为 (3,1)”,检查权重与第一维贡献。
  3. 取消勾选恢复基准,展开“查看逐项计算”,核对每一行。

本地计算使用人工Q、K、V,说明数值怎样汇总,不据此判断模型怎样理解自然语言。

多头注意力,让多组信息共同参与计算

  刚才,我们用一组 Q、K、V 完成了匹配和汇总,这可以看作一个注意力头。但同一段前文中,值得关注的关系可能不止一种。如果只使用一组权重,这些信息就需要通过同一次汇总来结合。

  于是,多头注意力(Multi-Head Attention)让同一份输入经过多组不同的投影,分别生成 Q、K、V。每个头独立计算匹配得分、分配权重并汇总信息,再把各头的结果拼接起来,经过一次可学习的输出投影,形成供后续计算使用的表示。

  这样,不同的注意力头就有机会从不同角度利用信息之间的关系。不过,它们并没有预先规定的分工,比如“一个负责指代,另一个负责语法”。具体学到了什么,要看模型的训练结果。多个头也不是几个独立的 AI 在讨论,而是同一个模型内部并行进行的计算。

一张注意力图,不能代替答案依据

  了解多头注意力后,我们可能还会好奇:能不能通过注意力图,看出模型为什么这样回答?

  注意力图通常展示某一层、某个注意力头对不同位置分配的权重,颜色越深,代表该位置的权重越大。但它只展示了计算的一部分,没有包含对应的 V、其他注意力头和后续网络的计算。刚才“只改 V”的实验就说明:即使注意力权重完全相同,最终汇总的信息也可能不同。 因此,不能仅凭某个词的颜色更深,就断定模型是因为它才答错的。

  而且,模型能够利用某段资料,并不代表资料本身就是正确的。比如我们提供了一份旧版软件的操作说明,模型可能根据它生成回答,但这些操作未必还适用于当前版本。要判断回答是否可靠,我们仍然需要核对资料的适用条件和实际结果。

  回到开头的例子:“小林把文件发给小周,随后他关闭了电脑。”注意力可以帮助模型联系前面的人物和动作,却不能凭空消除原句的歧义。我们可以进一步明确“他”究竟指谁,再检查模型是否正确理解。

  这也提醒我们,提供资料只是第一步。信息是否明确、有没有相互矛盾、是否适用于当前任务,同样会影响最终回答。至于怎样组织信息、怎样让模型更好地利用上下文,我们会在后面的课程中结合实际任务继续深入。

权重相同,能证明结果相同吗?

  先回到刚才的实验。将 q = (1, 0),保持 K 不变,准备把 C 的 v 从 (1, 1) 改成 (3, 1)。

  在修改之前,先想一想:匹配得分和注意力权重会改变吗?最终汇总的向量又会怎样变化? 然后实际操作,对比两次结果,看看自己的判断是否正确。

  接下来,考虑一个小说创作任务。我们已经明确告诉 AI“主角不会游泳”,但提供的旧草稿里仍写着主角独自游过河。假设注意力图显示,某个注意力头对旧草稿中的内容分配了较高权重。

  这是否意味着旧草稿更值得相信,或者之前确认的人物设定已经失效?我们应该怎样判断 AI 后续写出的故事是否符合要求?

查看答案与解析

  第一个实验中,由于 q 和 K 都没有改变,匹配得分和注意力权重保持不变。但 C 的 V 发生了变化,使汇总向量的第一维增加约 0.0908,从 (0.813, 0.232) 变成约 (0.904, 0.232),第二维则没有变化。

  这说明,即使注意力权重完全相同,最终汇总的信息也可能不同。 只看权重图,还不足以判断模型实际得到了什么信息。

  小说创作也是类似的道理。旧草稿获得较高的注意力权重,只能说明模型在这一处计算中给相关位置分配了较大权重,并不代表它比已确认的设定更可靠。

  真正需要检查的是续写的内容:主角有没有违背“不会游泳”的设定?原本矛盾的过河情节是否得到了合理处理?注意力图可以帮助我们观察计算过程,但不能代替对实际结果的判断。

  注回到模型内部,注意力只是整个计算过程的一部分。模型还需要区分 token 的先后顺序,并进一步处理注意力汇总的信息。下一节,我们就把位置信息、前馈层和残差连接结合起来,看看它们怎样与注意力配合,共同组成 Transformer 的基本结构。

讨论

登录后参与讨论