模型训练原理(二)|大模型为什么只靠“预测下一个 Token”,就能学会语言、知识和代码?
第一课我们把“大模型训练”拆到了最底层:模型拿到数据,产生预测,形成 Loss,再通过 Gradient 和 Optimizer 修改参数。换句话说,训练最核心的事情始终没有变——找到一组更好的参数。
但第一课最后其实故意留下了一个更麻烦的问题:
普通监督学习可以写成:
(x,y)
输入 (x),给一个标准答案 (y)。
可语言模型的 (y),到底从哪里来?
这也正是第二课真正要解决的问题:Next Token Prediction、Conditional Probability、Context 和 Autoregressive Modeling。
这个问题一旦想通,你会第一次真正明白:
为什么互联网上那些没有人工标签的书、网页、代码和文章,居然都可以拿来训练大模型。
先想一个看起来几乎无解的问题
假设我现在给你一本小说。
里面有几十万字。
然后告诉你:
用它训练一个神经网络。
你第一反应可能会问:
训练什么?
输入是什么?
答案又是什么?
因为在传统监督学习里,我们习惯看到的是这样的数据:
输入:
“法国的首都是哪里?”
答案:
“巴黎。”
或者:
输入:
一张猫的照片。
答案:
“猫。”
这很好理解。
模型做错了,可以拿预测和标准答案比较。
有了差异,就能算 Loss。
有了 Loss,就能训练。
可是一本小说不是这样。
它没有人专门在每句话旁边写:
“这句话的标准答案是……”
互联网也不是这样。
网页、论坛、论文、新闻、GitHub 代码、技术文档,大多数都只是普通内容。
没有 Label。
没有 Answer。
没有人为它们准备 (y)。
这就产生了一个非常现实的问题。
如果训练大模型需要人类把互联网重新标注一遍,那么今天这种规模的大模型几乎不可能出现。
因为数据规模一旦来到数十亿、数千亿甚至更多 Token,人工逐条构造答案根本不可行。
所以真正关键的问题不是:
模型怎么学?
第一课已经回答了。
真正的问题变成了:
我们能不能让文本自己产生训练答案?
答案是:
可以。
而且方法简单得惊人。
一句话,自己就能产生训练数据
假设我们有一句话:
我喜欢机器学习
为了方便教学,我们暂时假设:
“我”
“喜欢”
“机器”
“学习”
分别对应一个 Token。
真实 Tokenizer 不一定这么切,那个问题我们后面单独讲。
现在先只看这句话。
我们把后面的内容暂时遮住,只给模型:
我
然后问它:
下一个 Token 是什么?
答案在哪里?
根本不用找人标。
原文已经告诉我们:
喜欢
于是我们得到第一条训练数据:
x=“我”
y=“喜欢”
继续。
给模型:
我喜欢
让它预测下一步。
原文已经告诉我们:
y=“机器”
再继续:
输入:
我喜欢机器
目标:
学习
你会发现,一句本来没有任何人工标签的普通文本,突然变成了很多组:
(x,y)
更准确地写:
(前面的 Token,下一个 Token)
这就是一个极其重要的转折。
传统监督学习通常需要:
人提供 Input,人再提供 Label。
语言模型却可以直接利用文本本身:
前面的文本作为 Input,原文真正出现的下一个 Token 作为 Label。
于是,原本只有“内容”的互联网,突然拥有了几乎取之不尽的训练目标。
这就是 Next Token Prediction 最容易被低估的地方。
它看起来只是:
猜下一个 Token。
实际上它解决了大规模语言模型训练首先必须解决的一个生死问题:
海量监督信号从哪里来?
答案:
从数据自己里面来。
这就是 Self-Supervised Learning 真正“Self”的地方
很多人第一次看到 Self-Supervised Learning,会误解成:
“模型自己教自己。”
不太准确。
这里的“Self”,更应该理解成:
监督信号可以从数据自身构造出来。
比如原文是:
深度学习正在改变软件开发方式
训练过程中,可以不断构造:
看到:
深度
预测:
学习
看到:
深度学习
预测:
正在
看到:
深度学习正在
预测:
改变
……
并不需要一个人坐在电脑前告诉模型:
“这里答案是‘正在’。”
因为答案早就在原始文本里。
所以,一旦拥有大量原始文本,我们就拥有了大量自动生成的训练任务。
这才是 Next Token Prediction 能够 Scale 的第一个根本原因。
但这里有一个非常重要的误区
我们经常说:
大模型就是预测下一个 Token。
这句话没有错。
但如果把它理解成:
大模型就是高级一点的文字接龙。
那就已经错得很远了。
因为模型真正学习的并不是:
“看到这几个字以后,死记硬背下一个字是什么。”
它真正要学习的是一个概率问题。
假设现在的 Context 是:
法国的首都是
接下来到底是什么?
“巴黎”非常合理。
但模型真正做的事情,不是简单输出一句:
答案 = 巴黎。
更准确地说,它需要判断整个 Vocabulary 里的大量 Token:
在当前 Context 下,
谁更可能出现?
概念上可能类似:
| 巴黎 | 很高 |
| 伦敦 | 较低 |
| 北京 | 很低 |
| 香蕉 | 几乎不可能 |
| 跑步 | 几乎不可能 |
这里故意不写具体概率,因为这些数字取决于具体模型和上下文。
但思想非常重要:
模型真正学习的是“下一个 Token 的概率分布”。
数学上写成:
P(xt | x<t)
这条公式是理解语言模型的第一条核心公式。
先别背。
我们把它翻译成人话。
P(xt | x<t) 到底在说什么?
先看:
xt
表示现在要预测的第 (t) 个 Token。
而:
x<t
表示它之前已经出现的所有 Token。
所以:
P(xt | x<t)
真正的意思是:
在已经看到前面这些内容的条件下,下一个 Token 出现的概率是多少?
中间这个符号:
|
可以直接读成:
“在……条件下”。
例如:
P(巴黎 | 法国的首都是)
意思就是:
已经知道前面是“法国的首都是”以后,接下来出现“巴黎”的可能性有多大?
这时候你会发现:
所谓 Language Model,最底层其实真的是一个:
Probability Model。
它不断问同一个问题:
给定现在的 Context,接下来各种 Token 有多可能出现?
这件事非常重要。
因为后面的:
Logits、
Softmax、
Cross Entropy、
Sampling、
Temperature、
DPO、
Policy、
KL,
最后几乎都会重新回到“概率分布”上。
如果这一层没建立起来,后面很多东西只能靠背。
为什么一定要强调 Context?
因为语言几乎不可能脱离上下文理解。
比如只给你一个字:
行
它是什么意思?
不知道。
可能是:
银行。
行业。
行为。
步行。
“不行。”
“这样也行?”
单独看这个 Token,几乎没法判断。
现在我把 Context 给出来:
我准备把钱存进银
你几乎马上就知道:
下一个很可能是:
行
再换一个:
这个方案我觉得不
你也可能预测:
行
同样一个 Token。
含义完全不同。
区别在哪里?
不是 Token 自己变了。
是:
Context 变了。
所以语言模型真正学习的从来不是一个简单关系:
银→行
而是:
整个 Context
→
下一个 Token 的概率分布
这也是为什么现代大模型如此重视 Context。
一句话里某个“它”到底指谁?
代码里的变量在哪里定义?
一个人物几十段之前说过什么?
前面的系统指令要求了什么?
这些问题本质上都在影响:
P(xt | x<t)
于是一个我们后面会反复遇到的问题已经提前出现了:
如果 Context 越来越长,模型到底怎样知道哪些历史信息现在最重要?
这个问题最终会把我们带到 Attention。
再往后会带到 KV Cache、Long Context、Sparse Attention。
但现在不要急着往 Transformer 跳。
第二课先把概率模型这件事吃透。
Autoregressive 其实一点都不神秘
接下来讲一个听起来很学术的词:
Autoregressive Modeling
自回归建模。
第一次看到这个词,很多人会觉得又是什么复杂数学。
其实放到大语言模型里,它的核心直觉非常简单。
假设现在有:
今天下班以后我准备
模型根据当前 Context 预测下一个 Token。
假设这次产生:
去
那么新的 Context 就变成:
今天下班以后我准备去
接下来模型再次预测。
假设得到:
吃
新的 Context 变成:
今天下班以后我准备去吃
再预测:
饭
于是:
今天下班以后我准备去吃饭
生成过程一直重复:
| 当前 Context |
| ↓ |
| 预测一个 Token |
| ↓ |
| 把这个 Token 接回 Context |
| ↓ |
| 再预测下一个 Token |
| ↓ |
| 再接回去 |
所以一段几百字的回答,在建模层面并不是:
模型一次性决定整篇文章。
而是被拆成:
第一次预测。
第二次预测。
第三次预测。
……
直到结束。
这就是为什么叫:
Autoregressive。
过去已经出现的序列,会不断参与后面内容的预测。
说得更人话一点:
模型永远只决定“下一步”,但下一步一旦发生,就会改变后面的所有步骤。
这个直觉非常重要。
因为它还能解释一个日常现象:
为什么模型有时候前面生成错了一点,后面会越走越偏?
因为之前生成的内容已经进入新的 Context。
后面的预测是建立在这个 Context 上继续进行的。
错误不会自动消失。
它可能继续影响:
P(xt+1 | x≤ t)
这也是自回归生成一个天然的重要特征。
最漂亮的一步来了:整篇文章,可以拆成无数个“下一步”
现在假设一段文本是:
x1,x2,x3,…,xT
我们真正想建模的是整段文本:
P(x1,x2,…,xT)
也就是:
这一整个 Token Sequence 出现的概率。
乍看非常复杂。
几十个 Token 还好。
如果是一万 Token 呢?
十万呢?
模型难道要一次性理解一个如此巨大的联合概率?
关键就在这里。
概率论里的 Chain Rule 告诉我们:
P(x1,x2,…,xT)
可以拆成:
P(x1)
P(x2 | x1)
P(x3 | x1,x2)
⋯
P(xT | x1,…,xT-1)
压缩以后:
P(x)=∏t=1TP(xt | x<t)
这条公式非常重要。
但真正值得记住的不是公式本身。
而是它背后的思想:
一个巨大的“整段语言建模问题”,可以被拆成很多个完全相同的“下一 Token 预测问题”。
比如一句:
我今天晚上准备回家吃饭
不用直接问模型:
“这整句话的概率是多少?”
我们可以拆:
“我”出现得合不合理?
已经看到“我”,接“今天”合理吗?
已经看到“我今天”,接“晚上”合理吗?
已经看到“我今天晚上”,接“准备”合理吗?
……
一直到最后。
于是一个看起来巨大无比的问题:
怎么学习语言?
被统一成了同一个局部任务:
根据目前已经看到的东西,预测下一步。
这就是自回归语言模型设计得非常漂亮的地方。
Chain Rule 不是 Transformer 发明的
这里顺便把一个技术边界讲清楚。
P(x1,…,xT)
∏tP(xt | x<t)
本身只是概率论中的 Chain Rule。
Transformer 没有发明它。
大语言模型也没有发明它。
真正关键的设计选择是:
我们利用这种分解方式,把文本建模变成一个从左到右的 Next Token Prediction 问题。
而这件事刚好还有一个巨大的好处:
训练目标和生成过程可以自然接起来。
训练时学习:
P(xt | x<t)
真正生成时,也不断使用:
P(xt | x<t)
得到一个新 Token。
然后继续。
训练学的东西,
正好就是生成时需要使用的东西。
这也是为什么这种建模方式如此自然。
现在终于可以回答最有意思的问题
很多人第一次知道大模型是 Next Token Prediction以后,会有一种巨大的违和感。
你告诉我:
ChatGPT、Claude、Gemini 这类模型,
底层竟然只是一直在预测下一个 Token?
那为什么最后会写代码?
为什么会翻译?
为什么知道历史?
为什么能解释物理?
为什么还能表现出推理?
如果目标真的只是:
猜下一个 Token。
这些能力到底从哪里冒出来?
这里才是第二课最值得真正想明白的地方。
答案不是:
“Next Token Prediction 里面藏着一个神秘的智能公式。”
恰恰相反。
Objective 非常简单。
真正复杂的是:
想在真实世界的海量文本上持续把下一个 Token 猜对,本身就是一件极其困难的事情。
想预测好语言,你就不得不学语言
假设文本是:
虽然外面正在下暴雨,但是
如果模型完全不懂语言结构,
它很难持续预测后面的内容。
因为:
“虽然……”
和后面的:
“但是……”
之间有明显的结构关系。
这意味着为了降低预测错误,
模型需要逐渐捕捉:
语法。
词义。
上下文。
句式。
长距离依赖。
模型没有一节课叫:
《现代汉语语法》
但如果不捕捉语法规律,它的预测就很难一直做好。
所以训练会不断给它压力。
想预测好事实文本,你就不得不捕捉事实关系
再看:
法国的首都是
后面大量高质量文本里,经常会出现:
巴黎
如果模型总认为:
“东京”
“香蕉”
“CPU”
概率更高,
它就会反复产生更大的预测错误。
于是训练会推动参数变化。
久而久之,
“法国”
“首都”
“巴黎”
这些概念之间会形成某种有利于预测的内部关系。
注意这里的措辞。
不是说:
模型内部一定存在一个数据库单元:
France.capital = Paris
第一课已经讲过,神经网络里的知识通常不是这么整齐地存储的。
更准确地说:
参数逐渐形成一种分布式的内部结构,使正确关系在相关 Context 中更容易得到高概率。
这才接近真实训练过程。
想预测好代码,你就不得不学代码中的规律
假设训练数据里出现:
for i in range(10):
后面经常会是什么?
如果模型完全不知道 Python,
它很难预测。
它需要逐渐捕捉:
冒号之后的结构。
缩进。
循环变量。
函数调用。
括号配对。
变量定义。
常见程序模式。
再复杂一点:
如果前面已经写了一个函数,
几十行之后调用了其中某个变量,
想预测后面的代码,
模型甚至需要跟踪更长距离的程序关系。
所以没有人需要单独告诉它:
“现在开始学习 Python Grammar。”
训练目标永远没变:
预测下一个 Token。
但为了完成这个简单 Objective,
模型不得不逐渐形成越来越复杂的内部 Representation。
一个非常值得记住的判断
这里可以建立一个以后读论文都很有用的认知:
Objective 简单,不代表解决 Objective 所需要的能力简单。
比如国际象棋。
规则并不长。
但想真正下好,非常难。
围棋也是一样。
而 Next Token Prediction 更夸张。
它只有一句任务描述:
根据 Context,预测下一个 Token。
但我们要求它预测的不是一小批简单句子。
而是:
小说。
论文。
数学。
代码。
对话。
百科。
历史。
法律。
技术文档。
复杂推理文本。
多种语言。
如果模型想在如此庞大的数据分布上不断降低预测错误,
它就必须找到越来越多能够解释这些数据的规律。
这就是为什么一个极其简单的训练目标,
最终可能推动一个模型内部形成极其复杂的表示。
这里的“神奇”不是:
目标有多高级。
而是:
数据世界本身有多复杂。
所以“大模型只是文字接龙”到底对不对?
现在可以比较准确地回答这句话了。
说它对:
是因为自回归语言模型确实不断预测下一个 Token。
这没什么好否认。
说它误导:
是因为“文字接龙”这个说法很容易让人产生一个错误印象:
模型只是在根据相邻词频机械接词。
而现代 LLM 实际要建模的是:
P(xt | x<t)
这个 Context 可能非常长。
下一个 Token 的概率,可能取决于:
前面的语法结构。
几十个 Token 前的实体。
几百 Token 前的定义。
代码中的变量关系。
文章的主题。
用户刚刚提出的限制条件。
甚至更长范围的信息。
所以真正的问题从来不是:
它是不是在预测下一个 Token?
当然是在。
真正值得问的是:
为了把下一个 Token 预测得足够好,它必须从 Context 中提取出多复杂的结构?
这才是有价值的问题。
但是千万不要再走到另一个极端
看到这里,也很容易开始说:
原来只要不断做 Next Token Prediction,最后就一定会出现真正的智能。
这也说过头了。
Next Token Prediction 直接优化的是:
文本概率。
它并没有直接要求:
事实必须永远正确。
推理必须永远可靠。
用户指令必须永远服从。
工具必须正确调用。
复杂任务必须执行到底。
模型输出必须符合人类偏好。
举个最简单的例子。
互联网里既有:
正确知识,
也有错误信息。
有严肃论文,
也有小说。
有事实陈述,
也有讽刺。
有今天有效的资料,
也有已经过时的内容。
Pretraining 的基本任务不会因为某段话是假的,就突然改变成另一个 Objective。
它仍然在学习:
在这样的 Context 下,接下来出现什么 Token。
所以:
Language Modeling
和:
Truth
并不是同一个目标。
同样:
Next Token Prediction
也不等于:
Perfect Assistant
这就是为什么 Base Model 训练完成以后,大模型训练并没有结束。
后面还会有:
SFT。
Preference Learning。
DPO。
RL。
RLVR。
Distillation。
这些方法的出现,本质上都在继续回答:
如果“预测人类文本”还不是最终目标,那么我们应该怎样继续训练模型?
但这是后面的课。
今天不往前抢。
还有一个很容易忽略的细节:一段文本不是只有一个训练信号
假设我们有:
机器学习正在改变世界
很多初学者会下意识想象:
输入:
机器学习正在改变
目标:
世界
于是这一整句话只有一次训练。
实际上不是。
概念上,它里面有大量预测位置。
比如:
看到:
机器
预测:
学习
看到:
机器学习
预测:
正在
看到:
机器学习正在
预测:
改变
看到:
机器学习正在改变
预测:
世界
所以一段长度为 (T) 的 Token Sequence,可以贡献大量 Next Token Prediction 目标。
这件事为什么重要?
因为所谓“大规模语料”的价值,
不只是:
有很多文档。
真正更接近训练尺度的是:
里面包含多少可以用于预测的 Token。
于是你会经常看到大模型训练描述里谈:
多少 Billion Tokens。
多少 Trillion Tokens。
而不是简单说:
“我们用了多少篇文章。”
因为对于语言模型训练来说,
Token 才是更接近底层的计算单位和监督单位。
这里再纠正一个很高级、但很重要的误解
前面为了教学,我们一直这样描述:
先看到:
“我”
预测:
“喜欢”
然后再看到:
“我喜欢”
预测:
“机器”
很容易让人产生一个印象:
那训练的时候岂不是必须:
一个 Token 算完,
再算下一个 Token,
然后再算第三个?
如果真的这么训练,大规模训练会非常慢。
实际的 Decoder-only Transformer 训练并不是这么傻。
对于一段已知训练文本,
模型可以在一次计算中同时为很多位置产生 Next Token Prediction。
比如:
输入位置 1 希望预测位置 2。
输入位置 2 希望预测位置 3。
输入位置 3 希望预测位置 4。
……
这些位置可以高度并行计算。
但有一个条件:
当前位置绝对不能偷看未来。
预测第 5 个 Token 时,
不能提前看到第 6、7、8 个 Token。
否则考试时答案已经放桌上了。
后面我们讲 Causal Self-Attention 时,会专门看到模型怎样通过:
Causal Mask
实现这件事。
所以这里先记住一句特别重要的话:
Autoregressive 描述的是信息依赖关系,不代表训练时一定逐 Token 串行计算。
这个区别很多入门教程会混过去。
但后面理解 Transformer Training 和 Inference 的差异时,它非常重要。
训练时和真正聊天时,也不是完全同一回事
还有一个伏笔。
训练阶段有一个巨大优势:
正确文本已经存在。
比如训练语料是:
北京是中国的首都
在预测“是”的时候,前面真实 Context 是:
北京
在预测“中国”的时候,前面真实 Context 是:
北京是
训练数据会一直提供真实历史。
但真正生成的时候不一样。
用户输入一句话以后,
后面的 Token 是模型自己生成的。
假设模型前面生成了一个错误 Token,
那么这个错误 Token 很可能会进入下一步 Context。
下一次预测又建立在它上面。
所以:
训练时的 Context 来源,
和生成时的 Context 来源,
存在一个非常值得研究的差别。
现在不用展开。
后面讲 Teacher Forcing、Inference、以及更远处的 On-policy Learning 时,我们还会重新遇到类似思想。
到这里,我们终于可以把第一课的 ((x,y)) 改写成 LLM 版本
第一课我们一直说:
(x,y)
到了语言模型 Pretraining,
现在可以写成:
(x<t,xt)
其中:
x<t
就是已经出现的 Context。
而:
xt
就是原始数据里真实出现的下一个 Token。
模型有一组参数:
θ
于是它试图学习:
Pθ(xt | x<t)
现在第一课的训练链条终于真正变成了语言模型版本:
| 原始文本 |
| ↓ |
| Token Sequence |
| ↓ |
| Context |
| ↓ |
| 模型 |
| ↓ |
| 预测 Next Token |
| ↓ |
| 和真实 Next Token 比较 |
| ↓ |
| Loss |
| ↓ |
| Gradient |
| ↓ |
| Optimizer |
| ↓ |
| Parameter Update |
| ↓ |
| 新模型 |
| ↓ |
| 然后继续 |
你会发现:
第一课和第二课其实是在回答同一件事的两半。
第一课回答:
模型到底是怎么学的?
通过 Loss、Gradient 和 Parameter Update。
第二课回答:
语言模型这么庞大的训练信号到底从哪里来?
从文本自身的下一个 Token 来。
两件事一拼起来,
现代语言模型 Pretraining 的最基本骨架就已经出现了。
最后还有一个洞,不填这个洞,第三课就不会出现
我们今天一直在写:
Pθ(xt | x<t)
说模型会判断:
“巴黎”的概率应该比较高。
“香蕉”的概率应该很低。
听起来很自然。
但神经网络真的会直接输出:
巴黎:92%
伦敦:3%
北京:1%
吗?
不会。
神经网络首先产生的,其实只是很多普通数字。
例如:
巴黎:8.4
伦敦:4.2
北京:3.8
香蕉:-1.7
这些数字:
可能大于 1。
可以是负数。
加起来也根本不等于 1。
它们甚至还不是概率。
这些东西有一个名字:
Logits。
那么新的问题马上来了:
8.4 到底是什么意思?
为什么 8.4 不能直接理解成 84%?
怎么把一堆任意实数,
变成:
0≤ Pi≤1
并且:
∑iPi=1
的真正概率分布?
还有更有意思的问题。
假设“巴黎”概率最高。
模型是不是每一次都必须选“巴黎”?
如果永远选最高概率 Token,会发生什么?
如果不永远选第一名,那模型又凭什么决定选谁?
Temperature 到底在“加热”什么?
Top-k 和 Top-p 又到底删掉了什么?
到这里我们才发现:
今天虽然一直说:
预测下一个 Token。
但我们还没有真正打开模型输出端。
而这正是下一课要解决的问题。
模型训练原理(三)|大模型吐出来的不是文字:先看懂 Logits、Softmax 和 Sampling
下一课最重要的任务,不是教你背 Softmax 公式。
而是让你真正看见:
一句自然语言,到底是怎样从一堆神经网络内部的数字里“长出来”的。
更多推荐
所有评论(0)