引言
想象一下,你在 AI 助手中输入这样一句话:“我把冰淇淋放在太阳下。几分钟后,它……”
你很可能会想到“融化了”。语言模型也可能给出类似的续写。但它从未尝过冰淇淋,也没有感受过阳光,究竟如何把你输入的文字变成一个合适的回答?
在模型内部,文字首先变成数字。这些数字经过一层又一层的数学运算,最终产生词表中各个候选 Token 的分数。系统选择一个 Token,再重复这个过程,逐步生成完整的回答。
Token、向量、矩阵、注意力和张量,描述的就是这个过程中的不同部分。只要跟随一句话走进模型内部,这些术语就不再那么抽象。
本文主要介绍许多文本生成大语言模型采用的解码器式 Transformer 架构。人工智能还有其他架构,但理解这条基本流程,能够帮助我们认识现代对话式 AI 的工作原理。
第一章:Token——把文字拆成可以处理的单元
第一步是分词,也就是 Tokenization:将文本转换成一系列称为 Token 的处理单元。
一个 Token 不一定等于一个完整的单词。 根据分词器的规则,它可能代表一个单词、单词的一部分、标点,或者包含空格的一段文本。不同模型使用的分词器,也可能对同一句话给出不同的拆分结果。
为了便于说明,我们继续使用英文句子:
“I left my ice cream in the sun.”
可以将它示意性地拆成:
“I” / “left” / “my” / “ice” / “cream” / “in” / “the” / “sun” / “.”
这里展示的是教学示例,并不是某个特定分词器经过验证的实际输出。真实的 Token 边界可能不同。子词分词方式允许模型使用词表中已有的较小单元,表示许多不常见或未作为完整词条收录的单词。
每个 Token 在分词器的词表中都有一个整数编号。例如,假设“ice”的编号是 412,“cream”的编号是 908。这些编号同样只是示例。
可以把 Token 编号理解为目录中的索引。编号较大,不代表这个 Token 更重要;两个编号接近,也不代表它们表达的概念相似。
分词让模型能够用一致的方式识别文本单元。接下来,模型还需要把这些编号转换成更适合学习和计算的数值表示。
第二章:嵌入——把 Token 编号转换成向量
模型会根据每个 Token 的编号,查找一组通过训练得到的数字。这组数字称为嵌入向量,也就是 Embedding Vector。
一个非常简化的向量可以写成:
[0.24, −0.61, 0.83, 0.09]
真实模型通常会为每个 Token 使用更多数值。这些数值共同构成一种可以由神经网络处理的表示。
我们很容易想象,每个数值都有一个明确的标签:某一维表示“冷”,另一维表示“食物”,还有一维表示“甜”。这种比喻可以帮助入门,但真实的嵌入通常并不是按照这些清晰的人类标签组织的。
实际上,有用的信息往往分布在许多维度之中。训练会调整这些数值,因为某些数值组合能够帮助模型更好地完成预测任务。
还需要区分初始嵌入与上下文表示。单纯的嵌入查找,并没有完成对整个句子的解释。同一个 Token 出现在甜点、制冷或者比喻表达中时,通常会从相同的初始嵌入开始。
随着它经过模型的不同层,其表示会结合当前上下文发生变化。
因此,初始嵌入提供的是一个学习得到的起点;后续各层逐步形成与当前语境有关的表示。
第三章:矩阵——把一系列向量组织起来
一句话包含多个 Token,每个 Token 都对应一个向量。把这些向量按行排列,就形成了一个矩阵。
假设一个简化输入包含 12 个 Token,每个 Token 用 8 个数字表示,那么它的输入表示就是一个 12 行、8 列的矩阵。
每一行对应一个 Token 位置,每一列对应表示向量中的一个分量。
这种组织方式便于模型高效处理大量数值。模型可以对整组数据进行矩阵运算,而不必把每个数值都当成彼此独立的对象来处理。
这里还要区分两个容易混淆的概念:嵌入表与输入嵌入矩阵。
模型的嵌入表包含整个词表中各个 Token 的嵌入向量。输入嵌入矩阵则是根据当前输入序列,从嵌入表中选取相应向量,并按照输入顺序排列得到的结果。
前者是完整的查找表,后者是当前这段输入对应的数值表示。
第四章:位置——为什么词序很重要
比较下面两个句子:
“狗追赶猫。”
“猫追赶狗。”
它们使用了相同的词语,却描述了不同的事件。只有词语身份,还不足以表达这种差别。
因此,Transformer 需要引入位置信息。有些设计会把与位置有关的向量加入 Token 嵌入。许多较新的模型则采用旋转位置嵌入,也就是 RoPE,对注意力计算中的查询和键表示进行与位置有关的旋转变换,使位置关系影响计算结果。
理解它的作用,并不要求先掌握旋转变换的数学公式。关键在于:模型需要知道信息出现在什么位置,以及不同位置之间有什么关系。
在冰淇淋的例子中,“放在太阳下”发生在“几分钟后”的事件之前。这样的顺序有助于模型形成符合语境的续写。
第五章:注意力——连接上下文中的信息
为了合理地续写冰淇淋的例子,模型需要结合输入中的多个部分。“冰淇淋”指出对象,“太阳下”提示受热环境,“几分钟后”则说明时间已经过去。
自注意力机制,也就是 Self-Attention,允许不同 Token 位置的表示结合彼此的信息。
典型的注意力机制会从当前表示中,通过学习得到的投影产生三组表示:查询 Query、键 Key 和值 Value,通常简称为 Q、K、V。
查询与可用的键进行比较,产生相关分数。这些分数经过归一化后形成注意力权重,再由这些权重决定如何对值向量进行加权组合。
这些名称描述的是数学角色,并不表示模型在有意识地提问或阅读标签。
多头注意力让一个层能够并行形成多种不同的信息组合,从不同的学习结果出发处理上下文。
对于用于逐步生成文本的因果语言模型,一个位置可以关注自身及此前的位置,但未来位置会被遮挡。模型不能提前查看尚未生成的答案。
在教学图中,我们可能从提示词末尾画出连线,指向“冰淇淋”和“太阳下”。这样的连线只是解释概念,并不代表某个真实模型的注意力测量结果。实际的注意力模式会随着模型、输入、层和注意力头而变化。
第六章:权重与矩阵乘法——变换信息的表示
注意力计算本身就使用学习得到的权重。它并不是先完成注意力处理,然后模型才开始使用权重矩阵。
在神经网络中,矩阵乘法会不断把一种表示转换成另一种表示。每个输出分量都可以通过学习得到的数值系数,组合多个输入分量。
下面看一个简单例子。假设输入向量是:
[2, 3]
其中一个输出分量可以这样计算:
2 × 0.5 + 3 × 0.2 = 1.6
另一个输出分量可以这样计算:
2 × (−1) + 3 × 1 = 1
于是,得到的新向量就是:
[1.6, 1]
这个例子只用于展示乘加运算,并不代表真实语言模型中的参数。
真实网络处理的向量和矩阵通常大得多。Transformer 模块会组合注意力、前馈网络、非线性函数、归一化和残差连接等机制。
非线性函数尤其重要。 如果只是反复进行线性变换,多次变换仍然可以合并成一次线性变换。非线性运算让网络能够表达更加复杂的关系。
残差连接则让信息能够沿着旁路传递,并与变换后的结果相加,有助于深层网络中的信息与梯度传播。
随着表示经过一个又一个模块,模型会反复组合和变换信息,而不是让一个始终不变的词向量穿过一层层数字滤镜。
第七章:训练——有用的权重从哪里来
这些计算之所以有用,是因为其中的参数经过了学习。
语言模型预训练中的一个常见目标,是根据前面的 Token 预测下一个 Token。模型输出概率分布,损失函数则衡量这个分布为训练文本中的实际目标 Token 分配了多大的概率。
反向传播负责计算梯度,优化器根据梯度调整参数。参数更新通常综合一个批次中许多训练位置的信息,而不是每出现一个错误单词,就由人手动纠正一次。
经过大量更新,模型逐渐学习到有助于预测的模式,包括语法、事实关联、编程语言,以及事件之间的关系。
但一个 AI 助手还需要学会响应指令,而不只是继续写下一段文字。后训练,也就是 Post-training,可以通过示范、偏好反馈或基于奖励的方法,进一步塑造模型的行为。
训练与日常使用是不同的过程。在一次普通回答中,模型通常使用已有权重进行计算,并不会更新这些权重。
你的提示词改变了当前需要处理的上下文,但不会自动重新训练底层模型。
第八章:从数字重新变成文字
经过最后一层处理后,最后一个可用位置的表示会被映射为词表中各个 Token 的分数。这些分数称为 Logits。
随后,Softmax 函数将这些分数转换为概率分布。
假设候选结果具有以下概率:
- “melted”:65%。
- “started”:20%。
- “was”:10%。
- 其他 Token 合计:5%。
这些概率完全是教学示例。这里使用的文字标签,在某个实际分词器中也可能被拆成不同的 Token。
系统接下来需要选择一个 Token。贪心解码会选择分数最高的选项;采样方法则允许从多个候选项中进行选择,Temperature、Top-p 等设置会影响用于选择的分布或候选范围。
因此,概率最高的 Token 并不总是最终生成的 Token。
选中的 Token 会加入上下文,参与下一步计算。不断重复这个过程,就形成一串 Token,再由分词器解码成可读的文字。
聊天应用还会提供消息、角色和指令的格式信息。这些上下文结构帮助模型生成助手回复,而不只是机械地续写用户最后输入的句子。
第九章:张量——这些数值结构的统称
前面已经出现了单个数字、向量和矩阵。在深度学习软件中,它们都可以纳入更广泛的概念:张量,也就是 Tensor。
标量是零维张量,向量是一维张量,矩阵是二维张量。增加更多轴,就能组织更复杂的数据集合。
假设一个批次包含 4 段序列,每段都填充到 12 个 Token,每个 Token 用 8 个数值表示,那么这些表示可以存放在形状为下面这样的张量中:
[4, 12, 8]
这三个轴分别表示:批次大小、序列长度和表示宽度。
注意力计算还可能引入注意力头等额外的轴。模型的不同组件也会使用不同形状的张量。输入、中间结果、输出和模型参数,都可以由张量保存。
这里有一个常见的术语陷阱:一个“4096 维向量”包含 4096 个分量,但从张量的轴数来看,它仍然只有一个轴。
向量有多少个分量,与张量有多少个轴,是两个不同的问题。
张量计算包括矩阵乘法、逐元素运算、求和等归约操作、归一化以及非线性运算。这些运算提供了数值处理机制,而模型是否能够表现出有用的能力,还取决于架构、训练数据、学习得到的参数和训练方法。
第十章:KV Cache——避免不必要的重复计算
从概念上看,每生成一个新 Token,上下文都会增长。但高效的实现并不需要重新计算此前所有 Token 的每一个中间结果。
键值缓存,也就是 KV Cache,会保存此前位置在注意力计算中产生的键和值。 处理新 Token 时,模型可以复用这些结果。
生成过程通常分成两个阶段。
第一个阶段是预填充,也就是 Prefill。模型处理输入提示词,并建立初始缓存。
第二个阶段是解码,也就是 Decoding。模型继续生成 Token,同时扩展并复用缓存。
缓存能够减少重复计算,但需要占用内存或显存。更长的上下文,以及更多同时处理的请求,都可能增加缓存的存储需求。
KV Cache 是临时计算状态,不同于模型学习得到的权重,也不同于聊天应用保存的对话历史。
第十一章:为什么流畅的回答仍然可能是错的
生成一个合理的续写,并不保证其中的事实准确。
模型可能因为某种表达符合训练中学到的模式,就生成一个语气自信、但内容错误的陈述。模糊的提示词、不完整的信息,或者不可靠的关联,都可能导致错误回答。
一个 Token 的生成概率,也不是对整句话真实性的直接测量。“接下来很可能出现这个词”,不等于“这句话很可能是真的”。
有些 AI 系统会加入检索、搜索、计算器、代码执行或其他工具,为模型提供外部信息或计算结果。
这些工具能够改善回答,但系统仍然需要选择相关证据,并正确解释工具返回的结果。调用了工具,并不意味着最终结论自动可靠。
Token 生成过程解释了文字是怎样产生的,而判断这些文字是否值得信任,仍然需要单独进行核实。
结论
一句话变成 AI 回答,需要经过一系列数值变换。
分词把文字转换成编号,嵌入把编号映射为向量,位置信息帮助模型区分顺序。注意力结合可用的上下文,学习得到的各种变换不断更新这些表示。
输出层产生 Token 分数,解码策略选择下一个 Token,再重复这个过程,直到回答完成。张量组织其中的数值数据,KV Cache 等技术则减少不必要的重复计算。
理解这条流程,并不需要先掌握每一个公式。最关键的联系是:语言变成数值表示,学习得到的计算变换这些表示,计算结果再指导后续语言的生成。
当这条联系清晰起来,Token、向量、矩阵、注意力和张量,就成为了同一个系统中各有作用、彼此连接的组成部分。
