前段时间,儿子问我:“爸爸,ChatGPT 是怎么知道该说什么的?”

我决定认真回答这个问题。不是敷衍一句“它很聪明”,而是真的把 LLM 的原理拆给他看。于是做了一套 PPT —— LLM for Kids,从 Token、Embedding 一路讲到 Attention、Transformer,用“小猫坐在垫子上”当例句,用“成绩单”和“画饼图”当类比。

做完这套 PPT,我自己的收获比预期大得多。当你必须把一个概念解释到小学生能懂的程度,你就被迫剥掉所有术语的包装,直面本质。

而这个本质,简单到让人意外:

LLM 就是一个函数。

不是比喻,不是类比,是数学意义上的函数。输入一组 Token,输出一个概率分布。所有让人觉得“AI 好像在思考”的行为,都是这个函数反复调用自身的结果。

从一个 d 维空间说起

训练一个 LLM,第一步是假设一个 d 维空间的存在。d 可以是 4096,可以是 8192,具体多少取决于模型设计。

每个 Token——一个词、一个子词、一个标点——被映射成这个空间里的一个向量。这步操作叫 Embedding,本质上就是一张查找表:Token ID 进去,d 维向量出来。

训练之前,这些向量是随机初始化的。“猫”和“狗”可能离得很远,“猫”和“利率”可能紧挨着。但训练结束后,语义相近的词会被拉到附近——不是人工设定的,是梯度下降自己调出来的。

词的“意思”,就是它在高维空间里的位置。

Attention:动态路由

但这里有个问题:Embedding 给每个 token 的是一个静态的、与上下文无关的位置。“苹果”不管出现在“我吃了一个苹果”还是“苹果发布了新 iPhone”,查表拿到的向量是同一个——它只编码了“苹果”的平均语义,不知道在当前这句话里它到底是水果还是公司。

Attention 做的就是:根据上下文,动态调整每个 token 的表示。 Embedding 是给每个 token 分配一个“默认人设”,Attention 是让它们互相交流之后,根据语境各自调整。没有 Attention,每个词都活在自己的世界里,不知道邻居是谁。

对于序列中的每个位置,Attention 回答一个问题:我应该关注谁?关注多少?

数学上,它把每个向量变换成三个角色:

  • Q(Query):我在找什么
  • K(Key):我能提供什么
  • V(Value):我实际的内容

然后用一个公式完成匹配和聚合:

算的是每对位置之间的相关性分数。 是个缩放因子,防止点积过大导致 softmax 输出趋近 one-hot(梯度消失)。softmax 把分数归一化成权重,再用权重对 V 做加权求和。

一句话概括:Attention 就是一个可学习的、动态的加权求和。

Multi-Head Attention 则是同时做多组这样的运算。每个 Head 学到不同的关注模式——有的关注语法依赖,有的关注语义相似,有的关注位置距离。最后把多个 Head 的结果拼起来,过一个线性变换。

FFN:知识仓库

每个 Transformer Block 里,Attention 之后紧跟一个 Feed-Forward Network(FFN):

两层全连接,中间一个激活函数。看起来平平无奇,但近年来 Mechanistic Interpretability 研究揭示了一个有趣的分工:

Attention 负责信息路由——决定从哪里取信息。FFN 负责知识存储——模型记住的“事实”大量编码在 FFN 的参数里。

这意味着当你问 LLM“法国的首都是什么”,Attention 负责把“法国”和“首都”关联起来,FFN 负责从参数里“回忆”出“巴黎”。

训练目标:简单到不像话

整个训练过程的目标只有一个:Next Token Prediction。

给定前 n 个 Token,预测第 n+1 个。计算预测的概率分布和真实分布之间的交叉熵损失,反向传播,更新参数。

词表 V 0 → "的" 1 → "苹果" 2 → "坐" 3 → "猫" … 50,000 个 tokenizer 生成 "苹果" → id=1 Embedding 表 |V| × d 矩阵(可学习) 0: [0.12, -0.45, ...] 1: [0.83, 0.21, ...] 2: [-0.31, 0.67, ...] 向量 x [0.83, 0.21, …] d 维 静态,与上下文无关 线性投影(可学习) W_Q d × d_k → Q ="我在找什么" W_K d × d_k → K ="我能提供什么" W_V d × d_k → V ="实际内容" 训练前随机初始化,训练中梯度更新 Attention softmax(QKᵀ/√d)·V 上下文融合 "苹果"→ 水果 or 公司? FFN 知识存储 × N 层(12 ~ 96 层) 输出层 → 词表概率分布 预测:"坐" P("坐")=0.72 真实答案:"坐" 计算损失 交叉熵 反向传播 → 更新所有参数 θ Embedding 表 · W_Q · W_K · W_V · W_FFN ... 参数 θ = 全部可学习的权重 训练就是在调 θ,让 f_θ(X)≈Y 前向传播 反向传播 可学习参数 固定组件

就这么一个目标。没有人教它语法,没有人教它逻辑,没有人教它写代码。但当模型足够大、数据足够多,这些能力就“涌现”了。

为什么?因为要准确预测下一个 Token,你必须理解上下文。要理解上下文,你就得隐式地学会语法、语义、逻辑、常识、甚至世界知识。预测下一个词,是对语言理解能力的极致压缩。

那“智能”是什么?

回到开头的论点:LLM 就是一个函数。

几十亿到几千亿个参数 ,通过海量数据训练出来,将 Token 序列映射到词表上的概率分布。单次 forward pass,纯矩阵运算,无副作用,确定性输出。

那对话呢?不过是这个函数的自回归调用——上一步的输出拼到输入末尾,再调一次。Temperature 和 Top-p 采样引入了随机性,但那是推理阶段的工程选择,不是模型本身的属性。

这不是在贬低 LLM。恰恰相反,一个“仅仅”做函数拟合的系统,能涌现出看起来像推理、像创造、像理解的行为,这件事本身才是真正值得敬畏的。

Conway 的生命游戏也是函数——几条简单规则,却能演化出无限复杂的图案。LLM 类似:简单的训练目标,通过足够大的参数空间和数据,涌现出超出直觉的能力。

去神秘化的意义

理解“LLM 是函数”,有实际价值:

它让你不再把 LLM 的错误当成“AI 不靠谱”,而是理解为函数在某些输入区域的拟合不够好。它让你知道 Prompt Engineering 在做什么——调整输入向量在高维空间中的位置,让它落到函数拟合得好的区域里。它让你理解为什么 Context Window 有上限——不是技术限制那么简单,而是 Attention 的计算复杂度是

不需要敬畏,不需要恐惧,需要的是理解。 当你知道引擎盖下面是什么,你才能把它用到极致。