一文看懂大模型底层原理:从“学知识”到“吐 Token”,它到底在做什么?
文章目录
当你在 ChatGPT 的对话框里输入一句话,到它把回复一个字一个字生成出来,中间并不是“瞬间想好答案”,而是走完了一整套固定流程。把这套流程按时间顺序拆开看,大模型从训练到上线,大致会经历三步:先在海量文本里学语言和知识,再通过额外训练学会按人的要求回答问题,最后在真正使用时,1个 Token 1个 Token 地把回复生成出来。
1、先看全貌:大模型的“一生”分三步
大模型从诞生到服务用户,通常会经历三个阶段:
| 阶段 | 类比 | 核心目标 |
|---|---|---|
| 预训练 | 上学读书 | 积累海量世界知识 |
| 微调 | 岗前培训 | 学会按要求回答问题 |
| 推理 | 正式上班 | 接收输入,输出结果 |
这三个阶段少一个都不行。只有预训练,模型知道很多东西,但不一定会好好回答;只有微调,没有足够知识储备,也答不出像样内容。真正好用的大模型,靠的是这三步接起来以后形成的整体能力。
2、预训练阶段:先把语言世界读进去
核心思想:靠“预测下一个词”把知识压进参数里
预训练阶段的核心任务并不复杂,概括起来就是:预测下一个词。
给模型一句话,比如“今天天气真”,让它猜下一个字更可能是“好”“热”还是别的词。猜对了,就沿着这个方向继续调参数;猜错了,就反过来修正。这个过程重复足够多次以后,模型参数里就会逐渐沉淀出语言里的统计规律、常识关联和一部分推理能力。
这件事在技术上叫 自回归语言建模(Autoregressive Language Modeling),目标函数通常写成这样:
L = − ∑ t = 1 T log P ( x t ∣ x 1 , x 2 , . . . , x t − 1 ) L = -\sum_{t=1}^{T} \log P(x_t | x_1, x_2, ..., x_{t-1}) L=−t=1∑TlogP(xt∣x1,x2,...,xt−1)
公式看着复杂,意思其实很直接:给定前面的内容,让模型尽量把下一个 Token 预测准。
训练数据有多大?
以 GPT-3 为例,公开资料里提到过它使用了大约 45TB 的文本数据,来源包括书籍、维基百科、网页和代码等。
模型并不是把这些内容逐字背下来,而是把其中的统计模式和语义关系编码进数十亿甚至上千亿个参数里。更接近的说法是:原始文本被消化掉了,能帮助预测语言的结构和关联被保留下来。
预训练真正巧的地方在于,它并没有被单独教“什么是语法”“什么是事实”“什么是逻辑”,但为了把下一个词猜得更准,它不得不在大量例子里学会这些东西。很多能力,就是在这个过程中被带出来的。
一个很有意思的角度是:预训练看起来只是在做“猜词游戏”,但模型为了把这个游戏玩好,最后被逼着学会了语法、语义、常识和部分推理。
3、微调阶段:从“会续写”到“会回答”
预训练完成后,模型已经有了相当强的语言能力,但还不算一个合格的对话系统。它擅长的是“接着往下写”,不天然擅长“听懂问题并给出合适回答”。
比如问一句“Python 怎么读取文件?”,一个只做过预训练的模型,很可能顺着上下文继续写成教材段落、论文式表述,甚至跑题。它知道很多内容,却没有被专门训练成问答助手。
微调就是在补这一课,常见做法分两步。
第一步:SFT,先学会按指令回答
第一步是 SFT(Supervised Fine-Tuning,监督微调)。做法是用大量“指令 - 回答”样本训练模型,让它熟悉问答格式和任务边界。例如:
指令:请用三句话解释什么是递归
回答:递归是函数调用自身的编程技巧。它需要一个基准条件来终止调用链。经典例子是计算阶乘:n! = n × (n-1)!
这类数据喂得足够多以后,模型会逐渐形成新的行为模式:看到问题就组织答案,尽量切题,尽量完整,也尽量符合常见表达习惯。
第二步:RLHF,再学会什么叫“答得好”
只会答,还不够。还要知道什么样的回答更有帮助、更安全、更符合人的偏好。这部分通常交给 RLHF(Reinforcement Learning from Human Feedback,基于人类反馈的强化学习)。
它的大致流程是:
- 让模型针对同一个问题生成多个回答
- 由人工对这些回答排序,判断哪个更好
- 用这些排序结果训练一个奖励模型(Reward Model)
- 再用强化学习方法,让原模型朝高奖励方向优化
经过这一步,模型不只是“能答”,而是更像一个被调教过的助手:回答更稳,更少冒犯,结构也更贴近人的预期。
可以把这两步粗略分开看:SFT 解决“按要求回答”,RLHF 解决“回答得更像一个合格助手”。
4、推理阶段:真正使用时,模型在做什么
训练阶段结束后,模型就进入了实际工作阶段。用户输入一句话,模型收到的是一段文本;真正开始计算前,它要先把这段文本变成自己能处理的形式,再经过多层网络计算,最后生成新的 Token,循环下去,直到输出完整回答。
Step 1:Tokenization,把文本切成 Token
模型不直接处理汉字、单词或句子,它处理的是 Token。Tokenizer 的工作,就是把输入切成一串 Token,再映射成对应的 ID。
# 以GPT系列常用的BPE分词为例
input_text = "大模型真的太强了"
tokens = tokenizer.encode(input_text)
# 可能被切成: ["大", "模型", "真的", "太", "强", "了"]
# 对应的token id: [1234, 5678, 910, 234, 567, 89]
Token 不等于“字”,也不等于“词”。它是一种折中单位。常见词、词组可能整体保留,低频词则会被拆开。很多模型使用 BPE 一类分词方法,目的很明确:既不能把词表做得太大,也不能让序列长得过头,还得尽量保留常见语义单元。
Step 2:Embedding + 位置编码,把 Token 变成向量
Token ID 只是整数,不能直接拿去做复杂运算。模型会通过 Embedding 矩阵,把每个 ID 查表映射成一个高维向量。
token "模型" → id 5678 → 查表 → [0.12, -0.34, 0.56, ..., 0.78] (4096维向量)
这个向量承载的是语义信息,但语义还不够,顺序同样重要。“我打你”和“你打我”用到的字几乎一样,意思却完全不同,所以模型还需要额外编码位置信息。
现代大模型里,很多会使用 RoPE(旋转位置编码)。它把位置信息融进注意力计算里,在处理长文本时更有优势。
Step 3:N 层 Transformer Block,核心计算都在这里
真正最耗算力的部分,是后面的多层 Transformer Block。一个大模型往往要堆几十层,LLaMA-70B 这种量级的模型,层数可以到 80 层左右。输入经过每一层,都会被重新加工一次。
每层通常包含两个核心模块:多头自注意力和前馈网络。
多头自注意力:让每个 Token 看见别的 Token
自注意力的作用,是让序列里的每个 Token 都能参考上下文里的其他 Token,并按相关程度分配不同权重。
例如在“他拿起桌上的苹果咬了一口”这句话里,计算“咬”时,模型更需要关注“苹果”,而不是平均看待所有词。自注意力就是在做这种关联计算。
核心公式通常写成:
Attention ( Q , K , V ) = softmax ( Q K T d k ) V \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V Attention(Q,K,V)=softmax(dkQKT)V
- Q(Query):当前 Token 想找什么信息
- K(Key):别的 Token 能提供什么线索
- V(Value):真正要传递的内容
所谓“多头”,就是同时做多组不同的注意力计算。不同的头可能分别偏向语法关系、长距离依赖、实体关联或语义相似性。
前馈网络:把信息再加工一遍
注意力层负责在 Token 之间传递和整合信息,前馈网络则负责对每个 Token 的表示做进一步变换。它通常是两层线性变换加上非线性激活,大致可写成:
FFN(x) = W₂ · GELU(W₁ · x + b₁) + b₂
有不少研究认为,模型里相当一部分事实性知识就沉在这些 FFN 参数中。注意力更像在“调信息”,FFN 更像在“存和改”。
残差连接 + LayerNorm:让深层网络还能稳定工作
每个子层外面一般都带残差连接和归一化(LayerNorm):
output = LayerNorm(x + SubLayer(x))
残差连接让输入可以直接绕过子层往后传,减轻深层网络中的梯度消失问题;LayerNorm 则帮助数值分布保持稳定。层数一多,这两样东西几乎是标配。
Step 4:输出层,从隐藏状态到概率分布
经过多层 Transformer 后,模型会拿当前位置的隐藏状态向量做一次线性投影,把它映射到整个词表大小的维度上,得到每个候选 Token 的分数,也就是 logits。再经过 Softmax,这些分数就变成概率分布。
hidden_state (4096维) → Linear → logits (32000维) → Softmax → 概率分布
这时候,模型对下一个 Token 的判断可能是这样:
"的" → 0.15
"了" → 0.12
"很" → 0.08
"不" → 0.06
...
Step 5:采样策略,不一定总选概率最高的
概率分布拿到了,还得决定怎么选。
最直接的方法是贪心解码(Greedy),每次都取概率最高的 Token。这样结果最稳定,但往往容易显得死板,碰上某些场景还可能反复重复。
所以实际系统通常会引入采样策略。常见的有几种:
- Temperature(温度):调节分布尖锐程度。温度越低,越保守;温度越高,随机性越强。
- Top-K 采样:只在概率最高的前 K 个 Token 里抽样。
- Top-P 采样:按累计概率截断,只在累计概率达到某个阈值的候选集合里抽样。
比如:
# Temperature越低,分布越尖锐(越确定)
# Temperature越高,分布越平坦(越随机/有创意)
probs = softmax(logits / temperature)
| Temperature 值 | 效果 | 适用场景 |
|---|---|---|
| 0(贪心) | 永远选最高概率的词 | 代码生成、需要精准的任务 |
| 0.7 | 较为确定,偶有惊喜 | 日常对话 |
| 1.0 | 原始概率,均衡 | 通用场景 |
| 1.5+ | 天马行空,可能语无伦次 | 脑洞创意,需谨慎 |
温度低,不代表模型更聪明,只代表它更不愿意冒险;温度高,也不等于更有创造力,只是允许它更频繁地选择低概率候选。实际产品往往会把几种策略混合起来用,在稳定性和灵活性之间找平衡。
Step 6:自回归循环,一个 Token 一个 Token 往后接
选出一个 Token 后,流程并不会结束。模型会把刚生成的 Token 接回输入序列末尾,再重复前面的计算,继续生成下一个 Token。这个过程会一直持续,直到出现结束标记 <EOS>,或者达到最大长度限制。
整个过程是自回归的,也就是说:后面的每一步,都依赖前面已经生成出来的内容。
输入: "Python怎么读取文件?"
第1步生成: "可"
第2步生成: "以"
第3步生成: "使"
第4步生成: "用"
...
直到生成 <EOS>
这也是为什么大模型的回复往往是流式出现的。不是它“想好了一整段再一起发出来”,而是它本来就是一段一段往后推的。
Step 7:Detokenization,把 Token 还原成人话
等到模型生成完一串 Token ID,最后一步就是通过 Tokenizer 的反向解码,把这些 ID 还原成文字,返回给用户。到这里,一次完整推理才算结束。
5、一张图串起全流程
【预训练】海量文本 → 预测下一个词 → 知识压入参数
↓
【微调】 SFT(学对话格式)+ RLHF(学人类偏好)
↓
【推理】 用户输入文字
↓
Tokenization:文字 → Token ID 序列
↓
Embedding + 位置编码:Token ID → 高维向量
↓
N × Transformer Block:
(多头注意力【融合上下文】→ FFN【加工特征】→ 残差+LayerNorm【稳定训练】)
↓
输出层 → Softmax → 词表概率分布
↓
采样策略(Temperature / Top-K / Top-P)→ 选出下一个 Token
↓
追加到序列 → 重复推理 → 直到 EOS
↓
Detokenization:Token ID → 文字 → 返回用户 ✅

