先记住一句话

Token 是模型处理的离散符号,embedding 是符号对应的可学习向量;自回归训练把序列右移一位,让模型在每个位置根据过去预测下一个 token。

字符串TokenIDEmbeddingTransformerLogitsLoss / 生成

0. 先看完整计算顺序

① 原始文本I love robots
② 训练输入 IDs[0, 1, 2, 3, 4]
③ 向量序列$X\in\mathbb R^{5\times3}$
④ Causal Transformerhidden states
⑤ 输出logits → softmax
⑥ 训练 / 推理loss / next token
同一个网络有两种使用方式:训练时用正确答案算 loss,推理时把预测 token 接回输入。

1. Tokenization:字符串怎样变成符号

神经网络不能直接对字符串做矩阵乘法。Tokenizer 先把文本切成有限词表中的符号。为了能完整手算,我们定义一个只有 6 项的玩具词表:

例 1:一个玩具 tokenizer

Token<BOS>Iloverobots<EOS>
ID012345
"I love robots" → [<BOS>, I, love, robot, s, <EOS>] → [0, 1, 2, 3, 4, 5]

robots 不在词表里,所以被拆成 robot + s。真实 tokenizer 会用 BPE、Unigram 等方法学习子词词表;这里的切法只为说明计算。

BPE 的“学习”不是神经网络训练

BPE 先在大量文本上统计相邻符号组合,反复合并最常见的组合,最后保存词表和有顺序的合并规则。它没有神经网络、loss、反向传播或梯度下降。

例 1A:从 low, low, lower 手算两轮 BPE

初始先把每个词看成基本符号:

l o w | l o w | l o w e r
相邻组合l + oo + ww + ee + r
出现次数3311

若并列时规定先选 l + o,第一轮得到:

l + o → lo  得到:lo w | lo w | lo w e r

重新统计后,lo + w 出现 3 次,于是第二轮得到:

lo + w → low  得到:low | low | low e r

以后编码 lower 时,tokenizer 按已经保存的优先级执行:l o w e r → lo w e r → low e r。因此歧义不是模型临场猜测,而是由固定算法和固定规则确定。

Byte-level BPE 的直觉:

先保证任何 UTF-8 文本都能退回到基础字节,再把语料中常见的字节序列合并成 token。中文、英文、emoji 可以共享同一套词表;一个 token 可能是一个英文子词、一个汉字、多个汉字,也可能只是某个字符的一部分。OpenAI 公开的 tiktoken 使用模型相关的 encoding,不同 GPT 模型不必采用完全相同的词表和切分。

因此实际训练通常分为两个不同阶段:

① Tokenizer 阶段统计语料 → 词表与规则
② 固定 tokenizer文本 → token IDs
③ 神经网络阶段训练 embedding + Transformer
日常所说“训练 tokenizer”通常是统计学习;真正通过反向传播改变的是 embedding、Transformer 和输出层参数。

token 不等于单词。它可以是子词、字节、图像 patch、视觉 code 或离散动作。词表大小是在两种成本之间折中:

  • 词表大:序列较短,但 embedding/output matrix 更大。
  • 词表小:覆盖灵活,但同一内容被切得更长,attention 与生成更贵。
Token ID 没有数值大小含义:

若把 robot 的 ID 从 3 改成 500,同时把它的 embedding 搬到矩阵第 500 行,模型语义不变。ID 只是数组索引,不是“robot = 3.0”这个连续数值。

2. Embedding lookup:ID 怎样变成向量

设词表大小 $V=6$、模型宽度 $d=3$。模型维护可训练矩阵 $E\in\mathbb R^{6\times3}$。这里假设当前参数是:

ID / token维度 1维度 2维度 3
0 / <BOS>0.10−0.200.00
1 / I0.400.10−0.30
2 / love−0.200.700.50
3 / robot0.800.10−0.40
4 / s0.050.600.20
5 / <EOS>−0.500.200.30

例 2:查表与 one-hot 乘法是同一件事

robot 的 ID 是 3,所以直接取 $E$ 的第 3 行:

$$E[3]=[0.80,\ 0.10,\ -0.40]$$

若写成 one-hot,结果完全相同:

$$[0,0,0,1,0,0]\;E=[0.80,\ 0.10,\ -0.40]$$

于是训练输入 [<BOS>, I, love, robot, s] 变成 $5\times3$ 矩阵:

