无需数学基础,理解LLM运作原理

作者:技术拾光时间:2026-06-27 06:27:01浏览:600

大语言模型通过tokenizer将文本转为整数ID,经嵌入层变为高维向量并加入位置信息,再经多层Transformer中的注意力机制与前馈网络处理,最终将最后一个token映射为概率分布,逐token采样生成回答。整个过程依赖残差连接与层归一化稳定训练,核心是下一词预测。

今天读到一篇相当不错的文章,题目是《How LLMs Actually Work》。作者绕开了复杂的数学原理,用非常直观的方式把大语言模型(LLM)的工作机制讲清楚了。如果你一直觉得大语言模型是个黑盒,那这篇文章正好能帮你打开它——当然,前提是别被那些术语吓到,我们一句一句拆开看。

一张图就能说明白:LLM要理解一句话并给出回答,大致需要经历这么几步——先把文本切成token ID,再变成高维向量,加入位置信息,通过多层Transformer让token互相交换信息,做局部和全局变换,最后把最后一个token的向量映射成下一个token的概率分布,然后一个token一个token地采样生成完整回答。听起来有点绕?别急,我们一步一步来。

1. Tokenization:模型不读文字,只读整数

这个环节很关键:LLM并不直接处理自然语言字符串。它先通过tokenizer(分词器)把文本变成一串整数ID,每个整数对应词表里的一个token。注意,token不一定是单词,也不一定是字符,更多时候是subword。比如tokenization可能会被切分成["token", "ization"],running会被切分成["run", "ning"]。为什么这么干?因为如果直接用整个单词作词表,词表会大到爆炸,而且遇到新词时泛化能力很差;如果降到字符级别,词表倒是小了,但序列长度会变得非常长,计算成本飙升。所以subword方案是一种折中。

这正好解释了LLM里一个经典现象:不同模型家族的tokenizer各不相同。GPT系列常用BPE变体,LLaMA风格模型则偏爱SentencePiece。简单来说,tokenizer就像是LLM世界的“输入法+压缩器+词表协议”,它决定了模型怎么“看”你输入的每个字。

2. Embeddings:整数本身没意义,要变成向量

前面说的token ID只是一个索引,比如1024这个数字本身不代表任何语义。模型真正处理的是embedding(嵌入)——从embedding matrix里查出来的一行高维向量。看到“hidden size = 4096”时别慌,我们可以把它理解成模型给每个token画了一张“含义雷达图”。

比如token是“苹果”,人看到这个词会联想到:水果、甜的、红色/绿色、Apple公司、手机、乔布斯、可以吃、科技品牌……但模型不会用中文标签写这些特征,它会把“苹果”变成一串数字,大约长这样:[0.12, -0.48, 0.03, 1.27, ...],一共4096个数字。这串数字不是随机的,而是训练出来的“含义坐标”。如果只用一维描述,“苹果=8,香蕉=7,手机=3”;二维的话就是“甜度、科技感”两个轴——苹果水果可能是甜度9、科技感1,Apple公司则是甜度0、科技感10。4096维就是超级复杂的雷达图,同时看几千个隐含方向:是不是名词?是不是品牌?是不是食物?和水果相关程度?和手机相关程度?和颜色相关程度?和上下文相关程度?等等。当然,真实维度不是人工命名的,但理解思路就是这样。

还有一点需要注意:embedding不是静态的。随着Transformer一层层处理,这个4096维向量会不断变化。经典的例子是king - man + woman ≈ queen,这就是向量空间中语义关系的体现。不过,embedding只管语义,不管位置——“dog”出现在句首还是句尾,查出来的基础embedding是一样的,所以才需要后续的“位置编码”。

3. Positional Encoding:模型怎么知道顺序?

纯self-attention本身不天然知道词序。如果不给它位置信息,它就无法区分“dog bites man”和“man bites dog”。所以模型必须把token的“位置”注入进去。早期的方法是把位置信息加进embedding里,但这种方法有两个问题:一是语义和位置被塞进同一组数字里,容量有限;二是绝对位置embedding对长上下文泛化不好——如果模型训练时只见过2048长度,位置5000的特征没有被充分学习过。

现代LLM大多使用RoPE(旋转位置编码,Rotary Position Embeddings)。它不是把位置向量加到embedding上,而是在attention的计算过程中旋转Query和Key向量,旋转角度取决于token的位置。这样做的好处是能更好地处理相对位置关系,也更适合长上下文场景。

不过,即使用了RoPE,LLM仍然有一个“lost in the middle”的问题:长prompt中开头和结尾的信息更容易被利用,中间部分经常被忽略。所以不要以为上下文长了就万事大吉——能塞进去,不代表模型能同等权重地用上。

4. Attention:token之间怎么交换信息?

每个token会被投影成三种向量:Query(我在找什么?)、Key(我能被什么匹配?)、Value(如果我被匹配上,我传递什么信息?)。Query和Key做点积,得到匹配分数,再通过softmax变成权重,最后用这些权重对Value做加权平均——高权重的token的Value会更强地影响当前token的新表示。

