理解 Decoder-only Transformer 如何把 token ids 变成 next-token logits
在 词元化 部分,我们已经把文本转成了 token ids。到这里,模型看到的不是字符串,而是一串整数。
接下来的问题是:这些整数进入 Transformer 之后,为什么最后会变成每个位置对整个词表的打分?
先把完整模型记作 $fθ$,其中 $𝜃$ 表示模型的所有可训练参数。对一个 batch 来说,输入是:
$$
x \in \mathbb{Z}^{B \times T}
$$
输出是:
$$ z = f_\theta(x), \quad z \in \mathbb{R}^{B \times T \times V} $$
这里 𝐵 是 batch size,𝑇 是序列长度,𝑉 是 vocabulary size。也就是说,模型不是直接输出下一个 token id,而是给每个位置都输出一组长度为 𝑉 的 logits。
logits 是什么、有多大?
logits 是 softmax 之前的原始分数,可正可负、量级不固定;它本身不是概率,只有经过 softmax 之后才是概率分布。
典型规模感:Qwen3.5-0.8B 的 𝐷 = 1024、𝑉 = 248,320、Qwen3.5-9B 的 𝐷 = 4096、𝑉 = 248,320。𝑉 通常比 𝐷 大一到两个数量级,LM Head 的 𝑉 × 𝐷 矩阵因此能占模型相当一部分:
- Qwen3.5-0.8B:embedding 与 LM Head 共享权重(weight tying),这一份 𝑉 × 𝐷 矩阵约占 32%(~254M)。
- Qwen3.5-9B:两者不共享,LM Head 单独约 11%(~1.02B),加 embedding 合计约 22%。
模型越小、词表越大,这块比例越夸张(下一章 Embedding 与 LM Head 会展开 weight tying 的取舍)。
语言模型训练的目标是 next-token prediction:位置 𝑡 的输出用来预测下一个 token,也就是
$\cdots x_{t+1}$ 。
| 输入位置 | 模型可见内容 | 这个位置的 logits 用来预测 |
|---|---|---|
| 00 | x0 | x1 |
| 11 | x0,x1 | x2 |
| 22 | x0,x1,x2 | x3 |
| T−1 | x0,…,xT−1 | 下一个待生成 token |
这就是为什么输出要保留 𝑇 这个维度。模型不是只在最后一个位置工作,而是对输入序列中的每个位置都给出一个“下一个 token 会是什么”的预测。
再看最后一维 𝑉。 $z_{b,t,v}$ 表示第 𝑏 个样本、第 𝑡 个位置上,词表中第 𝑣 个 token 的未归一化分数。它还不是概率。需要概率时,才对最后一维做 softmax:
$$ p(x_{t+1}=v \mid x_{\le t}) = \mathrm{softmax}(z_{b,t,:})_v $$
这里 $𝑥 ≤ 𝑡$ 表示从 $𝑥_0$ 到 $𝑥_t$ 的所有 token,即位置 𝑡 能看到的全部上文。
所以 [𝐵, 𝑇, 𝑉] 这个形状不是随便来的:𝐵 表示多少条样本,𝑇 表示多少个预测位置,𝑉 表示每个位置要在整个词表上打分。
从 token ids 到 logits,中间最重要的变化有两次。