[[ 0.10, -0.20,  0.00],   # <BOS>
 [ 0.40,  0.10, -0.30],   # I
 [-0.20,  0.70,  0.50],   # love
 [ 0.80,  0.10, -0.40],   # robot
 [ 0.05,  0.60,  0.20]]   # s

位置也必须进入表示

仅做 token lookup 时,robot lovelove robot 只是同两行向量换序;模型还需要明确位置。用最简单的加法式位置向量举例,假设位置 3 的向量是 $P_3=[0.05,-0.10,0.20]$:

$$X_3=E[\text{robot}]+P_3=[0.80,0.10,-0.40]+[0.05,-0.10,0.20]=[0.85,0.00,-0.20]$$

现代模型也常使用 RoPE,不一定把位置向量直接加到输入;但“token 内容”和“它位于哪里”仍是两个不同信号。

Input embedding

由 token ID 查表得到;同一个 token 的起始向量相同。

Contextual hidden state

经过 attention 后得到;同一个 robot 在不同上下文中会变成不同向量。

Embedding 的“大小”可能指两个不同数字

符号含义例子
$V$词表大小,也就是有多少行100,000 个 token
$d$每个 token 向量的宽度,也就是有多少列4,096 维

此时 embedding matrix 的形状是 $100{,}000\times4{,}096$,共有 409,600,000 个可训练参数。词表越大,行数越多;模型宽度越大,每一行越长。

3. 自回归:把联合概率拆成一步一步

自回归是一种概率分解,不等于 Transformer,也不要求输出一定是文字:

$$p(x_{1:T})=\prod_{t=1}^{T}p(x_t\mid x_{<t})$$

对我们的序列,模型要估计五个条件概率:

例 3:整句概率、NLL 与 perplexity

已知过去正确下一个 token假设模型概率$-\ln p$
<BOS>I0.800.22314
<BOS> Ilove0.700.35667
… I loverobot0.600.51083
… love robots0.900.10536
… robot s<EOS>0.500.69315

整句概率:$0.80\times0.70\times0.60\times0.90\times0.50=0.1512$

总 NLL:$-\ln(0.1512)=1.8892$,也等于右列相加后的结果(存在末位舍入)。

平均 loss:$1.8890/5=0.3778$。

Perplexity:$e^{0.3778}\approx1.459$。

整句很长时,许多小于 1 的概率相乘会非常小,所以实际计算用 log:乘法变加法,数值也更稳定。

4. Teacher forcing:一条序列怎样变成五道题

训练时完整正确序列已经在磁盘里。输入和标签只需错开一位:

模型输入
<BOS>Iloverobots
训练标签
Iloverobots<EOS>
位置
01234
位置 2 的输入历史以 love 结尾,标签是 robot。所有位置可在一次 forward 中同时算出。

Teacher forcing 的意思是:训练位置 $t$ 时,前缀使用数据中的真实 token,而不是模型刚才猜出的 token。这样训练稳定且可以并行;推理时没有未来真值,才必须使用自己的输出。

5. Causal mask:为什么并行训练没有偷看答案

虽然五个位置一起进入 Transformer,但 attention mask 禁止每个 query 读取未来 key。下面行是 query 位置,列是它想读取的位置:

例如位置 2 可以看 0、1、2,却不能看位置 3 的 robot 和位置 4 的 s。实现中被屏蔽的 attention score 会在 softmax 前加上 $-\infty$。

例 4:mask 在 softmax 中怎样生效

假设位置 2 对五个 key 的原始 attention score 是:

[1.2, 0.3, 0.8, 2.0, −0.1]

位置 3、4 属于未来,mask 后变成:

[1.2, 0.3, 0.8, −∞, −∞]

对前三项 softmax:$e^{1.2}=3.320$,$e^{0.3}=1.350$,$e^{0.8}=2.226$,总和 $6.896$,所以权重约为:

[0.482, 0.196, 0.323, 0, 0]

未来位置严格得到 0 权重,而不是“很小的权重”。

6. Hidden state、logits、softmax 与 loss

口语里常说“Transformer 输出 logits”,但严格地说,Transformer 主体先为每个位置输出一个连续 hidden state;LM Head(也叫输出层或 unembedding)再把它投影成 logits:

Transformerhidden state,$d$ 个连续数
LM Head$V$ 个连续 logits
Softmax$V$ 个连续概率
选择1 个离散 token ID
离散的是两端的 token ID;embedding、hidden state、logits 和概率都是连续数值。

