来源:市场资讯
(来源:图灵人工智能)
只有矩阵乘法,却有「理解」:Transformer 的数学奇迹与边界
![]()
本文约7000字,预计阅读时长:22分钟。
你每天用的 ChatGPT、Claude、Gemini,核心都是同一套架构——Transformer。但绝大多数使用者——包括很多开发者——从没看过其中的那些公式实际在算什么。「注意力机制让每个词关注其他词」「FFN 提取高级特征」——这些描述没有错,但停留在表面,就像说「发动机把汽油变成动力」一样,正确却无用。
这篇文章想做的是另一件事:打开那个发动机盖,从数学内部看 Transformer 在做什么。
不用类比,不绕过公式。我们要跟着数字走完整个流程:一个词是怎么变成向量的,向量是怎么通过矩阵乘法感知上下文的,非线性是如何进入计算的,语义又是怎么在一层一层的运算中积累出来的。每一步都有公式,每一个公式背后都有一个具体的问题需要解决。
Transformer 的每一个操作,都可以写成数学公式。矩阵乘法、内积运算、ReLU 函数——没有一个操作包含「语义」「理解」「知识」这些词。但最终涌现出来的,是某种极像理解的东西。
从这个视角看进去,这件事本身就是一个奇迹——而当你看清了奇迹是怎么发生的,你也会看清它的边界在哪里。
![]()
一、起点:把一个词编码进高维空间
在进入 Transformer 之前,每个词首先要被转换成计算机能处理的形式。模型有一张词表,包含约三万个常见的词和子词单元(token);每个 token 被分配一个唯一的整数 ID——「猫」可能是 2134,「狗」可能是 891,「飞机」可能是 1502。这一步叫做分词(tokenization),是整个流程的入口。
但整数本身毫无语义可言。2134 和 2135 在数学上只差 1,但「猫」和它的词表邻居之间未必有任何语义关联。计算机能做整数运算,但做不了语义运算。解决方案是:给每个 token 一个 维实数向量,用这个向量的 个维度,去尝试编码这个词在各种语义维度上的信息。
这就是 Embedding 矩阵——一张 行(词表大小,约三万)、 列(向量维度,通常取 4096)的矩阵。每一行是一个 token 的向量表示。查表操作极其简单:把 token 的整数 ID 当作行号,取出那一行,就得到了这个词的 4096 维向量。
这 4096 个数字的每一个,最初是随机初始化的。训练之前,这张表是一堆毫无意义的随机浮点数。训练结束后,它涌现出一个关键性质:语义相似的词,向量的「方向」非常接近;语义不相关的词,向量的方向互相远离。
衡量方向远近,用的是内积。两个向量 的内积:
几何含义是:把 投影到 的方向上,再乘以 。夹角 越小, 越接近 1,内积越大;垂直时内积为 0;方向相反时内积为负。换言之,内积的大小直接反映两个向量方向的接近程度,也就是两个词语义的相关程度。这个量将贯穿整个模型,是 Transformer 衡量「相关性」唯一的数学工具。
「猫」和「狗」内积很大,「猫」和「飞机」内积接近 0。没有人设计这个性质——训练时,「猫」和「狗」在语料里出现在极其相似的上下文中,预测任务的压力把它们的向量推向同一方向。语义,从统计压力中自发涌现,第一次,以几何结构的形式出现在了这台机器里。
这里有一个关键的几何事实支撑了这一切:4096 维空间里,可以同时存在指数量级的方向,任意两个方向近似垂直,互不干扰。 一个 4096 维向量,可以同时在「动物性」「宠物属性」「捕食行为」「体型大小」……数千个语义维度上独立携带信息。低维空间里装不下这么多语义,4096 维可以。这也是整篇文章最后要回到的地方:人类语言里的所有概念,正是被压缩进了这个高维空间的几何结构里。
但此刻,每个词的向量是孤立的。「它」的向量只知道自己是个代词,不知道在「猫追老鼠,它逃跑了」里「它」指的是谁。孤立的向量携带词义,但感知不到上下文——接下来需要另一种机制。
![]()
二、让每个数字感知整个序列
注意力机制要解决的问题是:让序列里的每个 token,都能「看」到其他 token 的信息,并根据相关性决定从哪里吸收多少。
关键设计是:每个 token 的向量 通过三个可学习的矩阵,被投影成三个向量:
模型有 个并行的注意力头,每个头在一个独立的 维子空间里计算,——总维度 均分给每个头。 是每个头各自拥有的投影矩阵。
矩阵乘法在做什么? 乘以 ,结果 。从维度上看: 维向量变成了 维向量——这是一次线性变换,把原始向量投影到了一个新的子空间里。「线性」意味着:新向量的每一个维度,都是原始 维向量各分量的加权求和,权重就是 对应列里的数字。 有 列,每列定义了一个「投影方向」;乘法的结果告诉你: 在这 个方向上各有多大的分量。换句话说,矩阵乘法的作用是换一个角度看同一个向量——原来是从 维的原始空间看,现在从 维的新子空间看。
这三个向量分别叫 Query、Key、Value。但这些名字是人类事后贴上去的标签——、、 本质上只是三个不同的向量,它们的「含义」不是被人定义的,而是通过作用呈现的:因为我们规定了「 和 的内积大,代表 token 和 token 匹配」,这个规则让训练压力有了方向——梯度下降把 和 调整到这样一个状态:语义相关的 token,它们经过投影后的 和 内积就是更大;语义无关的就是更小。「Query 代表我需要什么信息」——这个含义,是在内积大=匹配这个规则下,被训练压力强迫出来的几何性质,不是任何人写进去的。
相关性的计算是内积:
分母 是一个必要的缩放:在高维空间里,向量内积随维度增大而系统性偏大,不做缩放会导致 Softmax 退化为近似的 argmax,梯度几乎消失,模型无法学习。
Softmax 把原始分数归一化为概率权重:
为什么要用这个公式?直接把分数除以总和也能归一化,为什么要先取指数 ?原因有两层:第一, 恒正,保证权重不会出现负数;第二,也是更重要的, 是严格凸函数,它放大分数之间的差距——两个分数原本差 1,取指数后可能差 2.7 倍;差 2,则差 7.4 倍。这意味着:分数最高的 token 获得的权重,会远远大于分数低的 token,注意力因此更集中、更明确,而不是均匀地分散在整个序列上。
加权聚合:向量在这一步真正发生了移动。
为什么要乘以 ,而不是直接用 ?因为 是这个 token 的全部信息混合在一起,既包含词汇意义,也包含语法角色、位置信息……如果直接用 ,「它」不加区分地把「老鼠」的所有信息都吸进来,包括很多和「指代」无关的东西。 的作用是:在 维子空间里,把 里「当我被引用时真正有用的信息」提取出来,其余的压制掉。 是一个 维向量,代表「token 在被引用时提供的内容」。
加权求和的几何含义是: 是词表里所有 token 的 向量的加权平均,权重就是注意力权重 。权重越大,那个 token 的 向量在结果里贡献越多。对「它」而言,「老鼠」的权重最高,所以 的方向主要受「老鼠」的 老鼠 牵引,向「老鼠」相关的语义方向漂移。这个操作把「它」从一个孤立的代词,变成了一个携带了「指代老鼠」这个语境信息的向量。此时 ——还在 维的子空间里。
然而,单头注意力只能在一个 维子空间里捕捉一种统计模式,「指代关系」和「句法关系」在同一个子空间里会相互竞争。多头注意力的解决方案是并行运行 个独立的注意力头,每个头有自己的 ,在各自的子空间里各自计算,各自输出一个 维向量。 个头的输出拼接在一起,得到一个 维向量,再通过输出投影矩阵 混合:
是另一次矩阵乘法:把 维的拼接向量投影回 维输出空间。它的作用是让混合「有道理」——拼接后的向量只是把各头的结果首尾相接,各头的信息仍然孤立地分布在不同区段。 是一个全连接线性变换,结果的每一个维度,都是拼接向量所有 个分量的加权组合,因此每个输出维度同时受到所有头的信息影响。 的权重由训练决定,梯度下降把它调整到一个让各头信息「有效整合」的状态——什么叫有效?就是整合后的向量,对最终预测下一个 token 的损失最小。没有别的标准。各头的分工(偏向相邻词、偏向远距离依赖……)不是人工设计的,是初始化的随机性加上梯度竞争推动的自发分化。
至此,每个 token 的向量已经充分感知了上下文。但注意力机制本质上是线性操作——加权求和无论多复杂,仍然是线性变换。而语言中几乎所有有意义的语义映射都是非线性的,这带来了一个根本性的限制。
三、引入非线性:让数学表达复杂的语义
线性变换有一个铁律:无论叠多少层,多个线性变换的复合始终等价于单层线性变换——,三层和一层没有本质区别。模型永远无法用纯线性操作表达弯曲的决策边界。
为此,每层注意力之后紧接一个前馈网络(FFN):
FFN 对序列中每个 token 的向量独立计算,没有 token 之间的交互——注意力层负责「信息的横向流动」,FFN 负责「每个 token 自身的纵向加工」。
升维: 把 维向量扩展到 维。 有 行,每行是一个 维方向向量,与输入做内积相当于在问:「这个向量在我这个方向上有多大分量?」 个方向同时审视当前 token。
ReLU 激活:,把负值归零。非线性从这里诞生:不同的输入向量,在 的各方向上投影值不同,被激活的神经元子集不同,走过的计算路径完全不同。输入「巴黎是___的首都」和输入「猫追老鼠」,会激活完全不同的神经元组合。
降维: 把稀疏的高维激活向量压缩回 维。这一步的作用是:把「哪些神经元被激活了」这个高维的开关模式,转化成一个具体的 维向量方向,加回到原始向量上,让这个 token 的向量朝一个新的方向移动。
神经元激活的意义就在这里:每一个被激活的神经元,对应 里的一列,这一列是一个 维向量,代表「当这种模式被触发时,应该向输出中注入什么方向的信息」。输入「巴黎」,某些神经元被激活, 里对应的列加权叠加,最终把「法国、首都、欧洲……」这些语义方向推入了当前向量。这不是被人写进去的知识,而是训练时,模型为了预测准确,被迫把这种对应关系编码进了权重里。
因此,经过一层 MHA + 一层 FFN 后,每个 token 的向量都发生了两件事:MHA 让它吸收了序列里其他 token 的信息(横向流动),FFN 根据当前向量的内容,把相关的语义知识注入进来(纵向加工)。这个向量不再只是「这个词本身」,而是「这个词,在当前上下文里,加上了与之相关的知识」。
一次注意力(跨 token 信息交换)加一次 FFN(非线性加工),构成了一个完整的 Transformer Block。但一层远远不够——信息的积累需要深度。
四、堆叠:让理解逐层加深
一个完整的 Transformer Block 结构如下:
输入 X ∈ R^{T × d}↓ 多头注意力(token 间信息交换)↓ 残差:X' = X + MHA(X)↓ LayerNorm↓ FFN(每个 token 独立非线性加工)↓ 残差:X'' = X' + FFN(X')↓ LayerNorm输出 X'' ∈ R^{T × d}(形状不变)其中两个保障训练稳定性的设计不可缺少。残差连接子模块:在 96 层深的网络里,梯度从输出层反向传播时每经过一层就衰减,96 层后几乎为零,前几层根本无法学习。残差提供了绕过子模块的直通路径,让梯度能直接传回,同时每层只需学「增量」而非「完整变换」。LayerNorm 将每个 token 的向量归一化到均值为 0、方差为 1,防止多层变换后数值失控。
这个 Block 重复 层(GPT-3 中 ),参数不共享。
为什么需要这么多层?因为语义的识别本质上是分阶段的,浅层看不到深层的结构。
以「猫追老鼠,它逃跑了」为例,逐层跟踪「它」这个 token 的向量发生了什么:
第 0 层(原始 Embedding): 「它」的向量只编码了「这是一个代词」这个词汇级别的信息。此时它不知道自己指向谁,「老鼠」的向量也只是「老鼠这个词本身」,没有任何「被追、受威胁」的语境信息。
第 1 层(MHA): 「它」的注意力扫描整个序列,但这时每个词的向量还很「原始」,能感知到的主要是词性、相邻位置这类表层信息。「它」开始和「猫」「老鼠」建立一些关联,但还很模糊——代词指代关系需要理解「谁在追谁」,而这需要先理解「追」这个动词的方向性,第 1 层还没有足够的信息做到这一点。
第 1 层(FFN): 「老鼠」的向量激活了 FFN 里与「被捕食动物、逃跑行为」相关的神经元,这些神经元对应的 列把「容易逃跑的、受威胁的」方向注入了「老鼠」的向量。「老鼠」变成了「老鼠+在被追的语境里」。
第 2 层(MHA): 「它」现在处理的不再是原始 Embedding,而是第 1 层输出的向量。此时「老鼠」的向量已经携带了「受威胁、逃跑方向」的语义,「它」的 Query 向量与「老鼠」的 Key 向量内积变得更大——「它」更强烈地被「老鼠」吸引,开始把「老鼠」的 Value 信息大量混入自己的向量。
更深层: 每一层都在上一层输出的基础上工作。语义信息从局部流向全局,从表层词义积累到深层语境理解。到了第 96 层,「它」的向量已经不是「一个代词」,而是「在猫追老鼠这个情境里,指向老鼠的那个它」——这个含义,是 96 层矩阵乘法和 ReLU 逐步积累出来的,每一层都是前一层的基础。
第 0 层:token 向量 ≈ 这个词本身的词汇信息第 1 层:token 向量 ≈ 词汇信息 + 局部相邻词的初步关联第 2 层:token 向量 ≈ 上层输出 + 更丰富的语境信息第 96 层:token 向量 ≈ 这个词在这个具体语境下的完整含义注意这个过程的关键:每一层 MHA 能看到的「其他 token」,已经是上一层加工过的向量,而不是原始的词向量。信息不是一步传过去的,而是在反复的交互和加工中,一层一层积累进来的。
96 层之后,序列最后一个位置的 维向量,把整个输入序列的全部语义压缩在内。接下来,模型要用它做一件事:预测下一个词。
![]()
五、从向量到预测:为什么是内积
96 层处理结束后,序列最后一个位置的 维向量 携带了整个输入序列的语义——它代表的是「在这段上下文之后,下一个词应该是什么方向的信息」。
现在要做的,是把这个语义向量和词表里每一个词比较,找出「在这个语境下最可能出现的词」。怎么比较?还是内积。
回想第一节:Embedding 训练结束后,每个词在 维空间里有一个方向,语义相近的词方向接近。 经过 96 层加工,也在这个空间里有了一个方向——这个方向代表「当前上下文预期的下一词的语义」。把它和词表里每个词的向量做内积:
内积越大,说明 的方向和词 的方向越接近,也就是说这个词越符合当前上下文的语义期望。(logits)就是词表里每个词的「符合程度原始分数」。Softmax 把这组分数转成概率分布:
采样或取最高概率,得到下一个 token。把它拼回输入,再做一次完整的 96 层前向传播,预测下一个……
模型只会一件事:对当前序列,输出下一个 token 的概率分布。所有的「对话」「推理」「写作」,都是这一件事循环几百次的结果。
但在这套计算流程能产生有意义的预测之前,还有一件更根本的事情需要发生——所有参数最初是随机数字,它们是如何被调整到今天这个状态的?
六、训练:统计压力如何塑造一切
所有参数————最开始都是随机数字。GPT-3 有 1750 亿个这样的随机浮点数。训练的任务,是用大量文本数据,把这些随机数字调整到一个特定的状态,使得模型能准确预测文本中的下一个 token。
训练数据是自动构造的,无需任何人工标注——原始文本通过滑动窗口,自动产生「输入→下一个词」的训练对。一条长度 的序列产生 个训练样本,标签来自文本本身。LLaMA-3 的训练语料约 15 万亿 token。
损失函数量化每次预测有多准:
正确答案概率为 1 时损失为 0;概率越低, 越大。梯度下降对每个参数计算偏导数,然后朝让损失减小的方向走一小步:
反向传播从损失出发,沿计算图反向,用链式法则逐层推导,一次完成所有参数的梯度计算。Adam 优化器在此基础上维护每个参数的梯度历史均值 和方差 ,自适应地为每个参数调整步长。整个过程重复 次迭代。
没有人告诉模型任何一条知识。「猫和狗是同类」「巴黎是法国首都」「它指代老鼠」——全是从「预测下一个词」的压力中,在数十亿次微小的参数调整里,被迫学到的副产品。
现在,这台机器的每一个数学步骤都已经清楚了。但一个更根本的问题随之浮现:这些浮点数,究竟是怎么携带「含义」的?
七、含义究竟是什么:一个出乎意料的答案
把每个步骤都理解了之后,有一个问题反而变得更加尖锐:矩阵乘法、内积、ReLU——这些操作,是如何承载「老鼠」「指代」「因果」这些概念的?
答案出乎意料:含义是高维空间里的几何位置,没有比这更深的东西了。
不存在任何叫做「理解」的模块。不存在任何神经元「存储了老鼠」这个概念。所谓「它指代老鼠」,是一个纯粹的几何事实:经过 96 层处理后,「它」的向量在 4096 维空间里,漂移到了和「老鼠」相关向量距离很近的位置。这个位置关系,是统计压力在高维空间里涌现出来的结构,不是符号存储,不是人工编码。
第一节已经展示过,高维空间拥有容纳指数量级近似垂直方向的能力。现在我们可以把这个数学事实推到它的逻辑终点:如果一个 4096 维向量可以同时在数千个语义维度上独立携带信息,那么 96 层矩阵乘法的作用,就是在这个空间里为每个 token 找到一个精确的位置——这个位置同时编码了词义、语法角色、上下文关系、主题归属……所有这些信息,以近似正交的方向叠加在同一个向量里,互不干扰。
所谓「理解」,是找到了正确的几何位置。所谓「知识」,是向量之间的方向关系。所谓「语义」,是高维空间里被统计压力塑造出来的几何结构。
这台机器掌握的不是世界本身,而是人类描述世界的语言的几何结构。 它没有被告知任何知识,却在数学的压力下,把人类几千年来书写进语言的一切,都编码成了高维空间里的方向与距离。这个区分至关重要——它意味着模型的边界,恰好是人类语言的边界。
![]()
尾声:奇迹与边界
跟着数字走完这段旅程:从整数 2134,到 4096 维向量,到注意力权重,到 96 层的非线性变换,到最终的概率分布——这一路上,发生的只是矩阵乘法、内积和 ReLU。涌现出来的,是某种看起来极像理解的东西。
这是奇迹。但奇迹有边界。
这台机器学到的,是人类语言中的统计结构——哪些词倾向于出现在哪些词之后。当语言忠实地反映了世界的结构时,模型看起来「理解」了世界;但当语言和现实之间出现裂缝时,模型会毫不犹豫地选择语言那一侧。它会自信地编造一个不存在的论文引用,因为「在这个上下文中,一个格式正确的引用」在高维空间里的几何位置,比「承认我不知道」更接近训练数据的统计模式。幻觉不是 bug,而是这套数学的必然推论。
理解了这一点,你就拥有了一个判断框架:凡是能被语言的统计结构捕捉的任务,LLM 都会越来越强;凡是需要超越语言、触及世界本身的任务,LLM 的天花板写在了它的数学原理里。
这不是悲观。这是工程师看清了自己手中工具的能力边界后,才可能做出的最好的决策。
附录:数字全程追踪
以下用一个极简例子(词表 3 个词,向量维度 ),把正文中每个步骤的数学计算完整展示。所有数字均为示意,不代表真实模型参数。
A1. Embedding 查表
(行依次对应:猫、狗、飞机)
输入「猫」(ID=0),取第 0 行:猫
A2. 内积:衡量语义相似度
猫狗
猫飞机
猫-狗内积 3.38(方向接近),猫-飞机内积 -1.86(方向相反)。内积的符号和大小,直接反映了语义距离。
A3. Q/K 投影与注意力分数
设 :
「它」它,计算 它它
「老鼠」老鼠,计算 老鼠老鼠
注意力分数:
它老鼠
A4. Softmax 与加权聚合
五个 token 的注意力分数:,对应「猫、追、老鼠、它、逃跑」。
指数值:,总和
注意力权重:
「老鼠」权重最高(0.236),「它」的输出向量将主要混入「老鼠」的 向量信息。
A5. FFN 神经元激活示例
设 ,,注意力层输出后的向量 :
神经元 3 被关闭。不同输入向量激活不同的神经元子集,这就是 FFN 产生非线性区分能力的机制。
A6. Logits 与最终预测
最终向量 ,与词表内积得 logits:
猫狗飞机
Softmax 后:猫,狗,飞机
语义接近的词获得了接近的概率,语义不相关的词概率趋近于零——内积在这里再一次发挥了作用。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.