说人话就是:每个token都会去上下文里“找相关信息”,先判断谁和自己最相关,再按相关程度把它们的信息混合进自己。Query负责提问,Key负责被匹配,Value负责提供内容,匹配越高,内容影响越大。

举个例子:句子"The cat that I saw yesterday was sleeping."当模型处理"was"时,它需要知道谁"was sleeping"。"was"的Query会和前面token的Key做比较——和"cat"的匹配度较高,和"yesterday"的匹配度较低。softmax后"cat"得到更高权重,于是"cat"的Value对"was"的新表示影响更大,模型就能把几个位置之前的主语关联过来。

对于GPT-style decoder-only模型,还有一个限制:生成是从左到右的,所以当前位置不能看未来token,这叫causal masking(因果掩码)。实现上就是把未来token的注意力分数设得极低,softmax后权重几乎为0。

另外,attention的计算代价很高。full attention里每个token要和所有可见token做比较,所以prompt长度翻倍,计算量大致会变成四倍——这就是长上下文贵、慢、占资源的底层原因之一,也催生了FlashAttention、sparse attention、linear attention等研究方向。

5. Multi-head Attention

单个attention head只能学一种关系,但语言里同时存在很多种关系:主谓一致、代词指代、局部短语、长距离引用、位置模式……所以Transformer会并行运行多个attention head。每个head不是简单拿原始token向量的一小段切片,而是用自己的一套“滤镜”,从完整的4096维向量里提取它关心的128维信息。

每个head独立做attention,输出再拼接起来,经过一个最终线性层混合回完整向量。这种设计让模型能同时捕捉多种不同的语义关系。

这里有一个实际工程上的重要点:KV cache(键值缓存)。生成时,模型不希望每生成一个token就重算整个prefix,所以会缓存过去token的Key和Value。新token到来时,可以直接复用旧的K/V。但KV cache是长上下文推理的主要内存成本之一。现代decoder-only LLM常用GQA(分组查询注意力,Grouped-Query Attention),让多个query head共享较少数量的key/value head,从而减少KV cache内存压力。

打个比方:正常多头注意力可以理解为32个head = 32套Query + 32套Key + 32套Value。问题是生成时要缓存历史K/V,上下文越长、层数越多、Key/Value头越多,占用的显存就越大。GQA改成:32个Query head但只有8个Key/Value head,每4个Query head共用1组Key/Value。这就像公司里多个项目组共享同一套后勤团队,保留不同的观察角度,同时大幅减少需要缓存的数据量。实际例子:LLaMA-2 70B有64个query heads但只有8个key/value heads,Mistral 7B则是32个query heads和8个key/value heads。

6. Feed-Forward Network

前馈网络(Feed-Forward Network,FFN)是模型“记知识”的大仓库之一。Attention负责token之间的信息交换,但每个Transformer layer还有一个重要的模块:FFN。Attention是token之间“互相看”,而FFN是每个token独立做进一步加工,不混合其他token。

FFN通常有三步:先把向量从一个较小的维度(比如4096)扩展到更大的维度(比如11008),然后通过一个非线性激活函数做选择,最后压缩回原来的维度。这个过程可以理解成:Attention负责“从上下文里找信息”,FFN负责“把找到的信息在自己脑子里再加工一遍”。

  • Attention:这个token去看别的token——“我该参考谁?”“前面哪个词和我有关?”“这个代词指的是谁?”
  • FFN:这个token不再看别人,而是在自己内部加工——“结合刚才拿到的信息,我现在应该更像什么?”“我是水果苹果,还是Apple公司?”“我是变量名,还是普通英文单词?”

简单说:Attention是信息搬运/上下文关联,FFN是信息加工/知识变换。原始Transformer用ReLU,GPT/BERT常用GELU,现代LLaMA、Mistral、PaLM等常用SwiGLU。核心结构仍然是expand-transform-compress,变化主要在非线性函数。

值得注意的是,dense transformer里大量参数其实在FFN,而不是attention。FFN里存着很多模型的事实和语义结构,一些neuron会对特定概念强激活,比如Eiffel Tower、编程语言、过去时动词等。而MoE(混合专家模型,Mixture of Experts)不是每层只有一个FFN,而是有多个expert FFN,再由router为每个token选择少数几个expert,这样可以在不增加计算量的情况下大幅扩展模型容量。

7. Residual Stream 和 LayerNorm

Transformer里不是每层都把旧表示完全替换掉,而是把attention或FFN的输出加回原向量:new vector = old vector + block output。这叫残差连接(residual connection)。多层堆叠后,每层贡献都会累积在一个持续流动的表示里,这个运行中的总和就是残差流(residual stream)。

例如,一个token一开始只是“苹果”。经过attention后,它可能从上下文里拿到信息——“前面刚提到了Apple公司”。这一层不会把“苹果”原来的表示整个删掉,而是把新信息加进去,让它越来越像“Apple公司”。再经过下一层FFN,它又补上一些更深的知识——“Apple公司总部在硅谷”。残差连接就像给信息修了一条高速公路,让深层网络能够顺利地把信号传递下去。