例 5A:hidden state 怎样经过输出矩阵变成 logits

假设 hidden state 为 $h=[1,2,-1]$,输出词表只有四项。先忽略 bias,每一项 logit 都是 $h$ 与对应输出权重的点积:

候选输出权重点积计算logit
I[0.2, 0.1, 0.0]1×0.2 + 2×0.1 + (−1)×0.00.4
love[0.0, 0.5, 0.2]1×0.0 + 2×0.5 + (−1)×0.20.8
robot[0.6, 0.4, −0.2]1×0.6 + 2×0.4 + (−1)×(−0.2)1.6
<EOS>[−0.1, 0.0, 0.3]1×(−0.1) + 2×0.0 + (−1)×0.3−0.4

于是 $[1,2,-1]$ 经过这个 $4\times3$ 输出矩阵后,得到 logits [0.4, 0.8, 1.6, −0.4]。Logit 可以是任意实数,并不是离散类别或概率。

词表有多大,标准输出就有多大:

若词表大小为 $V=100{,}000$,每个位置就产生 100,000 个 logits,标准 Softmax 也在这 100,000 项上归一化。训练一个长度为 $T$ 的序列会得到 $T\times V$ 的 logits;生成时通常只使用最新位置的 $V$ 项。Top-k 和 top-p 通常是在完整 logits 算出之后筛选,数学上没有把输出词表变小。

Softmax 把 logits 转成总和为 1 的概率;cross-entropy 只取正确 token 的概率来计算这个位置的 loss:

$$p_i=\frac{e^{z_i}}{\sum_j e^{z_j}},\qquad \mathcal L_t=-\ln p_{\text{correct}}$$

例 5B:从四个 logits 手算一个位置的 loss

位置 2 的正确标签是 robot。为简化,只展示四个候选:

候选Iloverobot<EOS>
logit $z$012−1
$e^z$1.0002.7187.3890.368
概率0.0870.2370.6440.032

分母为 $1+2.718+7.389+0.368=11.475$,所以:

$$p(\text{robot})=7.389/11.475=0.644,\qquad \mathcal L=-\ln(0.644)=0.440$$

0.440 不是 44% 错误率。它表示模型对正确答案的“意外程度”。robot 虽然已经排名第一,但模型只给它 64.4% 的概率,仍有 35.6% 的概率质量放在错误答案上,所以 loss 还不为 0。

正确 token 概率$-\ln(p)$直觉
1.000.000完全确信正确答案
0.900.105很有把握
0.6440.440答案排第一,但还不够确信
0.500.693只有一半把握
0.102.303几乎没想到正确答案
0.014.605非常自信地预测错了

若一次更新后 robot logit 从 2 增加到 2.6,其他不变:

新的指数值:$e^{2.6}=13.464$。

新的分母:$1+2.718+13.464+0.368=17.550$。

正确概率:$p(\text{robot})=13.464/17.550=0.767$。

新的 loss:$-\ln(0.767)=0.265$。

训练达成了目标:正确 token 的 logit 增大,概率从 64.4% 升到 76.7%,因此 loss 从 0.440 降到 0.265。负对数还会对“非常自信地犯错”给出很大惩罚,并把整句概率的连乘转成各位置 loss 的相加。

梯度究竟更新什么

Loss 会通过输出层、Transformer、位置模块一路反向传播到 embedding。用一个标量说明 SGD:若 robot embedding 第一维当前为 $0.80$,梯度为 $\partial L/\partial E_{3,1}=0.30$,学习率 $\eta=0.10$:

$$E_{3,1}\leftarrow0.80-0.10\times0.30=0.77$$

真实训练会同时更新数十亿个参数,并通常使用 AdamW,而不是这个单变量 SGD;但“沿着降低 loss 的方向改变参数”就是同一件事。

7. 推理:为什么必须一个 token 一个 token 地生成

训练时标签已知,所以所有位置能并行;推理时第 2 步输入依赖第 1 步刚生成的 token。下面这个动画使用预先写好的玩具概率,演示 greedy decoding 的信息流:

等待播放
<BOS>
每一步都重新运行模型:读入目前完整前缀,得到下一 token 分布,选中一个 token,再把它追加到前缀。

例 6:Greedy、sampling 与 temperature