6、踩坑与常见误区总结
🚫 误区 1:“大模型在检索数据库里的答案”
✅ 事实:大模型没有实时检索能力(除非接入了 RAG)。它的"知识"是在预训练时压缩进参数权重的,本质上是在做概率预测,而非查找。
🚫 误区 2:“Temperature=0 就是最好的”
✅ 事实:贪心解码在创意任务中会让输出单调乏味,甚至陷入重复循环。应根据任务类型选择合适的采样策略。
🚫 误区 3:“Token 就是一个字/词”
✅ 事实:Token 是子词单元。中文里通常 1-2 个字为一个 Token,英文里一个常见词可能是 1 个 Token,而一个生僻词可能被拆成 3-4 个 Token。这直接影响你的 API 计费和上下文窗口使用量。
🚫 误区 4:“模型层数越多就越好”
✅ 事实:层数只是影响能力的因素之一。参数质量、训练数据质量、微调策略的好坏同样至关重要,盲目堆层反而可能带来训练不稳定、推理慢等问题。
🚫 误区 5:“大模型每次回答相同问题结果应该一样”
✅ 事实:只要 Temperature > 0,采样就引入了随机性。相同问题每次的输出可能不同,这是设计如此,而非 Bug。
7、写在最后
大模型的"神奇"并非魔法,而是海量数据 + 精巧架构 + 精心训练共同作用的结果。每一次你与它对话,它都在毫秒级别内完成了上述所有步骤,从数十亿参数中"召唤"出最符合你期望的那串文字。
理解这套原理,不仅能帮助你更好地使用大模型(比如知道怎么调参、为什么要控制 Token 数量),更能为你深入研究或开发大模型应用打下坚实基础。
更多推荐


所有评论(0)