这个技巧来自ResNet,最早是为了解决深层图像网络训练困难的问题。残差连接解决的是“深层网络怎么把信息和训练信号一路传下去”,而LayerNorm/RMSNorm解决的是“传下去的时候,数值不会出问题”。

  • 残差连接让Transformer每层只做“增量修改”,旧信息可以沿着residual stream一路传下去,所以深层网络更容易训练。
  • 残差流就像模型内部的公共黑板,attention、FFN和最终输出层都在上面读写。
  • LayerNorm/RMSNorm则是数值稳定器,防止这块黑板上的向量经过几十层相加后爆炸或塌缩。

8. Next-token Prediction

所有Transformer层处理完后,模型会得到每个token的最终向量。生成下一个token时,模型通常只取最后一个token的最终向量,把它映射成词表大小的一组分数——比如词表有100,000个token,就得到100,000个raw scores,这些叫logits。

logits还不是概率,经过softmax后才能变成“下一个token是每个候选token的概率分布”。模型通常不会永远选概率最高的token,temperature、top-k、top-p等解码参数会影响采样行为:低temperature更保守、更确定,高temperature更随机、更发散,top-k/top-p会限制候选token集合,只从比较合理的范围里采样。

一旦选出一个token,它就被追加到输入后面。模型再基于更长的序列预测下一个token,这个循环一直持续,直到生成EOS token或达到长度限制。整段回答就是这个循环反复运行的结果。

举个例子:当前输入是“苹果发布了新”,模型处理完所有Transformer层后,会拿最后一个token“新”的最终向量去预测后面最可能接什么。它不会直接说“芯片”,而是先给整个词表里的所有token打分:“芯片:12.8”“手机:10.4”“产品:9.7”“系统:8.9”“电影:-3.2”“香蕉:-6.5”……这些原始分数就是logits。softmax后变成概率:“芯片:45%”“手机:18%”“产品:12%”“系统:8%”……然后模型才开始“选下一个token”。temperature控制模型敢不敢冒险,top-k是只看前k个候选,top-p是只看累计概率达到p的候选集合。

基础LLM的核心训练目标就是next-token prediction——它并不是直接以“事实正确”“会聊天”“会推理”“会写代码”为目标训练的,而是在海量文本上学习预测下一个token。后训练(指令微调、RLHF等)才让模型变得像助手,但底层生成机制仍然是基于概率分布逐token采样。

顺便一提,有些模型会采用投机解码(speculative decoding):小模型先快速草拟多个token,大模型并行验证,如果草拟的token在大模型概率下可接受就直接采用,否则回退到大模型生成。做得好的时候,输出分布可以等价于单独运行大模型,但速度快得多。

9. Architecture vs Weights

最后聊聊GPT、Claude、Gemini、LLaMA这些模型到底差在哪里。闭源模型不会公布所有结构选择,但在这篇文章讨论的层面,它们大多都处于Transformer-family设计空间中。现代Transformer LLM的共同骨架大体包括前面提到的那些东西:tokenization、embedding、positional encoding、stacked transformer layers、multi-head attention、feed-forward network、residual stream、normalization、next-token prediction。

真正让模型不同的主要来自三个方面:

  • 第一,训练出来的weights——不同数据、规模、训练流程学出来的参数。
  • 第二,配置差异——层数、词表大小、head数、参数量、dense还是MoE等。
  • 第三,post-training——指令微调、人类偏好学习、安全控制、对话行为塑造等。

最后

简单总结几个关键点:

  • token是一切的入口。模型不是按人类自然理解的字、词、句直接思考,而是处理tokenizer给出的ID序列。tokenization会影响成本、长上下文、多语言表现、字符级任务表现。
  • embedding是语义空间。token ID通过embedding matrix变成向量,语义关系是训练中学出来的几何结构。
  • RoPE不是简单“告诉模型第几个词”,而是在attention的Q/K比较中编码相对位置,这也是它比早期绝对位置embedding更适合现代长上下文模型的原因。
  • attention是信息路由,不是知识本体。它决定当前token应该从哪些上下文token吸收信息,但dense模型中大量参数和事实结构其实在FFN里。
  • KV cache是推理成本的核心之一。很多人只知道“上下文越长越贵”,但原因不只是输入token变多,还包括每层要保存历史K/V,生成时持续复用。
  • FFN很可能是“模型知识仓库”的重要部分。事实、概念、语义结构大量分布在FFN权重和激活中,MoE本质上也是围绕FFN容量和计算成本做稀疏扩展。
  • 残差流是现代interpretability的核心对象。每个模块都在residual stream上读写,模型不是一层层覆盖旧信息,而是在不断累积和修改表示。
  • base model的训练目标不是“正确回答”,而是next-token prediction。后训练让模型变得像助手,但底层生成机制仍然是基于概率分布逐token采样。