第 01 章 / 第 03 课

从查表到 MLP:让模型看见上下文

把离散 token 变成向量,再把多个位置的向量组成一个可训练的上下文模型。

中文讲解 · 约 3 分钟两道自测 · 可重复作答附官方视频 · 英文第 3 / 15 课
这一课,你会学到
  • 解释 embedding 的查表含义
  • 追踪 batch、context 与 embedding 三个维度
  • 比较 bigram 与多位置上下文的限制
术语速查与实践准备
损失
把预测误差变成一个可优化的数。
梯度
损失对参数的局部变化率;更新使用相反方向。
token
分词器产生的离散单位,不一定是一个字或单词。
embedding
由 token ID 查到的可训练向量。

浏览器概念实验可以直接做。运行文中的 PyTorch 代码前,按官方安装说明准备独立环境;完整模型训练的时间与内存按实际数据、模型和硬件测量。

bigram 只看一个 token。如果需要根据前三个字符预测下一字符,我们需要把多个位置的信息交给一个可训练的函数。embedding 与 MLP 是一个足够小、也足够有说明力的起点。

token ID 只是地址

假设 a 的 ID 是 1、b 的 ID 是 2,并不表示 b 比 a“大一倍”。ID 的作用是从 embedding 表里取出一行。若词表大小为 V,每个向量有 E 个维度,embedding 表就是 [V,E]。

查表后,离散 ID 变成了可以连续调整的向量。训练更新的是这张表里的数值,而不是字符的编号。向量开始可以是随机数,它们是否包含有用关系,要由训练任务和数据决定。

用形状追踪一次前向过程

设一次有 B=4 个样本,每个样本看 T=3 个历史 token,每个 embedding 有 E=8 个数。输入 ID 的形状是 [4,3],查表后是 [4,3,8]。把每个样本的三个位置展平,得到 [4,24]。

接着用线性层和非线性函数形成 H 维隐藏状态,再输出 V 个分数。完整形状链是 [B,T] → [B,T,E] → [B,T×E] → [B,H] → [B,V]。最后这 V 个数是 logits,还没有归一化成概率。

import torch
from torch import nn

vocab_size, context, embedding_size = 6, 3, 8
embedding = nn.Embedding(vocab_size, embedding_size)
hidden = nn.Linear(context * embedding_size, 16)
output = nn.Linear(16, vocab_size)

ids = torch.randint(0, vocab_size, (4, context))
x = embedding(ids)
logits = output(torch.tanh(hidden(x.flatten(1))))
print(x.shape, logits.shape)

为什么需要非线性和留出集

多层线性变换如果中间没有非线性,整体仍可合并为一个线性变换。激活函数让模型可以表达更复杂的关系。不过,表达能力增加也意味着更容易记住训练数据,因此验证集从这一刻开始更重要。

比较 bigram 和 MLP 时,保持同一份数据划分和同一种损失定义。不要只比较参数量,也不要在看到验证结果后不断手工挑选验证样本。需要反复调参时,再保留一份最终测试集。

上下文窗口也有边界

这个 MLP 把固定长度的历史向量拼在一起。超出窗口的内容不会参与预测,改变窗口长度还会改变第一层输入尺寸。它帮助我们建立上下文直觉,但还不是能够按内容动态关联位置的注意力模型。

跟视频做完小 MLP 后,保存形状表和训练/验证曲线。接下来的两课先解决“它为什么不好训练”,再把输入从简单字符扩展到更实用的分词。

读完之后,给理解一次反馈。

设置 batch=4、context=3、embedding=8,写出查表、展平、隐藏层和输出层的形状。

本课参考资料

文章、例子与练习为本站原创讲解;官方视频与延伸资料保留作者来源。

核对日期 2026-10-14
核对实验结果,再留下完成记录。

完成记录与自测结果分别保存,不自动推断掌握程度。