若某一步分布是 robot: 0.60, AI: 0.25, <EOS>: 0.15

  • Greedy 永远选概率最大的 robot
  • Sampling 按概率抽样;重复很多次,约 60% 选 robot、25% 选 AI
  • Temperature 使用 $\operatorname{softmax}(z/T)$。$T<1$ 放大 logit 差异,使分布更尖;$T>1$ 让分布更平。

训练

输入真实前缀;一次 forward 计算所有位置;模型的早期错误不会改写本样本后面的输入。

生成

输入自己的历史输出;通常逐步生成;一个错误会改变后续所有条件,这就是 exposure bias 的来源。

8. 为什么 next-token prediction 能学到结构

目标本身简单,但要把正确 token 的概率持续推高,模型必须利用数据中可预测的规律。看一个极小语料:

Paris is the capital of France
Tokyo is the capital of Japan
Ottawa is the capital of Canada

若只记局部二元组,看到 capital of 后无法确定国家;要进一步降低 loss,模型必须利用更早出现的城市。类似地,代码需要变量和括号对应,长文本需要人物与论点一致。规模扩大后,大量任务共享同一预测接口。

但这个目标只奖励“符合训练分布”,不直接奖励真实、因果、安全或有帮助。错误事实和表面捷径也能降低 loss,所以还需要数据治理、后训练、检索和工具。

9. 同一个逻辑怎样进入机器人动作模型

若观测 $o$ 包含图像、语言和本体状态,离散动作也可自回归:

$$p(a_{1:T}\mid o)=\prod_{t=1}^{T}p(a_t\mid o,a_{<t})$$

例 7:把连续位移量化成 action token

假设末端 $\Delta x$ 范围是 $[-0.05,0.05]$ 米,用 256 个等宽 bin。真实动作 $\Delta x=0.012$ 米:

归一化位置:$(0.012-(-0.05))/0.10=0.62$。

Token ID:$\lfloor0.62\times256\rfloor=158$。

若用 bin 中心解码:$-0.05+(158.5/256)\times0.10\approx0.01191$ 米。

仅量化带来的误差约 $0.00009$ 米,也就是 $0.09$ mm。

维度更多、范围更大或 bin 更少时,量化误差会增加;逐维自回归还会引入延迟。因此现代机器人策略也常直接生成连续 action chunk,或使用 diffusion / flow matching。

重要边界:

“自回归”描述概率怎样分解和样本怎样依次产生。它不等于语言、不等于离散输出,也不等于 Transformer;连续变量同样可以自回归建模。

自测:最好先拿纸算,再展开答案

1. 词表大小 10,000、embedding width 512,embedding matrix 有多少参数?

$10{,}000\times512=5{,}120{,}000$ 个参数;若用 fp16,仅该矩阵权重约占 10.24 MB,不含梯度和 optimizer state。

2. ID 序列是 [2, 4, 2],embedding 输出的三行有什么关系?

第 1、3 行都查 $E[2]$,所以 input embedding 相同;加入不同位置并经过 attention 后,hidden state 通常不同。

3. 正确 token 概率从 0.25 提升到 0.50,cross-entropy 各是多少?

$-\ln0.25=1.386$,$-\ln0.50=0.693$,loss 减少 0.693。

4. 为什么 causal mask 允许训练并行,却没有泄漏未来?

所有 query 同时计算,但每个位置在 softmax 前把未来 key 的 score 设为 $-\infty$,对应权重严格为 0。

5. Teacher forcing 与 greedy decoding 的输入差别是什么?

Teacher forcing 的下一位置总拿真实历史;greedy decoding 拿模型自己上一轮选出的最高概率 token。

6. BPE 的学习为什么不属于神经网络训练?

它通过统计相邻符号频率并反复合并来产生词表和规则,没有可微网络、反向传播或梯度下降;规则确定后,编码也是确定性的。

7. 词表大小为 50,000 时,一个位置会得到多少个 logits?

标准语言模型会得到 50,000 个连续 logits,Softmax 在这 50,000 项上归一化,最后才选择一个离散 token ID。

原始资料

Generative Pre-Training 展示了语言建模预训练再迁移的路线;OpenAI 的 tiktoken 示例 展示了文本如何变成 token、不同模型如何对应不同 encoding(该页面已归档,模型列表应视为历史示例)。下一篇会把这里暂时当作黑箱的 Transformer 拆开,逐项计算 Q、K、V 与 attention。